'Heimdall'에 해당되는 글 31건

  1. 2009.09.01 Welcome to the real world.
  2. 2009.08.26 클래스를 새로 정의하면
  3. 2009.08.22 Speaking in English has never been easy for me ever.
  4. 2009.08.20 Android Sudoku #3. 옵션메뉴, 게임 시작화면 구성 (2)
  5. 2009.08.15 초보는 모를 수도 있는 자투리 팁 (2)
  6. 2009.08.14 Android Sudoku #1. 기본적인 메뉴구성
  7. 2009.08.12 Notepad 예제 #1: 샘플소스코드와 에러.
  8. 2009.08.11 Android 시작하기.
  9. 2009.08.08 시간이 지나며 점점 하기가 힘들어 지는 것
  10. 2009.08.06 캐나다 동부 여행 #1. Toronto to Montreal via Kingstone and Ottawa (4)

Welcome to the real world.

|
I felt like that when I started taking the first class of my last semester.
Trackback 0 And Comment 0

클래스를 새로 정의하면

|
toString()메소드를 오버로딩하는 습관을 꼭 들이자. toString()신공, 그거슨 진리!

public String toString(){
    StringBuilder sb = new StringBuilder();
    sb.append("Class 이름 및 특성\n");
    sb.append("클래스에서 눈여겨봐둘 내용 입력\n");
    sb.append("blah blah blah blah");

    return sb.toString();
}


'iProgramming > iJava' 카테고리의 다른 글

SimpleJVM #2. Operand stack.  (0) 2009.09.08
클래스를 새로 정의하면  (0) 2009.08.26
Nude Java #1. 개요  (0) 2009.08.04
Trackback 0 And Comment 0

Speaking in English has never been easy for me ever.

|
Nowadays, so many students study English. Reading, listening writing and speaking. I've studied Enlish since I was middle school student. Everyone knows what we need to start studying other languages since we were kids. Because it works better. 

Actually I had to give present in English to my laboratory members and my professor. I didn't prepare anything for the present at all. I had just believed in me. How arrogant I was!! I just screwed off my present. My face tunred red, sounded was like being chased by a murderer and eventually sat on my seat without QNA. Ha- ha. Yeah, it was horrible one. I spent thousands dollars for my Canada working holiday and lots of time to study English. What were those for? Damn, I must have been more carefully and prepared. 

I don't want to commit this mistake anymore. I'll do study harder and be good at English as much as I can be possibly proud of me. 
I don't know how long will it take, although, I believe I still have the hope. I'll see. 


'일상다반사 > iLife' 카테고리의 다른 글

Welcome to the real world.  (0) 2009.09.01
난 왜 하는 것마다 대충대충 엉성엉성 인거야 -_ -  (0) 2009.08.25
Speaking in English has never been easy for me ever.  (0) 2009.08.22
Religions of the world  (0) 2009.08.12
나는 잘 살고 있는데...  (0) 2009.05.30
헛된 꿈  (0) 2009.05.21
Trackback 0 And Comment 0

Android Sudoku #3. 옵션메뉴, 게임 시작화면 구성

|

1. 옵션 메뉴 생성

옵션메뉴는 D패드 위의 Menu버튼을 눌렀을때 나타나는 메뉴이며 지금은 그 메뉴 생성을 위해 필요한 이름값을 strings.xml에 집어넣는 것으로 시작한다.


이제 액티비티 클래스에서 옵션메뉴를 생성해야 하므로 Sudoku.java파일의 onCreateOptionsMenu메소드를 다음과 같이 구성한다. (Alt+Shift+S 후 v키를 누르면 Override/Overload할 수 있는 함수들이 나타나므로 익혀두자.) 

MenuInflater는 menu.xml의 메뉴정의를 읽어와서 실제화면의 메뉴로 '부풀린다(inflate)'.

다음은 옵션 메뉴의 항목이 선택되었을때의 동작을 결정한다

선택된 아이템의 id가 R.id.settings와 같다면 Settings.class(Settings.java) 액티비티를 시작 시킨다는 내용으로 이제 Settings.java를 생성할 차례

2. Settings 추가하기
안드로이드에서는 프로그램의 preference을 resource 파일들을 통해서도 정의 가능하다.

