2011年4月30日土曜日

Google App Engineのユニットテストのドキュメント(その4)

前回に続き、Google App Engine for Javaのテストについて
翻訳します。

ちなみに、翻訳にはKaede翻訳ツールを使っています。
もともと、こういう用途に使うために作ったものですからね。

翻訳元のドキュメントは
http://code.google.com/intl/en/appengine/docs/java/tools/localunittesting.html
です。

Writing Datastore and Memcache Tests (データストアとMemcacheのテストの記述)
以下のサンプルは、データストアサービスを使用しているテストです。
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class LocalDatastoreTest {

    private final LocalServiceTestHelper helper =
        new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

    @Before
    public void setUp() {
        helper.setUp();
    }

    @After
    public void tearDown() {
        helper.tearDown();
    }

    // run this test twice to prove we're not leaking any state across tests
    private void doTest() {
        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        assertEquals(0, ds.prepare(new Query("yam")).countEntities(FetchOptions.Builder.withLimit(10)));
        ds.put(new Entity("yam"));
        ds.put(new Entity("yam"));
        assertEquals(2, ds.prepare(new Query("yam")).countEntities(FetchOptions.Builder.withLimit(10)));
    }

    @Test
    public void testInsert1() {
        doTest();
    }

    @Test
    public void testInsert2() {
        doTest();
    }
}
このサンプルでは、LocalServiceTestHelperは全てのローカルサービスに共通する実行環境の部分のセットアップと終了処理を行い、LocalDatastoreServiceTestConfigがローカルデータストアサービスの特定された実行環境の部分のセットアップと終了処理を行っています。javadocを参照すると、全てのデータは(定期的にディスク内にフラッシュされるのとは対照的に)メモリ内に保持され、テストの終了ごとに全てのメモリ内のデータが一掃されるようにローカルデータサービスが初期化されるということが分かるでしょう。これはデータストアのテストにおけるデフォルトの振る舞いでしかなく、意図した通りではないときには、変更することができます。

2011/5/6 訳者訂正:
doTest()メソッド内2行目:withLimit(10); → FetchOptions.Builder.withLimit(10);
doTest()メソッド内5行目:withLimit(10); → FetchOptions.Builder.withLimit(10);



Changing the example to access memcache instead of datastore (データストアの代りにmemcacheにアクセスするようにサンプルを変更)
ローカルmemcacheサービスにアクセスするテストを作成するには、先述のコードを少し変更することで対応できます。
データストアに関するクラスをインポートする代わりに、memcacheに関するクラスをインポートします。LocalServiceTestHelperについては、同じくインポートする必要があります。
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import com.google.appengine.tools.development.testing.LocalMemcacheServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
作成するクラスの名前を変更して、LocalServiceTestHelperのインスタンスをmemcacheを指定するように変更します。
public class LocalMemcacheTest {

    private final LocalServiceTestHelper helper =
        new LocalServiceTestHelper(new LocalMemcacheServiceTestConfig());
最後に、実際にテストを実行する部分をmemcacheに関連するように変更します。
    private void doTest() {
        MemcacheService ms = MemcacheServiceFactory.getMemcacheService();
        assertFalse(ms.contains("yar"));
        ms.put("yar", "foo");
        assertTrue(ms.contains("yar"));
    }
データストアについての例では、LocalServiceTestHelperとサービスに付随するLocalServiceTestConfig(ここではLocalMemcacheServiceTestConfig)が実行環境を管理しています。



続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月28日木曜日

Google App Engineのユニットテストのドキュメント(その3)

前回に続き、Google App Engine for Javaのテストについて
翻訳します。

ちなみに、翻訳にはKaede翻訳ツールを使っています。
もともと、こういう用途に使うために作ったものですからね。

翻訳元のドキュメントは
http://code.google.com/intl/en/appengine/docs/java/tools/localunittesting.html
です。