음악과 힌트의 설정을 변경할 CheckBox들의 설정을 정의하고 있다.
그리고 Settings.class를 PreferenceActivity를 확장하여 생성된다.

addPreferencesFromResource메소드가 xml에서 읽어온 preference들을 현재 액티비티의 view에 추가한다.
Settings.class에서 Activity를 확장했으니 Manifest파일에 적어주어야 한다.
여기까지는 아무일도 하지 않는 옵션메뉴를 만드는 과정이었다. 사실 뭐 어떤가... 아직 게임은 시작도 안되는데 >_<b


2. 새 게임 시작하기
New Game 버튼을 누르면 난이도를 설정한 뒤 각 난이도에 맞는 게임판을 불러오게끔 구성할 것이며 일단 시작은 언제나 그랬듯이 이에 필요한 문자열 정보들을 기록하며 시작한다.

난이도 목록을 resource로 관리하기

이제 Sudoku.java파일을 열어서 onClick()메소드에 다음과 같은 내용을 추가해서 New Game버튼을 눌렀을때 난이도 설정하는 메뉴가 보이게끔 설정해준다.

openNewGameDialog() 메서드는 난이도 설정을 위한 UI를 다룬다.

openNewGameDialog에서 난이도 설정하면 startGame()을 이용해 게임 시작한다. 하지만 본격적으로 게임 화면을 구성하기 전에 난이도 선택이 잘 되고 있는지를 확인하기 위해 Log를 통해 확인할 수 있는 코드로 대신

게임종료하기는 finishi() 메서드를 이용해 구현 할 수 있으며 일단 현재 프로그램에서도 사용할 수 있도록 Exit버튼에 연결한다. onClick()메서드에 switch구문 내에 다음 내용을 추가한다.



여기까지는 화면의 초기화면과 옵션, 난이도 메뉴를 이용하면서 기본적인 UI구성에 대해 알아보았고 이후로는 2D그래픽관련 함수들을 이용하여 실제 게임화면과 게임에 사용되는 논리부분 구현이 될 것이다.
Trackback 0 And Comment 2
  1. 잡학저장소 2009.08.22 05:05 신고 address edit & del reply

    님 좀 짱인듯

초보는 모를 수도 있는 자투리 팁

|
나도 초보자지만 이제 곧 책펴들고 예제따라하려는 분들을 위한 팁 몇가지...

팁1. 에뮬레이터는 끄지 말고 계속 켜두기
예제 하나 할때마다 에뮬레이터 켰다 껐다 하는 사람이 많은데...사실 누가 미리 말 안해주면 그렇게 할 가능성이 높은게, 나같은 경우만해도 C, JAVA이런거 공부하면서 들여왔던 습관이 그것이라 안드로이드 시작할때도 똑같이 했는데, 영원처럼 느껴지는 에뮬레이터 구동속도때문에 속앓이 많이 했었다. 하지만... 에뮬레이터를 켜두고 프로젝트를 빌드시키면 에뮬레이터에 어플리케이션이 재설치가 되면서 작동이 된다. 고로, 에뮬레이터 한번 켜두면 그 기나긴 에뮬레이터 구동시간을 절약 할 수가 있게된다.

팁2. Life cycle of an Android activity
이것은 반드시 숙지해둬야할 내요이지 싶다. 각 상자들은 상태를 의미하고 화살표 주변의 함수이름들은 각 상태들이 전환되면서 호출되는 함수들을 보여준다. 

팁3. 이클립스 개발시 Log Cat을 살펴보자
코딩을 하다보면 에뮬레이터를 작동시켜보며 버튼이 잘 작동하나 안하나 확인하고플때가 있는데, 그렇다고 간단한 소스 변경해볼려고 디버그모드 전환해가며 브레이크 포인트설정하고 이러는게 상당히 번거롭다. 그럴때 도움이 될만한 팁이다.

1. 이클립스의 개발 시점(perpective)에 Log cat창을 하나 추가..
Window - Show View - Other - Android - Log cat한 뒤 콘솔창 옆에 추가가 된다.


2. 소스에 Log활용하기
여기선 어떤 클래스의 어떤 함수에서 어떠한 이벤트를 처리하는지 표시하는 로그 추가
Sudoku.java
private static final String TAG = "Sudoku"; //Sudoku.class를 위한 택
private static final boolean logFlag = true; //Log가 보고 싶지 않을땐 false,
....

@Override
public void onClick(View v) {
String method_tag = ".onClick();";
// TODO Auto-generated method stub
switch(v.getId()) {
case R.id.about_button :
if (logFlag) Log.d(TAG+method_tag, method_tag+"about_button is clicked");
Intent i = new Intent(this, About.class);
startActivity(i);
break;
case R.id.new_button :
if (logFlag) Log.d(TAG+method_tag, "new_button is clicked");
openNewGameDialog();
break;
case R.id.exit_button :
if (logFlag) Log.d(TAG+method_tag, "exit_button is clicked");
finish();
break;
// more buttons go here (if any)
}
}
이런식으로 적용 시키면 다음과 같은 메시지를 LogCat창에서 볼 수 있을 것이다.


개발중에는 logFlag에 true, false로 메시지를 조절하고 핸드폰에 올릴때는 해당 소스들을 다 빼서 올리면 될 것이다. 아무래도 저런 코드가 남아있는 상태라면 어플리케이션의 용량이나 사용하는 메모리 면에서나 좋을 것은 없을 것이다. 

Trackback 0 And Comment 2
  1. 잡학저장소 2009.08.16 18:40 신고 address edit & del reply

    하앍, 괜찮게 정리해 놧는데

Android Sudoku #1. 기본적인 메뉴구성

|
노트패드는 소스를 복사해서도 해보고 직접 타이핑(2번씩이나..)해보고 하면서도 원인을 잘 모르겠어서 나중에 내공이 쌓이거나 다른 사람에게서 해결책을 듣기전까지 잠시 접어두고, 인터넷에서 구한 책의 예제를 따라해볼까 하는데, 이번 주제는 바로 수도쿠!

난이도 자체는 Hello World찍는 것보다 딱히 어려울 것이 없지만 세로 화면(Portrait)에서는 잘 보이지만 가로 화면(Landscape)에서 제대로 보이지 않는 경우의 해결법을 알아보는 정도의 포스팅. @_@;

0. 프로젝트 생성
Project name : Sudoku
Package : com.example.android.cgkim.sudoku
Activity : Sudoku
Target/API LV : SDK 1.1  / 2

프로젝트를 생성하면 여러 파일들이 자동으로 생성되는데 이 파일을 간단히 짚어보고 넘어갈 필요가 있다.
Sudoku/src/com.example.android.cgkim.sudoku/Sudoku.java
public class Sudoku extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
간단하니 만큼 소스가 담고 있는 내용도 그리 복잡하진 않다. 간단히 말해 R.layout.main이라는 놈을 화면에 보여주는 것이다. 그리고 R.layout.main은 res/layout.main.xml에 대응된다고만 생각하고 넘어가련다.(사실은 그렇지 않지만 그리 틀린말도 아니고 이렇게 하는 편이 이해하기 쉬우니까...)
이쯤이면 눈치까야 한다. 처음 화면을 구성하기 위해서 res/layout/main.xml이 파일을 손보면 된다는 뜻. 이제 초라하지만 어쨋든 간단하게라도 화면을 구성해봐야 할 차례.

1. 메뉴 만들기

LinearLayout, TextView. Button


Sudoku.java는 손댈 일이 없고 ../res/layout/main.xml 파일을 xml편집모드로 위와 같은 화면을 구성한다.
Sudoku/res/layout/main.xml

main.xml에서 "@+id/...."로 된 부분은 그 객체의 id의 값을 정해주는 소스이고 "@string/...." 부분은 string에 있는(@: at) ...라는 녀석의 값을 참조하라는 뜻이다. 어쨌든 그 ...라는 값이 string이라는 곳에 없기 때문에 생기는 에러이다. 그러면 그것을 해결하려면 어째야 하는가 하니
res/values/strings.xml에 다음과 같이 입력해서 해결할 수 있다.
../res/values/strings.xml

여기까지 작성하고 일단 에뮬레이터를 실행시키면 다음과 같은 화면이 나오게 된다.