 Introducing the Java Testing Utilities (Javaにおけるテスト用ユーティリティの紹介)
MyFirstTestは、App Engine APIやローカルサービスの実装に依存しないために他に何も必要としない、最もシンプルで実行可能なテストのセットアップを提示しています。しかしながら、あなたのテストやコードがこれら(App Engine APIやローカルサービス)に依存する場合、以下のJARファイルをテストのクラスパスに追加する必要があります。
・${SDK_ROOT}/lib/impl/appengine-api.jar
・${SDK_ROOT}/lib/impl/appengine-api-labs.jar
・${SDK_ROOT}/lib/impl/appengine-api-stubs.jar

これらのJARは、APIの実行環境とテストで使用可能なAPIのローカル実装を作成します。
App Engineのサービスは実行環境から多くのものを呼び出して、かなりの量の定型コードをセットアップします。自分自身でセットアップを行う代わりに、com.google.appengine.tools.development.testingパッケージに含まれるユーティリティを使用することができます。このパッケージを使用するためには、以下のJARファイルをテストのクラスパスに追加する必要があります。
・${SDK_ROOT}/lib/testing/appengine-testing.jar

com.google.appengine.tools.development.testingパッケージのjavadocを参照してみてください。このパッケージで最も重要なクラスは、com.google.appengine.tools.development.testing.LocalServiceTestHelperで、必要な環境のセットアップの全てを取り扱い、テストでアクセスを必要とする全てのローカルサービスを初期化する最上位のポイントとなります。

特定のローカルサービスにアクセスするテストを記述する方法は、
・LocalServiceTestHelperのインスタンスを、特定のローカルサービスのための  LocalServiceTestConfigの実装と共に生成する。
・それぞれのテストの前にLocalServiceTestHelperのインスタンスのsetUp()メソッドを呼び出し、テストの後にtearDown()メソッドを呼び出す。



続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/


2011年4月25日月曜日

Google App Engineのユニットテストのドキュメント(その2)

前回に続き、Google App Engine for Javaのテストについて
翻訳します。

ちなみに、翻訳にはKaede翻訳ツールを使っています。
もともと、こういう用途に使うために作ったものですからね。

翻訳元のドキュメントは
http://code.google.com/intl/en/appengine/docs/java/tools/localunittesting.html
です。