뭔가... 뭔가 다른 점이 있다... 바로 배경색!!! 실수한척 하고 있지만 의도적으로 배경색을 지정하지 않았는데 그 이유는 배경색도 버튼에서 이름을 불러오기 위해 그 값들을 다른 파일에서 불러왔듯이 배경색도 다른 파일에서 그 값을 불러와 사용할 수 있다는 것을 보여주기 위함이다. 여기서 하고픈 말은 색 정보, 이름정보 등등을 각기 다른 파일에 따로 정리해서 넣어두면 차후에 수정하기에 용이하기 때문이다. 

../res/values/color.xml


그리고 배경화면도 값을 주어 지정해주자...
../res/layout/main.xml

이렇게 손을 봐주고나서 에뮬레이터를 실행시키면 배경색이 바뀌는 것을 볼 수 있다. 

별 내용없이 글만 길어져서 여기서 맺어야 할 듯 한데 그러기 전에 해결해야할 문제가 하나있다. 말보다 그림.

Dang~ 바로 요것. 버튼이 잘려서 나온다는 문제점이 발생했다.(에뮬레이터 활성 후 키패드의 7 혹은 9)

3. 가로본능 구현
침착하자. 가로 본능에 충실한 UI를 제공해주면 될일이다. 문제는 어떻게 하느냐 인데... 생각보다 간단하다.
절차는 layout-land라는 폴더를 만들어서 거기다가도 main.xml에 화면을 보여줄 UI를 작성하면 된다. Portrait에서의 main.xml, Landscape에서의 main.xml이 각각 세로와 가로일때의 화면을 담당하며 이녀석과 대응되는 것은 처음에 보았던 R.layout.main 이녀석이다. 

어쨌든 가로본능을 위한 UI의 코드
../res/layout-land/main.xml

이제 다시 빌드시키고 에뮬레이터 구동시키면 다음과 같이 알흠다운 화면을 볼 수 있을 것이다.


지금까지의 내용만으로는 그냥 화면을 구성하고 가로로 눞혔을때에 적절한 화면을 보여주는 정도에 불과하고 옵션 메뉴나 각 버튼은 작동하지 않는다. 하지만 프로젝트 생성시 자동생성되는 폴더나 파일들 중 일부의 기능과 용도, 사용법, 연계법을 약간 맛을 보았고, 세로화면과 가로화면을 따로 구성할 수 있다는 것도 알아보았다.

다음 포스트에서는 About버튼을 누르면 글상자를 보여주는 것을 구현하려 한다. 

Trackback 0 And Comment 0

Notepad 예제 #1: 샘플소스코드와 에러.

|
Dev Guide에 나와있는 NotePad를 실제로 해보기에 앞서서 과연 이놈이 되는 놈인지 아닌지 알아보려고 프로젝트(SDK 1.0)를 생성하고 소스파일과 레이아웃 파일을 복사&붙여넣기 신공으로 파일들을 준비한뒤 빌드시킨 결과.... 두둥!!

manifest파일에서 에러를 띄워주시는 센스를 보여주는 바람에 에러를 만들어내는 부분을 주석처리하고 실행~!
대체적으로 각 메뉴의 기능은 동작하지만 TitleEditor에 문제가 있어보입니다. 그래서 프로그램이 시작하면서 경고창을 보여주는게 아닌가 싶은데, 일단 이 문제를 알아보기 위해 reference에서 찾아보니 
android패키지 아래에 있으니.. manifest파일에서 출력하는 에러의 이유를 아직까지는 모르겠군요...

샘플소스 페이지 

Trackback 0 And Comment 0

Android 시작하기.

|

1. System Requirements

The sections below describe the system and software requirements for developing Android applications using the Android SDK tools included in Android SDK, Release .

Supported Operating Systems

  • Windows XP (32-bit) or Vista (32- or 64-bit)
  • Mac OS X 10.4.8 or later (x86 only)
  • Linux (tested on Linux Ubuntu Dapper Drake)

Supported Development Environments

  • Eclipse IDE
    • Eclipse 3.3 (Europa), 3.4 (Ganymede)
      • Recommended Eclipse IDE packages: Eclipse IDE for Java EE Developers, Eclipse IDE for Java Developers, Eclipse for RCP/Plug-in Developers
      • Eclipse JDT plugin (included in most Eclipse IDE packages)
      • Eclipse Classic IDE package is not supported.
    • JDK 5 or JDK 6 (JRE alone is not sufficient)
    • Android Development Tools plugin (optional)
    • Not compatible with Gnu Compiler for Java (gcj)
  • Other development environments or IDEs
    • JDK 5 or JDK 6 (JRE alone is not sufficient)
    • Apache Ant 1.6.5 or later for Linux and Mac, 1.7 or later for Windows
    • Not compatible with Gnu Compiler for Java (gcj)

Note: If JDK is already installed on your development computer, please take a moment to make sure that it meets the version requirements listed above. In particular, note that some Linux distributions may include JDK 1.4 or Gnu Compiler for Java, both of which are not supported for Android development.

컴퓨터 사양부분은 짚고 넘어가야 할 부분이라 생각합니다. 지금은 Galileo버전(신 버전)이 나온 상태인데 전 이 버전의 classic package를 다운받아서 설치를 하고 플러그인 설치까지 마쳤으나 Activity Virtual Device를 생성하지 못하는 일이 생겼었습니다. 그땐 왜 그런지 모르고 이리저리 삽질하다가 개발요구사양을 읽은 뒤에 잘못을 깨닫고 이클립스 버전을 알맞은(Eclipse IDE for Java Developer, 가장 용량이 작았어요!) 버전으로 다시 개발환경을 구축한 다음에야 정상적으로 동작하는 것을 확인했습니다. 하이라이트 처리한 부분은 주의깊게 볼 필요가 있습니다.

2. Download tools

위의 시스템 사양에 걸린 링크에서 다운로드 받으실 수 있습니다.

3. Install

JDK와 Android SDK를 설치 한 후 이클립스를 실행하여 ADT plug-in들을 받는 순서로 이루어 집니다.
빠뜨리지 말아야 할 부분으로는 JDK와 Android SDK의 설치경로를 환경변수에 잡아주는 과정이 필요하다는 겁니다.  

인스톨 방법


4. Build&Run

Hello, Android를 화면에 찍어주는 간단한 어플리케이션인데, 중요한 것은 에뮬레이터를 한번 구동시키는데 시간이 좀 필요하다는 것입니다.

가장 처음으로 구동했을때 이 화면만 수분을 보고 있다가 안되는 줄 알고 수차례 삽질했었습니다.

화면이 바뀌었다고 좋아하다가 여기서 또 수분을 기다리면서 되긴 되는건가? 라는 생각을 가지기도...

원래는 다른화면인데 찍다보니 보호화면이 나왔군요.. 사진에 보이는 menu버튼을 마우스로 클릭해주면 됩니다.

작성한 어플리케이션이 실제 에뮬레이터에 보여지는 그림입니다.


5. Plans

아무래도 구글 안드로이드 페이지에서 나와있는 Notepad프로그램 작성하기를 따라해볼 생각입니다. 처음 하시는 분들은 예제하나 빌드할때마다 에뮬레이터를 켜고 끄기도 하지만, 그럴 필요 없이 한번 에뮬레이터 구동을 시켜두면 나중에 다른 프로젝트를 빌드해도 에뮬레이터에 적용이 된다는 점 알아두는 것이 좋습니다.

Trackback 0 And Comment 0

시간이 지나며 점점 하기가 힘들어 지는 것

|

 이해 관계에 얽매이지 않는 친구를 얻거나 또한 그런 친구가 되어주는 것

요즘들어 머리속에 가장 크게 자리잡고 있는 생각.

Trackback 0 And Comment 0

캐나다 동부 여행 #1. Toronto to Montreal via Kingstone and Ottawa

|
캐나다 동부 여행은 여행사의 프로그램을 따라 진행하였다. 여지껏 그렇게 해본적이 없었지만 5촌 큰아버지의 추천과 도움으로 하게 되었었는데 상당히 인상깊은 여행이었다. 일정은 2박 3일간 토론토에서 출발해서 Kingston, Ottawa, Montreal, Quebec까지 가며 돌아올때는 반대의 순서에서 Ottawa를 들리지 않는 것이었다. St.Lawrence, Montmorency폭포의 아름다운 자연과 Ottawa, Montreal, Quebec의 아름다운 건물등을 고루 볼 수 있는 것이었다.
첫날은 여행사 사무실 앞에서 관광버스를 타고 Kingston으로 향했다. 그곳에서 Thousand Island(천섬) 사이를 유람선을 타고 갈 수가 있는데 캐나다 동부에 왔다면 반드시 경험해봐야 할 관광상품이다. St.Lawrence강 하류에 크고 작은 섬들이 모여있는데 그 중 사람이 살 수 있을만한 섬들이 1,000개가 약간 넘는다고 한다. 그 섬들 중엔 크기가 나무 몇그루와 작은 건물 하나 정도 있을 만한 것 부터 마을하나가 있을 정도로 큰 섬까지 다양하다. 특히 어떤 부자가 아내에게 선물하기 위해 섬을 하트모양으로 깎아내고 성을 지었다는 이야기도 전해진다.
01234567891011121314