 Setting Up a Testing Framework (テストを行うフレームワークのセットアップ)
SDKのテストユーティリティは特定のフレームワークに結び付けられてはいませんが、ここでのサンプルにはJUnitを使用して、具体的なヒントを得て、作業を完了できるようにしています。テストを記述する前に、テストを行うクラスパスに適切なJUnit 4のJARを追加する必要があります。それが終われば、とても簡単なJUnitテストを記述する準備は完了です。

import static org.junit.Assert.*;

public class MyFirstTest {
    @Test
    public void testAddition() {
        assertEquals(4, 2 + 2);
    }
} 
Eclipse 3.5を利用している場合、実行するテストのソースファイルを選択してください。「実行」メニュー>「実行」>「JUnitテスト」を選択します。テストの結果は、コンソールウィンドウに表示されます。

Apache Antでテストを実行する場合の情報は、Ant JUnit Taskドキュメントを参照してください。

Tis:アプリケーションのコードとは別の場所にユニットテストを保存するのが良い方法です。それにより、JUnitとその他のテストパッケージをアプリケーションと一緒にデプロイしてしまうことを避けられます。



続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/


2011年4月23日土曜日

Google App Engineのユニットテストのドキュメント(その1)

前回、Google App Engine for Javaのテストについて
少しだけ述べました。

今回は、その問題のドキュメントの翻訳を
してみようと思います。
ちなみに、翻訳にはKaede翻訳ツールを使っています。
もともと、こういう用途に使うために作ったものですからね。

翻訳元のドキュメントは
http://code.google.com/intl/en/appengine/docs/java/tools/localunittesting.html
です。

Local Unit Testing for Java (Javaにおけるローカルユニットテスト)
ユニットテストは、記述されたコードの質をチェックすることを可能にしますが、継続中の開発プロセスを改善するためにユニットテストを使用することも可能です。アプリケーションの開発が終わった後にテストを記述する代わりに、行うべきテストを記述することを検討してみてください。それが小さく、保守しやすく、再利用できるコードのユニットをデザインする助けとなります。そしてまた、コードを徹底的に、素早くテストすることを容易にします。

ローカル環境でユニットテストを行う場合、アプリケーションに含まれるリモートコンポーネントを除いた上での開発環境の内部に限定されたテストを実行するでしょう。App Engineは、ローカルで実装されたデータストアと、その他のApp Engineのサービスを利用するテスト用ユーティリティを提供しています。これは、App Engineにデプロイすることなく、サービスのスタブを使うことで、これらのサービスをローカルで利用したコードを実行することを可能にします。

サービスのスタブは、サービスの振る舞いをシミュレートするメソッドとなっています。例として、データストアサービスのスタブは、実際のデータストアに対するリクエストを作成すること無しにデータストアを利用するコードのテストを可能とするWriting Datastore and Memcache Tests(データストアとMemcacheのテストの記述)で示されています。データストアのユニットテストの間に保存されるエンティティはメモリ上に保持され、データストアには保存されず、テストの実行の後に削除されます。これにより、データストア自身に依存することなく、小規模に素早くテストを実行することができます。

このドキュメントはテストを行うフレームワークをセットアップするための情報を提供して、ローカルApp Engineサービスについてのユニットテストの記述方法を説明します。

・Setting Up a Testing Framework (テストを行うフレームワークのセットアップ)
・Intorduceing the Java Testing Utilities (Javaにおけるテストユーティリティの紹介)
・Writing Datastore and Memcahe Tests (データストアとMemcacheのテストの記述)
・Writing Task Queue Tests (タスクキューのテストの記述)
・Writing Tests for Other Services (その他のサービスのテストの記述)
・Writing Tests with Authentication Expectations (認証を前提としたテストの記述)


続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月21日木曜日

Google App Engineのユニットテスト

Kaede翻訳ツールでは、Google App Engine for Javaを利用しています。

アプリケーションを開発する上では、
きちんと機能するかどうかを確かめるためにテストを行うものですが、
Google App Engine for Javaではテスト用のユーティリティが用意されています。

Google App Engine スタートガイド#ハウツー
http://code.google.com/appengine/docs/java/howto/
内に、テストコードの記述方法、ユーティリティの利用の仕方が
書かれているのですが、
この通りには・・・できませんでした。

Eclipseのプラグインをインストールして使っているのですが、
日本語版のユニットテスト解説ページのコードでは、
「クラスが見つからない」というエラーが出て実行できませんでした。
クラスパスのjarアーカイブの内部に必要なクラスが見つからないんです。

そこで、英語版のテストの解説を見ると、どこかのアップデートで
変更があったようでした。
ちなみに、(本質的な問題ではありませんが)日本語版ではJUnit 3、
英語版のページではJUnit 4を使ってサンプルコードが書かれています。
セットアップで使われているクラスも違います。

翻訳されていないのはなぜ・・・?テストって大事なのに。




インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月17日日曜日

多言語キーボードで入力可能な言語の表記

Kaede翻訳ツールでは、
「翻訳元」テキストエリアに入力可能な
多言語バーチャルキーボードを実装しています。

その多言語キーボードで利用可能な言語を
Kaede翻訳ツールのトップページに記載しました。

場所は、ページの一番下、利用可能な言語の表の、
更に下です。

キーボードで入力可能な言語の「言語コード」は、
翻訳で利用可能な言語の言語コードとは違いがあります。
理由は、一つの言語に対して複数の文字や入力方法が利用されるからです。

たとえば、アルメニア語には東方と西方で違うコードが割り当てられています。
グルジア語ではQWERTYキーボードの配列と、タイプライターの配列の2種類があります。






インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月14日木曜日

多言語キーボードの実装

このブログの以前の記事で、
Google Virtual KeyboardのAPIドキュメントの翻訳(Overviewその1その2その3その4)
を行いました。

そして、Kaede翻訳ツールでも多言語キーボードを実装しました。

「翻訳元」テキストエリアの上、「show Virtual Keyboard」ボタンをクリックすると、
スクリーンの右下にバーチャルキーボードが現れます。
利用したい言語は、「show Virtual Keyboard」ボタンの右のセレクトボックスから
選択してください。

なお、既にバーチャルキーボードを表示している場合、
言語のセレクトボックスで他の言語を選択すると、
バーチャルキーボードの利用言語が変更されます。

この多言語キーボードで入力できる言語は、
Google Virtual Keyboard APIのJavaScriptリファレンス
Layout code enum」に記載されています。






インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月10日日曜日

「基本的な使い方」フレームのテキストエリア

http://kaedetrans.appspot.com/translation
ページにアクセスするとフレームに表示される
「基本的な使い方」のページに、
テキストエリアを追加しました。

以前、ローカルに保存されているファイルを
フレームに表示することができない
(ブラウザのセキュリティ上、フレームを使用してローカルファイルにアクセスできるようになっていると、外部のコンピュータにローカルファイルの内容を送信できるようになってしまうのを防ぐため)
事をこのブログ内でお伝えしましたが、
テキストエリアにローカルファイルの文章をコピーすることで
ウィンドウやタブの移動無しで翻訳を行うことができます。

洗練されているとは言えない方法ですが、
お役に立てれば幸いです。




インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月8日金曜日

4月9日以降の東京電力計画停電の原則不実施について

4月9日以降の東京電力の計画停電は、
原則として行われないこととなりました。

とはいえ、引き続き電気を無駄に使わないようにしましょう。

http://kaedetrans.appspot.com/teiden.html

2011年4月7日木曜日

Google Virtual Keyboardの使い方(APIリファレンス)その4

前回に引き続き、多言語文字入力を可能にする


Google Virtual Keyboard API
のドキュメントを翻訳してみます。

APIの利用方法の詳細を説明する、
API Reference (API リファレンス)
ページの続きです。



LayoutCode enum (レイアウトコードの列挙)

google.elements.keyboard.LayoutCode列挙は、レイアウトコードの定数となる名前をマップしています。一つの言語に対して複数のレイアウトと入力メソッドの使用を可能にするために、レイアウトコードは言語コードと一致しないことに注意してください。

var google.elements.keyboard.LayoutCode = {
  'ALBANIAN': 'sq',
  'ARABIC': 'ar',
  'ARMENIAN_EASTERN': 'hy_east',
  'ARMENIAN_WESTERN': 'hy_west',
  'BASQUE': 'eu',
  'BELARUSIAN': 'be',
  'BENGALI_PHONETIC': 'bn_phone',
  'BOSNIAN': 'bs',
  'BRAZILIAN_PORTUGUESE': 'pt_br',
  'BULGARIAN': 'bg',
  'CATALAN': 'ca',
  'CHEROKEE': 'chr',
  'CROATIAN': 'hr',
  'CZECH': 'cs',
  'CZECH_QWERTZ': 'cs_qwertz',
  'DANISH': 'da',
  'DARI': 'prs',
  'DUTCH': 'nl',
  'DEVANAGARI_PHONETIC': 'deva_phone',
  'ENGLISH': 'en',
  'ESTONIAN': 'et',
  'ETHIOPIC': 'ethi',
  'FINNISH': 'fi',
  'FRENCH': 'fr',
  'GALICIAN': 'gl',
  'GEORGIAN_QWERTY': 'ka_qwerty',
  'GEORGIAN_TYPEWRITER': 'ka_typewriter',
  'GERMAN': 'de',
  'GREEK': 'el',
  'GUJARATI_PHONETIC': 'gu_phone',
  'GURMUKHI_PHONETIC': 'guru_phone',
  'HEBREW': 'he',
  'HINDI': 'hi',
  'HUNGARIAN_101': 'hu_101',
  'ICELANDIC': 'is',
  'ITALIAN': 'it',
  'KANNADA_PHONETIC': 'kn_phone',
  'KAZAKH': 'kk',
  'KHMER': 'km',
  'KOREAN': 'ko',
  'KYRGYZ': 'ky_cyrl',
  'LAO': 'lo',
  'LATVIAN': 'lv',
  'LITHUANIAN': 'lt',
  'MACEDONIAN': 'mk',
  'MALAYALAM_PHONETIC': 'ml_phone',
  'MALTESE': 'mt',
  'MONGOLIAN_CYRILLIC': 'mn_cyrl',
  'MONTENEGRIN': 'srp',
  'NORWEGIAN': 'no',
  'ORIYA_PHONETIC': 'or_phone',
  'PAN_AFRICA_LATIN': 'latn_002',
  'PASHTO': 'ps',
  'PERSIAN': 'fa',
  'POLISH': 'pl',
  'PORTUGUESE': 'pt_pt',
  'ROMANI': 'rom',
  'ROMANIAN': 'ro',
  'RUSSIAN': 'ru',
  'SANSKRIT_PHONETIC': 'sa_phone',
  'SERBIAN_CYRILLIC': 'sr_cyrl',
  'SERBIAN_LATIN': 'sr_latn',
  'SINHALA': 'si',
  'SLOVAK': 'sk',
  'SLOVAK_QWERTY': 'sk_qwerty',
  'SLOVENIAN': 'sl',
  'SOUTHERN_UZBEK': 'uzs',
  'SPANISH': 'es_es',
  'SWEDISH': 'sv',
  'TAMIL_PHONETIC': 'ta_phone',
  'TATAR': 'tt',
  'TELUGU_PHONETIC': 'te_phone',
  'THAI': 'th',
  'TURKISH_F': 'tr_f',
  'TURKISH_Q': 'tr_q',
  'UIGHUR': 'ug',
  'UKRAINIAN_101': 'uk_101',
  'URDU': 'ur',
  'UZBEK_LATIN': 'uz_latn',
  'UZBEK_CYRILLIC_PHONETIC': 'uz_cyrl_phone',
  'UZBEK_CYRILLIC_TYPEWRITTER': 'uz_cyrl_type',
  'VIETNAMESE_TCVN': 'vi_tcvn',
  'VIETNAMESE_TELEX': 'vi_telex',
  'VIETNAMESE_VIQR': 'vi_viqr'
};

Troubleshooting
問題が発生した場合、
・APIキーが正当であるかどうか確認してください。
・タイピングが正しいかどうか確認してください。JavaScriptは大文字/小文字を区別する言語です。
・JavaScriptのデバッガを使用してください。Google Chromeはdeveloper toolsのフルセットを持ちます。FireFoxでは、Firebugか、JavaScriptコンソールが利用できます。IEでは、Microsoft Script Debuggerを利用できます。
・discussion groupを検索してみてください。あなたの質問への答えとなる投稿を見つけられない場合、問題が現れるウェブページへのリンクと共に、グループに質問を投稿してください。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月4日月曜日

4月5日の計画停電の予定

4月5日の東京電力の計画停電は
行われない予定です。

http://kaedetrans.appspot.com/teiden.html

Google Virtual Keyboardの使い方(APIリファレンス)その3

前回に引き続き、多言語文字入力を可能にする



Google Virtual Keyboard API
のドキュメントを翻訳してみます。


APIの利用方法の詳細を説明する、
API Reference (API リファレンス)
ページの続きです。