강의 수위는 항상 일정한 편이라서 침수되는 일은 드물다고 한다. 또한 캐나다의 부자들과 미국 부자들의 재력과시가 이 곳에서 잘 보인다는데, 무슨 말인고 하니 미국쪽에 있는 섬위의 집들은 크고 화려한 반면 캐나다 쪽은 그만한 화려함이 덜하다는 이야기인데 그러한 점도 유념해두면서 구경하는 것도 참고해둘만하다.
사실 이곳은 Toronto에서 Ottawa를 가는 도중 Kingston에 들려서 구경할 수 있으며 유람선이 운행하는 시간이 일정한데 성수기에는 미리 예약을 하는 것도 좋은 방법이다. Rockport외에도 2 곳이 더 있으며 각기 다른 경로로 운항하기 때문에 미리 알아보고 마음에 드는 곳으로 하는 것은 두번 말해 입아픈 이야기!!
유람을 끝내고 Ottawa로 가는 중 식사를 하기위해 중식 부페를 했는데 큰 상점가에 있는 식당으로 식사를 마치고 주변의 상가를 구경했지만 사람이 붐비지 않는 시간이라 그런지 한산했다.
01234567891011

점심시간 이후에 다시  Ottawa로 연방의상당을 보기 위해 달려갔다. Ottawa는 캐나다의 연방수도이다. 미국으로 보자면 Washington D.C와 같은 곳으로 연방의사당, 총독관저를 비롯해 각 나라의 대사관들이 모여있는 행정수도 이다.
01234567891011121314

이날은 Montreal에 있는 Marriot호텔에서 머물기로 했기때문에 Ottawa에서는 오래머물지 못하고 곧바로 떠나야 했다. 캐나다의 고속도로는 대도시를 가로지르거나 교통량이 많은 곳을 제외하고는 도로상태가 좋지 못한경우가 많다. 특히 Montreal, Quebec으로 통하는 고속도로는 Quebec주가 예전 Montreal Olympic때 진 빚을 아직도 갚는 중이라 그런지 가난한데, 때문에 도로정비가 제대로 이루어지지 않는듯 했다. 가뜩이나 겨울철마다 눈이 쌓이고 제설을 하는 과정에서 도로가 손상이 많이 되는데 참 안타까운 일이 아닐 수 없다. 어느덧 Quebec주를 들어오자 거의 모든 간판들이 프랑스어로 적혀있었다. 특별히 Tim Horton's 같이 사람 이름이 상호가 아닌 경우엔 프랑스어로 쓰여있었으며, 이런 상호조차도 프랑스어로 적혀있었던 것이 있는데 바로 KFC이다. PFK였던 것 같다. 아쉽게도 사진을 찍지 못해뒀지만 인터넷에 찾아보면 왠지 쉽게 찾을 수 있을지도 모르겠다.
하여튼 저녁은 Montreal내 한인 BBQ식당에서 한뒤 곧장 호텔에 짐을 풀고 첫날 여행을 끝냈다.
 
Trackback 1 And Comment 4
  1. 잡학저장소 2009.08.08 01:00 신고 address edit & del reply

    원래 이렇게 되어 있었던게 아닌것 같은데 =_- 슬라이드 넘기는 것처럼 되어 있군

    • 차가운 도시남자 Heimdall 2009.08.08 17:34 신고 address edit & del

      슬라이드 방식도 플래시 방식도 다 별로인듯...
      그냥 사진을 올리는게 더 나은 것 같아.
      스크롤이 길어지겠지만 -_ -;

  2. Asiris 2009.08.09 12:45 신고 address edit & del reply

    저는 그림 저렇게 올린게 더 보기 편한듯해요 ㅋㅋ

prev | 1 | 2 | 3 | 4 | next