 Global methods
.getLayoutName(layout)
getLayoutName(layout)は、ネイティブの言語でアクティブなレイアウトの名前を含む文字列を返すメソッドです。layout引数は、google.elements.keyboard.LayoutCodeの形式で表すレイアウトコードです。

Static Methods
以下の静的メソッドは、google.languageネームスペースで実装されています。
.setOnLoadCallback(callback)
setOnLoadCallback(callback)は、この呼び出しを含むページがロードされる時に一度だけ呼び出される指定されたハンドラ関数を登録する静的関数です。callback引数は、この関数を含むドキュメントがロードされ、APIが使用可能になる(たとえば、onLoadの後)時に呼び出される、必須の関数のことです。この関数はgoogleネームスペースで実装されています(つまり、google.setOnLoadCallback(callback)の形式で呼び出します)。
.setOnLoadCallback()は、値を返しません。
Note:以前のドキュメントでは、body要素のonload属性(<body onload="OnLoad()">)を使用することが推奨されていました。これは、ページの完全なコントロールが為され、ページによって全てのコードがロードされた時に行われるための良い方法であるためですが、このやり方は幾つかの実行環境ではbody.onloadハンドラを破壊する問題の原因となることがあります。setOnLoadCallback()はこれらの問題を持たないので、APIが完全にロードされて使用可能になった時にコードを呼び出すコールバックを登録するメソッドが推奨されます。




続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月2日土曜日

Google Virtual Keyboardの使い方(APIリファレンス)その2

前回に引き続き、多言語文字入力を可能にする


Google Virtual Keyboard API
のドキュメントを翻訳してみます。


APIの利用方法の詳細を説明する、
API Reference (API リファレンス)
ページの続きです。


 Methods
Method (メソッド)
説明
.getLaout()
getLayput()は、引数を持ちません。google.elements.keyboard.LayoutCodeの形式のkeyboardオブジェクトのアクティブなレイアウトを返します。
.isVisible()
isVisible()は、引数を持ちません。オンスクリーンキーボードのkeyboardインスタンスの可視/不可視の状態を示すboolean値を返します。
.setLayout(layout)
setLayout(layout)は、keyboardインスタンスのキーボードレイアウトを変更します。layout引数は、google.elements.keyboard.LayoutCodeの形式のレイアウトコードです。setLayout(layout)は値を返しません。
.setVisible(visible)
setVisible(visible)は、keyboardインスタンスの可視状態をセットします。visible引数は、キーボードが可視かどうかを表すboolean値です。setVisible(visible)は、値を返しません。



続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年4月1日金曜日

4月2日から4日までの計画停電の予定

4月2日から4日までの東京電力の計画停電は
行われない予定です。

http://kaedetrans.appspot.com/teiden.html

Google Virtual Keyboardの使い方(APIリファレンス)その1

前回に引き続き、多言語文字入力を可能にする



Google Virtual Keyboard API
のドキュメントを翻訳してみます。


APIの利用方法の詳細を説明する、
API Reference (API リファレンス)
ページの続きです。



Virtual Keyboard API Java Script Reference
Table of Contents
 JavaScript Reference(JavaScriptリファレンス)
  Constructor(コンストラクタ)
  Methods(メソッド)
  Global methods(グローバルメソッド)
  Static methods(静的メソッド)
 Layout code enum(レイアウトコードの列挙)
 Troubleshooting(トラブルシューティング)


Virtual keyboard JavaScript reference
Constructor(コンストラクタ) - google.elements.keyboard
このセクションで説明される全てのメソッドは、google.elements.keyboardネームスペースで実装されています。

コンストラクタ
google.elements.keyboard.Keyboard(layouts,textfieldIds)
説明
Keyboard(layouts,textfieldIds)は、新しいVirtual Keyboardインスタンスを生成します。
layoutsは、事前にロードされるキーボードレイアウトの配列で、LayoutCode enumの形式で指定されます(例として、google.elements.keyboard.LayoutCode.RUSSIAN)。一番目のレイアウトがデフォルトです。サポートされるスクリプトの完全なリストは、LayoutCode enumを参照してください。
Note:layouts配列に不正な値を渡すと、APIは例外をスローします。
textfieldIdsは、ユーザーインターフェイスにキーボードが適用される事を許可する要素を参照しているテキストフィールドのID文字列を含む配列となる、オプションの引数です。オプションの引数を渡さない場合、ページ上のテキストエリアや入力ボックスに、同じキーボードのインスタンスが適用されます。



続く。

インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/