aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dictionaries/cs_wordlist.combined.gzbin948259 -> 948265 bytes
-rw-r--r--dictionaries/da_wordlist.combined.gzbin1017628 -> 1017659 bytes
-rw-r--r--dictionaries/de_wordlist.combined.gzbin1292088 -> 1292098 bytes
-rw-r--r--dictionaries/en_GB_wordlist.combined.gzbin859901 -> 859935 bytes
-rw-r--r--dictionaries/en_US_wordlist.combined.gzbin876974 -> 876994 bytes
-rw-r--r--dictionaries/en_wordlist.combined.gzbin908339 -> 908369 bytes
-rw-r--r--dictionaries/es_wordlist.combined.gzbin951626 -> 951637 bytes
-rw-r--r--dictionaries/fi_wordlist.combined.gzbin1269538 -> 1269545 bytes
-rw-r--r--dictionaries/fr_wordlist.combined.gzbin1106516 -> 1106540 bytes
-rw-r--r--dictionaries/hr_wordlist.combined.gzbin1014504 -> 1014512 bytes
-rw-r--r--dictionaries/it_wordlist.combined.gzbin933682 -> 933691 bytes
-rw-r--r--dictionaries/lt_wordlist.combined.gzbin980888 -> 980894 bytes
-rw-r--r--dictionaries/lv_wordlist.combined.gzbin970371 -> 970377 bytes
-rw-r--r--dictionaries/nb_wordlist.combined.gzbin964752 -> 964888 bytes
-rw-r--r--dictionaries/nl_wordlist.combined.gzbin1053234 -> 1053244 bytes
-rw-r--r--dictionaries/pl_wordlist.combined.gzbin1089268 -> 1089295 bytes
-rw-r--r--dictionaries/pt_BR_wordlist.combined.gzbin878581 -> 878505 bytes
-rw-r--r--dictionaries/pt_PT_wordlist.combined.gzbin1105827 -> 1105961 bytes
-rw-r--r--dictionaries/sl_wordlist.combined.gzbin315154 -> 315163 bytes
-rw-r--r--dictionaries/sr_wordlist.combined.gzbin1052021 -> 1052033 bytes
-rw-r--r--dictionaries/sv_wordlist.combined.gzbin1139275 -> 1139282 bytes
-rw-r--r--dictionaries/tr_wordlist.combined.gzbin925939 -> 925947 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.pngbin474 -> 463 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.pngbin1083 -> 1889 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.pngbin941 -> 1741 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.pngbin338 -> 355 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.pngbin781 -> 1166 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.pngbin699 -> 1105 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.pngbin603 -> 589 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.pngbin1421 -> 2393 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.pngbin1248 -> 2196 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.pngbin1803 -> 1718 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.pngbin1907 -> 3102 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.pngbin1791 -> 2749 bytes
-rw-r--r--java/res/raw/main_de.dictbin1605721 -> 1605727 bytes
-rw-r--r--java/res/raw/main_en.dictbin1069840 -> 1069846 bytes
-rw-r--r--java/res/raw/main_es.dictbin1138899 -> 1138908 bytes
-rw-r--r--java/res/raw/main_fr.dictbin1329179 -> 1329192 bytes
-rw-r--r--java/res/raw/main_it.dictbin1143332 -> 1143338 bytes
-rw-r--r--java/res/raw/main_pt_br.dictbin1091987 -> 1092054 bytes
-rw-r--r--java/res/values-az-rAZ/strings-appname.xml27
-rw-r--r--java/res/values-az-rAZ/strings.xml244
-rw-r--r--java/res/values-az/strings-appname.xml27
-rw-r--r--java/res/values-az/strings.xml242
-rw-r--r--java/res/values-en-rIN/strings-appname.xml27
-rw-r--r--java/res/values-en-rIN/strings.xml244
-rw-r--r--java/res/values-et-rEE/strings-appname.xml27
-rw-r--r--java/res/values-fr-rCA/strings-appname.xml27
-rw-r--r--java/res/values-fr-rCA/strings.xml253
-rw-r--r--java/res/values-hy-rAM/strings-appname.xml27
-rw-r--r--java/res/values-hy-rAM/strings.xml244
-rw-r--r--java/res/values-hy/strings-appname.xml27
-rw-r--r--java/res/values-hy/strings.xml242
-rw-r--r--java/res/values-ka-rGE/strings-appname.xml27
-rw-r--r--java/res/values-ka/strings-appname.xml27
-rw-r--r--java/res/values-kk/strings-appname.xml27
-rw-r--r--java/res/values-km-rKH/strings-appname.xml27
-rw-r--r--java/res/values-km-rKH/strings.xml244
-rw-r--r--java/res/values-km/strings-appname.xml27
-rw-r--r--java/res/values-km/strings.xml242
-rw-r--r--java/res/values-land/dimens.xml2
-rw-r--r--java/res/values-lo-rLA/strings-appname.xml27
-rw-r--r--java/res/values-lo-rLA/strings.xml244
-rw-r--r--java/res/values-lo/strings-appname.xml27
-rw-r--r--java/res/values-lo/strings.xml242
-rw-r--r--java/res/values-mn-rMN/strings-appname.xml27
-rw-r--r--java/res/values-ms-rMY/strings-appname.xml27
-rw-r--r--java/res/values-ne-rNP/strings-appname.xml27
-rw-r--r--java/res/values-ne-rNP/strings.xml244
-rw-r--r--java/res/values-ne/strings-appname.xml27
-rw-r--r--java/res/values-ne/strings.xml242
-rw-r--r--java/res/values-si-rLK/strings-appname.xml27
-rw-r--r--java/res/values-si-rLK/strings.xml244
-rw-r--r--java/res/values-si/strings-appname.xml27
-rw-r--r--java/res/values-si/strings.xml242
-rw-r--r--java/res/values-sw600dp-land/dimens.xml2
-rw-r--r--java/res/values-sw600dp/dimens.xml2
-rw-r--r--java/res/values-sw768dp-land/dimens.xml2
-rw-r--r--java/res/values-sw768dp/dimens.xml2
-rw-r--r--java/res/values-zh-rHK/strings-appname.xml27
-rw-r--r--java/res/values-zh-rHK/strings.xml244
-rw-r--r--java/res/values/dimens.xml2
-rw-r--r--java/res/values/strings.xml5
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java12
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java53
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java14
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java11
-rw-r--r--java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java9
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java69
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java31
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryWriter.java8
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java96
-rw-r--r--java/src/com/android/inputmethod/latin/InputAttributes.java4
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java47
-rw-r--r--java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java120
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java6
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java8
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java38
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java6
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java19
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/SparseTable.java194
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java41
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java123
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java (renamed from java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java)42
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java13
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java22
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java16
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java2
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java (renamed from java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java)6
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java70
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SpannableStringUtils.java110
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java89
-rw-r--r--native/jni/Android.mk2
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp77
-rw-r--r--native/jni/src/defines.h2
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_node.h17
-rw-r--r--native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h25
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.cpp45
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.h7
-rw-r--r--native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h5
-rw-r--r--native/jni/src/suggest/core/policy/weighting.cpp13
-rw-r--r--native/jni/src/suggest/core/suggest.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp75
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h19
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.cpp44
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h52
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp3
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp124
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h18
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.cpp18
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h3
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp147
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h32
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp10
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp118
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h78
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp93
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h32
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp17
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.h12
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp13
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.cpp129
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.h70
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp108
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h50
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_weighting.h9
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java171
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java103
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java160
-rw-r--r--tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java39
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java58
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java35
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java32
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/Package.java2
-rw-r--r--tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java6
161 files changed, 6809 insertions, 817 deletions
diff --git a/dictionaries/cs_wordlist.combined.gz b/dictionaries/cs_wordlist.combined.gz
index d69ef6451..7829d6573 100644
--- a/dictionaries/cs_wordlist.combined.gz
+++ b/dictionaries/cs_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/da_wordlist.combined.gz b/dictionaries/da_wordlist.combined.gz
index 919d28e1d..e7140195b 100644
--- a/dictionaries/da_wordlist.combined.gz
+++ b/dictionaries/da_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/de_wordlist.combined.gz b/dictionaries/de_wordlist.combined.gz
index f5cce9d5a..6a4bd445c 100644
--- a/dictionaries/de_wordlist.combined.gz
+++ b/dictionaries/de_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_GB_wordlist.combined.gz b/dictionaries/en_GB_wordlist.combined.gz
index d28ef485b..839f3efca 100644
--- a/dictionaries/en_GB_wordlist.combined.gz
+++ b/dictionaries/en_GB_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_US_wordlist.combined.gz b/dictionaries/en_US_wordlist.combined.gz
index b656f880d..5595c75c0 100644
--- a/dictionaries/en_US_wordlist.combined.gz
+++ b/dictionaries/en_US_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_wordlist.combined.gz b/dictionaries/en_wordlist.combined.gz
index 8aa40e944..69c39d5d9 100644
--- a/dictionaries/en_wordlist.combined.gz
+++ b/dictionaries/en_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/es_wordlist.combined.gz b/dictionaries/es_wordlist.combined.gz
index 53b86076d..0a48b6d11 100644
--- a/dictionaries/es_wordlist.combined.gz
+++ b/dictionaries/es_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/fi_wordlist.combined.gz b/dictionaries/fi_wordlist.combined.gz
index 272011659..eefbfe51a 100644
--- a/dictionaries/fi_wordlist.combined.gz
+++ b/dictionaries/fi_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/fr_wordlist.combined.gz b/dictionaries/fr_wordlist.combined.gz
index 1d988d6fe..1a1832079 100644
--- a/dictionaries/fr_wordlist.combined.gz
+++ b/dictionaries/fr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/hr_wordlist.combined.gz b/dictionaries/hr_wordlist.combined.gz
index 7694a2ade..864f67651 100644
--- a/dictionaries/hr_wordlist.combined.gz
+++ b/dictionaries/hr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/it_wordlist.combined.gz b/dictionaries/it_wordlist.combined.gz
index 3b84cd741..dfb175259 100644
--- a/dictionaries/it_wordlist.combined.gz
+++ b/dictionaries/it_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/lt_wordlist.combined.gz b/dictionaries/lt_wordlist.combined.gz
index 316a5af01..029722d95 100644
--- a/dictionaries/lt_wordlist.combined.gz
+++ b/dictionaries/lt_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/lv_wordlist.combined.gz b/dictionaries/lv_wordlist.combined.gz
index b036ac21a..41e1c28bd 100644
--- a/dictionaries/lv_wordlist.combined.gz
+++ b/dictionaries/lv_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/nb_wordlist.combined.gz b/dictionaries/nb_wordlist.combined.gz
index b6e0d42d3..b699912b7 100644
--- a/dictionaries/nb_wordlist.combined.gz
+++ b/dictionaries/nb_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/nl_wordlist.combined.gz b/dictionaries/nl_wordlist.combined.gz
index 48ab0f473..89c238830 100644
--- a/dictionaries/nl_wordlist.combined.gz
+++ b/dictionaries/nl_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/pl_wordlist.combined.gz b/dictionaries/pl_wordlist.combined.gz
index bf02298c1..2b53f69cb 100644
--- a/dictionaries/pl_wordlist.combined.gz
+++ b/dictionaries/pl_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/pt_BR_wordlist.combined.gz b/dictionaries/pt_BR_wordlist.combined.gz
index 221ea7508..2d22447e4 100644
--- a/dictionaries/pt_BR_wordlist.combined.gz
+++ b/dictionaries/pt_BR_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/pt_PT_wordlist.combined.gz b/dictionaries/pt_PT_wordlist.combined.gz
index 6a041d9cf..1504165d0 100644
--- a/dictionaries/pt_PT_wordlist.combined.gz
+++ b/dictionaries/pt_PT_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sl_wordlist.combined.gz b/dictionaries/sl_wordlist.combined.gz
index 41a576bde..55e1bb1c8 100644
--- a/dictionaries/sl_wordlist.combined.gz
+++ b/dictionaries/sl_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sr_wordlist.combined.gz b/dictionaries/sr_wordlist.combined.gz
index dec6ae89e..8488a08b4 100644
--- a/dictionaries/sr_wordlist.combined.gz
+++ b/dictionaries/sr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sv_wordlist.combined.gz b/dictionaries/sv_wordlist.combined.gz
index 0471772e7..63425206e 100644
--- a/dictionaries/sv_wordlist.combined.gz
+++ b/dictionaries/sv_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/tr_wordlist.combined.gz b/dictionaries/tr_wordlist.combined.gz
index fae79ca21..0251778c7 100644
--- a/dictionaries/tr_wordlist.combined.gz
+++ b/dictionaries/tr_wordlist.combined.gz
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
index 87211a502..fa2cb8542 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png
index c1e16a651..8a6336a57 100644
--- a/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
index 26d068490..edf1379ab 100644
--- a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
index f98653ea1..8e9a34957 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png
index 16be37d05..0795fcc9b 100644
--- a/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
index 95d718a46..f76da5797 100644
--- a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
index 738316d66..a2f6ac0e2 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
index 944a8524d..b2bb9b803 100644
--- a/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
index 2016caf40..23e75bfe7 100644
--- a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
index b35c29fe6..17f0a7a58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
index 6809f0711..f04cadf6f 100644
--- a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
index 6bd506a11..e74d523bc 100644
--- a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/raw/main_de.dict b/java/res/raw/main_de.dict
index 5d35e64a2..69796bbaa 100644
--- a/java/res/raw/main_de.dict
+++ b/java/res/raw/main_de.dict
Binary files differ
diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict
index 6564d47fa..bef6b1005 100644
--- a/java/res/raw/main_en.dict
+++ b/java/res/raw/main_en.dict
Binary files differ
diff --git a/java/res/raw/main_es.dict b/java/res/raw/main_es.dict
index f5906c2e2..261ab8c87 100644
--- a/java/res/raw/main_es.dict
+++ b/java/res/raw/main_es.dict
Binary files differ
diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict
index 10adad092..18f529887 100644
--- a/java/res/raw/main_fr.dict
+++ b/java/res/raw/main_fr.dict
Binary files differ
diff --git a/java/res/raw/main_it.dict b/java/res/raw/main_it.dict
index 523f645c7..e161c2475 100644
--- a/java/res/raw/main_it.dict
+++ b/java/res/raw/main_it.dict
Binary files differ
diff --git a/java/res/raw/main_pt_br.dict b/java/res/raw/main_pt_br.dict
index f9ae9b561..21bbe7c67 100644
--- a/java/res/raw/main_pt_br.dict
+++ b/java/res/raw/main_pt_br.dict
Binary files differ
diff --git a/java/res/values-az-rAZ/strings-appname.xml b/java/res/values-az-rAZ/strings-appname.xml
new file mode 100644
index 000000000..2fcb76c69
--- /dev/null
+++ b/java/res/values-az-rAZ/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Klaviatura (AOYP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android Orfoqrafik Yoxlanış (AOYP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android Klaviatura Parametrləri (AOYP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Orfoqrafik Yoxlanış Parametrləri (AOYP)"</string>
+</resources>
diff --git a/java/res/values-az-rAZ/strings.xml b/java/res/values-az-rAZ/strings.xml
new file mode 100644
index 000000000..bd62a95d4
--- /dev/null
+++ b/java/res/values-az-rAZ/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Daxiletmə seçimləri"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Araşdırma Jurnalı Əmrləri"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontakt adlarına baxın"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Orfoqrafik yoxlanış kontakt siyahınızdakı qeydlərdən istifadə edir"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrasiyalı klikləmə"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Klikləmə səsi"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Klikləmədə popup"</string>
+ <string name="general_category" msgid="1859088467017573195">"Ümumi"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Mətn korreksiyası"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Jestlərlə yazma"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Digər seçənəklər"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Qabaqcıl ayarlar"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Ekspertlər üçün seçimlər"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Digər daxiletmə metodlarına keçin"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Dil keçid düyməsi başqa daxiletmə metodlarını da əhatə edir"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Dil keçidi düyməsi"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Çoxsaylı daxiletmə dilləri aktivləşdikdə göstər"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Slayd indikatorunu göstər"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Sürüşdürmə və ya Simvol düymələrinə keçərkən vizual işarəni göstər"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Klaviş popup kənarlaşdırılmasında gecikmə"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Gecikmə yoxdur"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Varsayılan"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> millisaniyə"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Sistem defoltu"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakt adları təklif edin"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Təklif və korreksiya üçün Kontaktlardakı adlardan istifadə edin"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"İkili boşluq periodu"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluqdakı iki klik boşluqdan sonra pauza daxil edir"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Avtomatik böyük hərfləşmə"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Hər cümlənin ilk sözünü böyük hərflə yaz"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Şəxsi lüğət"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Əlavə lüğətlər"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Əsas lüğət"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Korreksiya təkliflərini göstər"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Yazarkən təklif edilən sözləri ekranda göstər"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Həmişə göstər"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Portret rejimində göstər"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Həmişə gizlət"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Təhqiredici sözləri əngəlləyin"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Potensial təhqiredici sözlər təklif etməyin"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Avtomatik-korreksiya"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Boşluq və punktuasiya avtomatik yanlış sözləri düzəldir"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Deaktiv"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Orta"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aqressiv"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Çox aqressiv"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Növbəti-söz təklifləri"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Təkliflər edilməsində əvvəlki sözdən istifadə et"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Jestlərlə yazmağı aktiv et"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Hərflər üzərində sürüşdürərək söz daxil edin"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Jest izini göstər"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Dinamik üzmə önizləməsi"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Jest zamanı təklif edilmiş sözə baxın"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saxlanmış"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Get"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Növbəti"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Əvvəlki"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Hazırdır"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Göndər"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Pauza"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Gözlə"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Parolu səsli eşitmək üçün qulaqcığı taxın"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Cari mətn %s\'dir"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Mətn daxil edilməyib"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"%d açar kodu"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Sürüşdürmə"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Sürüşdürmə aktivdir (deaktiv etmək üçün klikləyin)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Böyük hərf kilidi aktivdir (deaktiv etmək üçün klikləyin)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Sil"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simvollar"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Hərflər"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Nömrələr"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Parametrlər"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Boşluq"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Səs daxiletməsi"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Smaylik"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Qayıt"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Axtar"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Nöqtə"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Dil keçidi"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Növbəti"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Əvvəlki"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Sürüşdürmə aktivdir"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Böyük hərf kilidi aktivdir"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Sürüşdürmə deaktivdir"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Simvol rejimi"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Hərf rejimi"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Telefon rejimi"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Telefon simvol rejimi"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Gizlədilmiş klaviatura"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> klaviaturası göstərilir"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"tarix"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"gün və tarix"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"E-poçt"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"mesajlaşma"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"nömrə"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"telefon"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"mətn"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"vaxt"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Səs daxiletmə klavişi"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Əsas klaviaturada"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Simvol klaviaturasında"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Qapalı"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Əsas klaviaturada mikrofon"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Simvol klaviaturasında mikrofon"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Səs daxiletməsi deaktiv edildi"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Daxiletmə üsullarını sazla"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Daxiletmə dilləri"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Cavab rəyi göndərin"</string>
+ <string name="select_language" msgid="3693815588777926848">"Daxiletmə dilləri"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Yadda saxlamaq üçün yenidən toxunun"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Lüğət mövcuddur"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"İstifadəçi əks əlaqəsini aktiv et"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"İstifadə statistikası və xəta haqqında hesabatları avtomatik göndərməklə daxiletmə metodu redaktəsini təkmilləşdirməyə kömək edin."</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatura teması"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"İngilis (BK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"İngilis (ABŞ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"İspan (ABŞ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"İngilis (BK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"İngilis (ABŞ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"İspan (ABŞ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g>(Ənənəvi)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Dil yoxdur (Əlifba)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Əlifba (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Əlifba (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Əlifba (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Əlifba (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Əlifba (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Əlifba (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Xüsusi daxiletmə üslubları"</string>
+ <string name="add_style" msgid="6163126614514489951">"Stil əlavə et"</string>
+ <string name="add" msgid="8299699805688017798">"Əlavə et"</string>
+ <string name="remove" msgid="4486081658752944606">"Ləğv et"</string>
+ <string name="save" msgid="7646738597196767214">"Yadda saxla"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Dil"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Tərtibat"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Xüsusi daxiletmə üslubunuz istifadəyə başlamazdan əvvəl aktivləşdirilməlidir. Aktiv etmək istəyirsiniz?"</string>
+ <string name="enable" msgid="5031294444630523247">"Aktiv et"</string>
+ <string name="not_now" msgid="6172462888202790482">"İndi yox"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Eyni daxiletmə üslubu artıq mövcuddur: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Rahat işləmə rejimi"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Klavişi uzun müddət basmada gecikmə"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrasiyalı klikləmə müddəti"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Səsli klikləmə səsi"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Xarici lüğət faylını oxuyun"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Endirmə Qovluğunda heç bir lüğət faylı yoxdur"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Yükləmək üçün lüğət faylı seçin"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Bu faylı həqiqətən <xliff:g id="LOCALE_NAME">%s</xliff:g> adlı yerə quraşdıraq?"</string>
+ <string name="error" msgid="8940763624668513648">"Xəta var idi"</string>
+ <string name="button_default" msgid="3988017840431881491">"Defolt"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> təbiqinə xoş gəlmisiniz"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"Jest Yazısı ilə"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Başlayın"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Növbəti addım"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> quraşdırılır"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> tətbiqini aktivləşdir"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Lütfən, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" tətbiqini Dil və daxiletmə parametrlərinizdə yoxlayın. Bununla tətbiqin cihazınızda işləməsinə icazə veriləcək."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> artıq sizin Dil və daxiletmə parametrlərinizdə aktivləşdirildi, beləliklə da bu mərhələ tamamlandı. İndi isə növbəti mərhələyə eçin!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Parametrlərdə aktivləşdir"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> tətbiqinə keçin"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Sonra, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" tətbiqini aktiv mətn-daxiletmə metodu olaraq seçin."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Daxil metodlarına keç"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Təbrik edirik, tam hazırsınız!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"İndi siz <xliff:g id="APPLICATION_NAME">%s</xliff:g> ilə bütün sevimli tətbiqlərinizdə yaza bilərsiniz."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Əlavə dillər quraşdır"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Sona çatdı"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Tətbiq ikonasını göstər"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Başlatma panelində tətbiq ikonasını göstər"</string>
+ <string name="app_name" msgid="6320102637491234792">"Lüğət Provayderi"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Lüğət Provayderi"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Lüğət Xidməti"</string>
+ <string name="download_description" msgid="6014835283119198591">"Lüğət yeniləmə məlumatı"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Əlavə lüğətlər"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Lüğət mövcuddur"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Lüğət üçün ayarlar"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"İstifadəçi lüğətləri"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"İstifadəçi lüğəti"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Lüğət mövcuddur"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Hazırda endirilir"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Quraşdırılıb"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Quraşdırılıb, deaktiv edilib"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Lüğət xidmətinə bağlantı problemi"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Lüğət mövcud deyil"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Təzələ"</string>
+ <string name="last_update" msgid="730467549913588780">"Son yeniləmə"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Güncəlləmələr yoxlanılır"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Yüklənir..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Əsas lüğət"</string>
+ <string name="cancel" msgid="6830980399865683324">"Ləğv et"</string>
+ <string name="install_dict" msgid="180852772562189365">"Quraşdırın"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Ləğv et"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Sil"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Mobil cihazınızda seçilmiş dil üzrə lüğət mövcuddur.&lt;br/&gt; Yazı təcrübənizi təkmilləşdirmək üçün <xliff:g id="LANGUAGE">%1$s</xliff:g> lüğətini &lt;b&gt;endirməyi&lt;/b&gt; tövsiyə edirik.&lt;br/&gt; &lt;br/&gt; Endirmə 3G ilə bir və ya iki dəqiqə çəkəcək. &lt;b&gt;Limitsiz data planınız&lt;/b&gt;.&lt;br/&gt; olmadığı halda əlavə xərc tutula bilər, endirməni avtomatik başlatmaq üçün Wi-Fi bağlantı tapmanızı tövsiyə edirik.&lt;br/&gt; &lt;br/&gt; Məsləhət: Siz lüğətləri mobil cihazınızın &lt;b&gt;Dil və daxiletmə&lt;/b&gt; <b>Parametrlərindən</b> endirə və ya ləğv edə bilərsiniz."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"İndi endirin (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi ilə endir"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g> üçün lüğət mövcuddur"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Nəzərdən keçirmək və endirmək üçün klikləyin"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Endirilir: <xliff:g id="LANGUAGE">%1$s</xliff:g> üçün təkliflər tezliklə hazır olacaq."</string>
+ <string name="version_text" msgid="2715354215568469385">"<xliff:g id="VERSION_NUMBER">%1$s</xliff:g> nömrəli versiya"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Əlavə edin"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Lüğətə əlavə edin"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"İfadə"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Daha çox seçim"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Daha az seçim"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Söz:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Qısayol:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Dil:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Bir söz yazın"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Könüllü qısayol"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Sözü redaktə edin"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Düzəliş edin"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Silin"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"İstifadəçi lüğətinizdə heç bir söz yoxdur. Əlavə et (+) düyməsinə toxunmqla bir söz əlavə edin."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Bütün dillər üçün"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Digər dillər​​..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Silin"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-az/strings-appname.xml b/java/res/values-az/strings-appname.xml
new file mode 100644
index 000000000..2fcb76c69
--- /dev/null
+++ b/java/res/values-az/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Klaviatura (AOYP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android Orfoqrafik Yoxlanış (AOYP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android Klaviatura Parametrləri (AOYP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Orfoqrafik Yoxlanış Parametrləri (AOYP)"</string>
+</resources>
diff --git a/java/res/values-az/strings.xml b/java/res/values-az/strings.xml
new file mode 100644
index 000000000..7fb13f7a0
--- /dev/null
+++ b/java/res/values-az/strings.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Daxiletmə seçənəkləri"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Araşdırma Giriş Əmrləri"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontakt adlarına baxın"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Orfoqrafik yoxlanış kontakt siyahınızdakı qeydlərdən istifadə edir"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrasiyalı klikləmə"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Klikləmə səsi"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Klikləmədə popup"</string>
+ <string name="general_category" msgid="1859088467017573195">"Ümumi"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Mətn korreksiyası"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Jestlərlə yazma"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Digər seçənəklər"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"İnkişaf etmiş parametrlər"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Mütəxəssislər üçün Seçənəklər"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Digər daxiletmə metodlarına keçin"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Dil keçid düyməsi başqa daxiletmə metodlarını da əhatə edir"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Dil keçidi düyməsi"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Çoxsaylı daxiletmə dilləri aktivləşdikdə göstər"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Slayd indikatorunu göstər"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Sürüşdürmə və ya Simvol düymələrinə keçərkən vizual işarəni göstər"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Klaviş popup kənarlaşdırılmasında gecikmə"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Gecikmə yoxdur"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Varsayılan"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Sistem defoltu"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakt adları təklif edin"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Təklif və korreksiya üçün Kontaktlardakı adlardan istifadə edin"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"İkili boşluq periodu"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluqdakı ikiqat tıklama bolşuqdan sonrakı periodu əlavə edir"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Avtomatik böyük hərf"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Hər cümlənin ilk sözünü böyük hərflə yaz"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Şəxsi lüğət"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Əlavə lüğətlər"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Əsas lüğət"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Korreksiya təkliflərini göstər"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Yazarkən təklif edilən sözləri ekranda göstər"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Həmişə göstər"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Portret rejimində göstər"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Həmişə gizlət"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Təhqiredici sözləri əngəlləyin"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Potensial təhqiredici sözlər təklif etməyin"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Avtomatik-korreksiya"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Boşluq və punktuasiya avtomatik yanlış sözləri düzəldir"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Deaktiv"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Orta"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aktiv"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Çox aktiv"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Növbəti söz təklifləri"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Təkliflər edilməsində əvvəlki sözdən istifadə et"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Jestlərlə yazmağı aktiv et"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Hərflər üzərində sürüşdürərək söz daxil edin"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Jest izini göstər"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Dinamik işlətmə önizləməsi"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Jest zamanı təklif edilən sözə baxın"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Yadda saxlanıldı"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Get"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Növbəti"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Əvvəlki"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Hazırdır"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Göndər"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Pauza"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Gözlə"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Parolu səsli eşitmək üçün qulaqcığı taxın"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Cari mətn %s\'dir"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Mətn daxil edilməyib"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"%d açar kodu"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Sürüşdürmə"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Sürüşdürmə aktivdir (deaktiv etmək üçün klikləyin)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Böyük hərf kilidi aktivdir (deaktiv etmək üçün klikləyin)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Sil"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simvollar"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Hərflər"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Nömrələr"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Parametrlər"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Boşluq"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Səs daxiletməsi"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Smaylik"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Qayıt"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Axtar"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Nöqtə"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Dil keçidi"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Növbəti"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Əvvəlki"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Sürüşdürmə aktivdir"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Böyük hərf kilidi aktivdir"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Sürüşdürmə deaktivdir"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Simvol rejimi"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Hərf rejimi"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Telefon rejimi"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Telefon simvol rejimi"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Klaviatura gizlədilib"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> klaviaturası göstərilir"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"tarix"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"gün və tarix"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"e-poçt"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"mesajlaşma"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"nömrə"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"telefon"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"mətn"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"vaxt"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Səs daxiletmə klavişi"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Əsas klaviaturada"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Simvol klaviaturasında"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Qapalı"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Əsas klaviaturada mikrofon"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Simvol klaviaturasında mikrofon"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Səs daxiletməsi deaktiv edildi"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Daxiletmə üsullarını quraşdırın"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Daxiletmə dilləri"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Cavab rəyi göndərin"</string>
+ <string name="select_language" msgid="3693815588777926848">"Daxiletmə dilləri"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Yadda saxlamaq üçün yenidən toxunun"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Lüğət mövcuddur"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"İstifadəçi əks əlaqəsini aktiv et"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"İstifadə statistikası və xəta haqqında hesabatları avtomatik göndərməklə daxiletmə metodu redaktəsini təkmilləşdirməyə kömək edin."</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatura teması"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"İngilis (BK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"İngilis (ABŞ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"İspan (ABŞ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"İngilis (BK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"İngilis (ABŞ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"İspan (ABŞ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Dil yoxdur (Əlifba)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Əlifba (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Əlifba (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Əlifba (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Əlifba (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Əlifba (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Əlifba (PC)"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Xüsusi daxiletmə üslubları"</string>
+ <string name="add_style" msgid="6163126614514489951">"Üslub əlavə edin"</string>
+ <string name="add" msgid="8299699805688017798">"Əlavə edin"</string>
+ <string name="remove" msgid="4486081658752944606">"Ləğv et"</string>
+ <string name="save" msgid="7646738597196767214">"Yadda saxla"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Dil"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Tərtibat"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Xüsusi daxiletmə üslubunuz istifadəyə başlamazdan əvvəl aktivləşdirilməlidir. Aktiv etmək istəyirsiniz?"</string>
+ <string name="enable" msgid="5031294444630523247">"Aktiv et"</string>
+ <string name="not_now" msgid="6172462888202790482">"İndi yox"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Eyni daxiletmə üslubu artıq mövcuddur: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Rahat işləmə rejimi"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Klavişi uzun müddət basmada gecikmə"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrasiyalı klikləmə müddəti"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Səsli klikləmə səsi"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Xarici lüğət faylını oxuyun"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Endirmə Qovluğunda heç bir lüğət faylı yoxdur"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Yükləmək üçün lüğət faylı seçin"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Bu faylı həqiqətən <xliff:g id="LOCALE_NAME">%s</xliff:g> adlı yerə quraşdıraq?"</string>
+ <string name="error" msgid="8940763624668513648">"Xəta var idi"</string>
+ <string name="button_default" msgid="3988017840431881491">"Varsayılan"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> təbiqinə xoş gəlmisiniz"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"Jest Yazısı ilə"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Başlayın"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Növbəti addım"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> quraşdırılır"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> tətbiqini aktivləşdir"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Lütfən, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" tətbiqini Dil və daxiletmə parametrlərinizdə yoxlayın. Bununla tətbiqin cihazınızda işləməsinə icazə veriləcək."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> artıq sizin Dil və daxiletmə parametrlərinizdə aktivləşdirildi, beləliklə da bu mərhələ tamamlandı. İndi isə növbəti mərhələyə eçin!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Parametrlərdə aktivləşdir"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> tətbiqinə keçin"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Sonra, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" tətbiqini aktiv mətn-daxiletmə metodu olaraq seçin."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Daxil metodlarına keç"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Təbrik edirik, tam hazırsınız!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"İndi siz <xliff:g id="APPLICATION_NAME">%s</xliff:g> ilə bütün sevimli tətbiqlərinizdə yaza bilərsiniz."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Əlavə dillər quraşdır"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Sona çatdı"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Tətbiq ikonasını göstər"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Başlatma panelində tətbiq ikonasını göstər"</string>
+ <string name="app_name" msgid="6320102637491234792">"Lüğət Provayderi"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Lüğət Provayderi"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Lüğət Xidməti"</string>
+ <string name="download_description" msgid="6014835283119198591">"Lüğət güncəlləmə məlumatı"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Əlavə lüğətlər"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Lüğət mövcuddur"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Lüğət seçənəkləri"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"İstifadəçi lüğətləri"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"İstifadəçi lüğəti"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Lüğət mövcuddur"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Hazırda endirilir"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Quraşdırılıb"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Quraşdırılıb, deaktiv edilib"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Lüğət xidməti ilə bağlantı problemi"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Lüğət mövcud deyil"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Təzələ"</string>
+ <string name="last_update" msgid="730467549913588780">"Son yeniləmə"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Güncəlləmələr yoxlanılır"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Yüklənir..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Əsas lüğət"</string>
+ <string name="cancel" msgid="6830980399865683324">"ləğv et"</string>
+ <string name="install_dict" msgid="180852772562189365">"Quraşdırın"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Ləğv et"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Silin"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Mobil cihazınızda seçilmiş dil üzrə lüğət mövcuddur.&lt;br/&gt; Yazı təcrübənizi təkmilləşdirmək üçün <xliff:g id="LANGUAGE">%1$s</xliff:g> lüğətini &lt;b&gt;endirməyi&lt;/b&gt; tövsiyə edirik.&lt;br/&gt; &lt;br/&gt; Endirmə 3G ilə bir və ya iki dəqiqə çəkəcək. &lt;b&gt;Limitsiz data planınız&lt;/b&gt;.&lt;br/&gt; olmadığı halda əlavə xərc tutula bilər, endirməni avtomatik başlatmaq üçün Wi-Fi bağlantı tapmanızı tövsiyə edirik.&lt;br/&gt; &lt;br/&gt; Məsləhət: Siz lüğətləri mobil cihazınızın &lt;b&gt;Dil və daxiletmə&lt;/b&gt; <b>Parametrlərindən</b> endirə və ya ləğv edə bilərsiniz."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"İndi endirin (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi ilə endir"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g> üçün lüğət mövcuddur"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Nəzərdən keçirmək və endirmək üçün klikləyin"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Endirilir: <xliff:g id="LANGUAGE">%1$s</xliff:g> üçün təkliflər tezliklə hazır olacaq."</string>
+ <string name="version_text" msgid="2715354215568469385">"<xliff:g id="VERSION_NUMBER">%1$s</xliff:g> nömrəli versiya"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Əlavə edin"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Lüğətə əlavə edin"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"İfadə"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Daha çox seçim"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Daha az seçim"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Söz:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Qısayol:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Dil:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Bir söz yazın"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Könüllü qısayol"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Sözü redaktə edin"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Düzəliş edin"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Silin"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"İstifadəçi lüğətinizdə heç bir söz yoxdur. Əlavə et (+) düyməsinə toxunmqla bir söz əlavə edin."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Bütün dillər üçün"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Digər dillər​​..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Silin"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-en-rIN/strings-appname.xml b/java/res/values-en-rIN/strings-appname.xml
new file mode 100644
index 000000000..5ad5eae66
--- /dev/null
+++ b/java/res/values-en-rIN/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Keyboard (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android Spell Checker (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android Keyboard Settings (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Spell Checker Settings (AOSP)"</string>
+</resources>
diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000..6337aa019
--- /dev/null
+++ b/java/res/values-en-rIN/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Input options"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Look up contact names"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Spell checker uses entries from your contact list"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on keypress"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Sound on keypress"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up on key press"</string>
+ <string name="general_category" msgid="1859088467017573195">"General"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Text correction"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Gesture typing"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Other options"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Advanced settings"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Options for experts"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Switch to other input methods"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Language switch key also covers other input methods"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Language switch key"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Show when multiple input languages are enabled"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Show slide indicator"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Display visual cue while sliding from Shift or Symbol keys"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Key pop-up dismiss delay"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"No delay"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"System default"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Double-space full stop"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Double tap on spacebar inserts a full stop followed by a space"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Capitalise the first word of each sentence"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Personal dictionary"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Add-on dictionaries"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Main dictionary"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Show correction suggestions"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Display suggested words while typing"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Always show"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Show in portrait mode"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Always hide"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Block offensive words"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Do not suggest potentially offensive words"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Auto-correction"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Correct mistyped words automatically with spacebar and punctuation"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Off"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressive"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Very aggressive"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Next-word suggestions"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Use the previous word when making suggestions"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Enable gesture typing"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Input a word by sliding through the letters"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Show gesture trail"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Dynamic floating preview"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"See the suggested word while gesturing"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Go"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Next"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Prev"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Finished"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Send"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Wait"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Plug in a headset to hear password keys spoken aloud."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Current text is %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"No text entered"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Key code %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift on (tap to disable)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps lock on (tap to disable)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbols"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letters"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Numbers"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Settings"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Voice input"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley face"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Search"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Switch language"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Next"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Previous"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift enabled"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock enabled"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift disabled"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Symbols mode"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Letters mode"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Phone mode"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Phone symbols mode"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Keyboard hidden"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"Showing <xliff:g id="MODE">%s</xliff:g> keyboard"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"date"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"date and time"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"email"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"messaging"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"number"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"phone"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"text"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"time"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Voice input key"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"On main keyboard"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"On symbols keyboard"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Off"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mic on main keyboard"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mic on symbols keyboard"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Voice input is disabled"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Configure input methods"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Input languages"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Send feedback"</string>
+ <string name="select_language" msgid="3693815588777926848">"Input languages"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Touch again to save"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Enable user feedback"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Help improve this input method editor by automatically sending usage statistics and crash reports"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"Spanish (US)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"English (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"English (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spanish (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Traditional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alphabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alphabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alphabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alphabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Customised input styles"</string>
+ <string name="add_style" msgid="6163126614514489951">"Add style"</string>
+ <string name="add" msgid="8299699805688017798">"Add"</string>
+ <string name="remove" msgid="4486081658752944606">"Remove"</string>
+ <string name="save" msgid="7646738597196767214">"Save"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Language"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Layout"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Your customised input style needs to be enabled before you start using it. Do you want to enable it now?"</string>
+ <string name="enable" msgid="5031294444630523247">"Enable"</string>
+ <string name="not_now" msgid="6172462888202790482">"Not now"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Usability study mode"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Key long press delay"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Keypress vibration duration"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Keypress sound volume"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Read external dictionary file"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"No dictionary files in the Downloads folder"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Select a dictionary file to install"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Really install this file for <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+ <string name="error" msgid="8940763624668513648">"There was an error"</string>
+ <string name="button_default" msgid="3988017840431881491">"Default"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Welcome to <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"with Gesture Typing"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Get started"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Next step"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"Setting up <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"Enable <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Please tick \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" in your Language &amp; input settings. This will authorise it to run on your device."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> is already enabled in your Language &amp; input settings, so this step is done. On to the next one!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Enable in Settings"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"Switch to <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Next, select \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" as your active text-input method."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Switch input methods"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Congratulations, you\'re all set!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Now you can type in all your favourite apps with <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Configure additional languages"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Finished"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Show app icon"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Display application icon in the launcher"</string>
+ <string name="app_name" msgid="6320102637491234792">"Dictionary Provider"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Dictionary Provider"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Dictionary Service"</string>
+ <string name="download_description" msgid="6014835283119198591">"Dictionary update information"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Add-on dictionaries"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Dictionary available"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Settings for dictionaries"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"User dictionaries"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"User dictionary"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Dictionary available"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Currently downloading"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Installed"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Installed, disabled"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Problem connecting to dictionary service"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"No dictionaries available"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Refresh"</string>
+ <string name="last_update" msgid="730467549913588780">"Last updated"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Checking for updates"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Loading..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Main dictionary"</string>
+ <string name="cancel" msgid="6830980399865683324">"Cancel"</string>
+ <string name="install_dict" msgid="180852772562189365">"Install"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Cancel"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Delete"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"The selected language on your mobile device has an available dictionary.&lt;br/&gt; We recommend &lt;b&gt;downloading&lt;/b&gt; the <xliff:g id="LANGUAGE">%1$s</xliff:g> dictionary to improve your typing experience.&lt;br/&gt; &lt;br/&gt; The download could take a minute or two over 3G. Charges may apply if you don\'t have an &lt;b&gt;unlimited data plan&lt;/b&gt;.&lt;br/&gt; If you are not sure which data plan you have, we recommend finding a Wi-Fi connection to start the download automatically.&lt;br/&gt; &lt;br/&gt; Tip: You can download and remove dictionaries by going to &lt;b&gt;Language &amp; input&lt;/b&gt; in the &lt;b&gt;Settings&lt;/b&gt; menu of your mobile device."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Download now (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Download over Wi-Fi"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"A dictionary is available for <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Press to review and download"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Downloading: suggestions for <xliff:g id="LANGUAGE">%1$s</xliff:g> will be ready soon."</string>
+ <string name="version_text" msgid="2715354215568469385">"Version <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Add"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Add to dictionary"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Phrase"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"More options"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Fewer options"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Word:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Shortcut:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Language:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Type a word"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Optional shortcut"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Edit word"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Edit"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Delete"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"You don\'t have any words in the user dictionary. Add a word by touching the Add (+) button."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"For all languages"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"More languages…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Delete"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-et-rEE/strings-appname.xml b/java/res/values-et-rEE/strings-appname.xml
new file mode 100644
index 000000000..bbc13d293
--- /dev/null
+++ b/java/res/values-et-rEE/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Androidi klaviatuur (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Androidi õigekirjakontroll (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Androidi klaviatuuri seaded (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Androidi õigekirjakontrolli seaded (AOSP)"</string>
+</resources>
diff --git a/java/res/values-fr-rCA/strings-appname.xml b/java/res/values-fr-rCA/strings-appname.xml
new file mode 100644
index 000000000..d45e239a0
--- /dev/null
+++ b/java/res/values-fr-rCA/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Clavier Android (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Correcteur orthographique Android (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Paramètres du clavier Android (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Paramètres du correcteur orthographique Android (AOSP)"</string>
+</resources>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index b56463ed9..8d8fedd9a 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -1,19 +1,244 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string>
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Options de saisie"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Commandes journaux rech."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Rechercher noms contacts"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Correcteur orthographique utilise entrées de liste de contacts."</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer à chaque touche"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Son à chaque touche"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Agrandir les caractères"</string>
+ <string name="general_category" msgid="1859088467017573195">"Général"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Correction du texte"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Saisie gestuelle"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Autres options"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Paramètres avancés"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Options destinées aux experts"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Autres modes de saisie"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"La touche de sélection de langue couvre d\'autres modes de saisie"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Touche de sélection de langue"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Afficher lorsque plusieurs langues de saisie sont activées"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Aff. indicateur saisie gestuelle"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Aff. un repère visuel si l\'utilisateur appuie sur Maj ou Symboles"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Masquer touche agrandie"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Aucun délai"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Par défaut"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Paramètres par défaut"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Point et espace"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Appuyez deux fois sur la barre d\'espace pour insérer un point et une espace"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Majuscules automatiques"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Majuscule au premier mot de chaque phrase"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Dictionnaire personnel"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dictionnaires complémentaires"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Dictionnaire principal"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Suggestions de correction"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Afficher les suggestions de terme lors de la saisie"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Toujours afficher"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Afficher en mode Portrait"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Toujours masquer"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Bloquer les termes choquants"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Pas de termes potentiellement choquants"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Correction auto"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Corriger autom. orthographe (pression sur barre espace/signes ponctuation)"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Désactiver"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Simple"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Proactive"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Très exigeante"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Suggestions pour le mot suivant"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Utiliser le mot précédent pour les suggestions"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Activer la saisie gestuelle"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Saisir un mot en faisant glisser le doigt sur les lettres"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Afficher le tracé du geste"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Aperçu flottant dynamique"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Afficher le mot suggéré lors des gestes"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Aller"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Suivant"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Préc."</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Terminé"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Envoyer"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Suspendre"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Attendre"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Branchez des écouteurs pour entendre l\'énoncé à haute voix des touches lors de la saisie du mot de passe."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Le texte actuel est %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Aucun texte saisi"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Code touche %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Maj"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Touche Maj activée (appuyer pour désactiver)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Verrouillage des majuscules activé (appuyer pour désactiver)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Supprimer"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboles"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Lettres"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Nombres"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Paramètres"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Onglet"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Espace"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Saisie vocale"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Émoticône"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Renvoyer"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Rechercher"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Point"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Changer de langue"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Suivant"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Précédent"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Touche Maj activée"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Verrouillage des majuscules activé"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Touche Maj désactivée"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Mode Symboles"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Mode Lettres"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Mode Téléphone"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Mode Symboles du téléphone"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Clavier masqué"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"Affichage du clavier <xliff:g id="MODE">%s</xliff:g>"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"Date"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"Date et heure"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"Courriel"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"SMS/MMS"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"Nombre"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"Numéro de téléphone"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"Texte"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"Heure"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Touche de saisie vocale"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Sur le clavier principal"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Sur clavier symboles"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Désactiver"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Micro sur le clavier principal"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Micro sur le clavier des symboles"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Saisie vocale désactivée"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Configurer les modes de saisie"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Langues de saisie"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Envoyer des commentaires"</string>
+ <string name="select_language" msgid="3693815588777926848">"Langues de saisie"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Appuyer de nouveau pour enregistrer"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Autoriser les commentaires des utilisateurs"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Contribuer à l\'amélioration de cet éditeur du mode de saisie grâce à l\'envoi automatique de statistiques d\'utilisation et de rapports d\'erreur"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"Anglais (britannique)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"Anglais (États-Unis)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"Espagnol (États-Unis)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Anglais (Royaume-Uni) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Anglais (États-Unis) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Espagnol, États-Unis (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditionnel)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Aucune langue (alphabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet latin (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet latin (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alphabet latin (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alphabet latin (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alphabet latin (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alphabet latin (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Styles saisie personnalisés"</string>
+ <string name="add_style" msgid="6163126614514489951">"Ajouter style"</string>
+ <string name="add" msgid="8299699805688017798">"Ajouter"</string>
+ <string name="remove" msgid="4486081658752944606">"Supprimer"</string>
+ <string name="save" msgid="7646738597196767214">"Enregistrer"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Langue"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Disposition"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Vous devez activer votre style de saisie personnalisé avant de l\'utiliser. Voulez-vous le faire maintenant ?"</string>
+ <string name="enable" msgid="5031294444630523247">"Activer"</string>
+ <string name="not_now" msgid="6172462888202790482">"Pas maintenant"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Le style de saisie suivant existe déjà : <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'étude de l\'utilisabilité"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Délai appui prolongé sur touche"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durée vibration press. touche"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume pression de touche"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Lire un fichier de dictionnaire externe"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Aucun fichier de dictionnaire dans le dossier \"Téléchargements\""</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Sélectionner un fichier de dictionnaire à installer"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Installer ce fichier pour la langue \"<xliff:g id="LOCALE_NAME">%s</xliff:g>\" ?"</string>
+ <string name="error" msgid="8940763624668513648">"Une erreur s\'est produite"</string>
+ <string name="button_default" msgid="3988017840431881491">"Par défaut"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Bienvenue dans <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"avec la saisie gestuelle"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Commencer"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Étape suivante"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"Configurer <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"Activer <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Sous \"Langue et saisie\", cochez \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" pour autoriser son exécution sur l\'appareil."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"L\'application \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" est déjà activée dans vos paramètres \"Langue et saisie\". Passez à l\'étape suivante."</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Activer le clavier dans les paramètres"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"Basculer vers <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Sélectionnez ensuite \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" comme mode de saisie actif."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Changer de mode de saisie"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Félicitations, l\'opération est terminée"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>, vous pouvez saisir du texte dans toutes vos applications préférées."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Configurer des langues supplémentaires"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"OK"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Afficher icône application"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Afficher l\'icône de l\'application dans le lanceur"</string>
+ <string name="app_name" msgid="6320102637491234792">"Fournisseur de dictionnaires"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Fournisseur de dictionnaires"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Service de dictionnaires"</string>
+ <string name="download_description" msgid="6014835283119198591">"Informations relatives à la mise à jour des dictionnaires"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Dictionnaires complémentaires"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Dictionnaire disponible"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Paramètres des dictionnaires"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"Dictionnaires personnels"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"Dictionnaire personnel"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Dictionnaire disponible"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Téléchargement en cours…"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Installé"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Installé, désactivé"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Pas de service dico."</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Aucun dictionnaire"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Actualiser"</string>
+ <string name="last_update" msgid="730467549913588780">"Dernière mise à jour"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Recherche de mises à jour en cours…"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Chargement en cours..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Dictionnaire principal"</string>
+ <string name="cancel" msgid="6830980399865683324">"Annuler"</string>
+ <string name="install_dict" msgid="180852772562189365">"Installer"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Annuler"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Supprimer"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Un dictionnaire est disponible pour la langue sélectionnée sur votre appareil mobile.&lt;br/&gt; Nous vous invitons à &lt;b&gt;télécharger&lt;/b&gt; le dictionnaire <xliff:g id="LANGUAGE">%1$s</xliff:g> pour faciliter votre saisie.&lt;br/&gt; &lt;br/&gt; Le téléchargement peut prendre une à deux minutes via une connexion 3G. Des frais peuvent s\'appliquer si vous ne disposez pas d\'un &lt;b&gt;forfait Internet illimité&lt;/b&gt;.&lt;br/&gt; Si vous n\'êtes pas sûr de votre forfait, nous vous conseillons d\'utiliser une connexion Wi-Fi pour lancer automatiquement le téléchargement.&lt;br/&gt; &lt;br/&gt; Astuce : Vous pouvez télécharger et supprimer des dictionnaires dans la section &lt;b&gt;Langue et saisie&lt;/b&gt; du menu &lt;b&gt;Paramètres&lt;/b&gt; de votre appareil mobile."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Télécharger (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> Mo)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Télécharger via Wi-Fi"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"Un dictionnaire est disponible en <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Appuyez ici pour consulter et télécharger le dictionnaire."</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"En cours de téléchargement. Des suggestions pour la langue suivante seront bientôt disponibles : <xliff:g id="LANGUAGE">%1$s</xliff:g>."</string>
+ <string name="version_text" msgid="2715354215568469385">"Version <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Ajouter"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Ajouter au dictionnaire"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Expression"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Plus d\'options"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Moins d\'options"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Mot :"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Raccourci :"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Langue :"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Saisissez un mot"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Raccourci facultatif"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Modifier le mot"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Modifier"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Supprimer"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"Votre dictionnaire personnel ne contient aucun mot. Ajoutez un mot en appuyant sur le bouton d\'ajout (\"+\")."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Pour toutes les langues"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Plus de langues…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Supprimer"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
</resources>
diff --git a/java/res/values-hy-rAM/strings-appname.xml b/java/res/values-hy-rAM/strings-appname.xml
new file mode 100644
index 000000000..dc3c0c678
--- /dev/null
+++ b/java/res/values-hy-rAM/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Ստեղնաշար (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android տառասխալների ուղղիչ (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android ստեղնաշարի կարգավորումներ (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android տառասխալների ուղղիչի կարգավորումներ (AOSP)"</string>
+</resources>
diff --git a/java/res/values-hy-rAM/strings.xml b/java/res/values-hy-rAM/strings.xml
new file mode 100644
index 000000000..fdf07420c
--- /dev/null
+++ b/java/res/values-hy-rAM/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Ներածման ընտրանքներ"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Հետազոտական գրառումների հրամաններ"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Փնտրել կոնտակտային անուններ"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Տառասխալների ուղղիչն օգտագործում է ձեր կոնտակտների ցանկի տվյալները"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Թրթռալ սեղմման ժամանակ"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Ձայնը սեղմման ժամանակ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Ելնող պատուհան՝ ստեղնի հպման դեպքում"</string>
+ <string name="general_category" msgid="1859088467017573195">"Ընդհանուր"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Տեքստի ուղղում"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Ժեստերով մուտքագրում"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Այլ ընտրանքներ"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Ընդլայնված կարգավորումներ"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Ընտրանքներ փորձագետների համար"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Անցնել մուտքագրման այլ եղանակների"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Լեզվի փոխարկման բանալին ընդգրկում է այլ մուտքագրման եղանակներ ևս"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Լեզվի փոխարկման ստեղն"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Ցույց տալ, երբ մուտքագրման մի քանի լեզուներ են միացված"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Ցուցադրել սահքի ցուցիչը"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Ցուցադրել տեսողական հուշումը Shift-ի կամ նշանների ստեղներից սահեցման ընթացքում"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Ելնող պատուհանի հեռացման հետաձգման ստեղն"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Առանց հետաձգման"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Նախնականը"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>մվ"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Համակարգի լռելյայնները"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Առաջարկել կոնտակտների անունները"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Օգտագործել կոնտակտների անունները՝ առաջարկների և ուղղումների համար"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Կրկնաբացակի վերջակետ"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Բացակի ստեղնի կրկնակի հպումը բացակից հետո վերջակետ է դնում"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Ավտոմատ գլխատառացում"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Գլխատառել յուրաքանչյուր նախադասության առաջին բառը"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Անհատական բառարան"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ավելացնել բառարաններ"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Հիմնական բառարան"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Ցուցադրել ուղղումների առաջարկներ"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Ցուցադրել առաջարկվող բառերը մուտքագրման ընթացքում"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Միշտ ցուցադրել"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Ցուցադրել դիմանկարային ռեժիմում"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Միշտ թաքցնել"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Արգելափակել վիրավորական բառերը"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Չառաջարկել հավանական վիրավորական բառերը"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Ինքնուղղում"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Տպագրական սխալով բառերում ավտոմատ տեղադրել բացակներն ու կետադրական նշանները"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Անջատված"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Համեստ"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Ագրեսիվ"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Շատ ագրեսիվ"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Հաջորդ բառի առաջարկներ"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Առաջարկներ կազմելու համար օգտագործել նախորդ բառը"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Միացնել ժեստերով մուտքագրումը"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Մուտքագրեք բառ` սահեցնելով տառերը"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Ցույց տալ ժեստի հետագիծը"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Դինամիկ սահող նախատեսք"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Տեսեք առաջարկված բառը՝ ժեստի միջոցով"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>` պահված է"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Առաջ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Հաջորդը"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Նխրդ"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Կատարված է"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Ուղարկել"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Դադար"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Սպասել"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Միացրեք ականջակալը՝ բարձրաձայն արտասանվող գաղտնաբառը լսելու համար:"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Տվյալ տեքստը %s է"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Տեքստ չի մուտքագրվել"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Բանալու կոդը՝ %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift-ը միացված է (հպել անջատելու համար)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps lock-ը միացված է (հպել՝ անջատելու համար)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Ջնջել"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Նշաններ"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Տառեր"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Թվեր"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Կարգավորումներ"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Բացակ"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Ձայնային մուտքագրում"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Ժպիտ"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Վերադարձ"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Որոնել"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Կետ"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Փոխել լեզուն"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Հաջորդը"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Նախորդը"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift-ը միացված է"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock-ը միացված է"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift-ն անջատված է"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Նշանների ռեժիմ"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Տառերի ռեժիմ"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Հեռախոսային ռեժիմ"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Հեռախոսի նշանների ռեժիմ"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Ստեղնաշարը թաքցված է"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"Ցուցադրված է <xliff:g id="MODE">%s</xliff:g> ստեղնաշարը"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"ամսաթիվ"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"ամսաթիվ և ժամ"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"էլփոստ"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"նամակագրություն"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"թվեր"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"հեռախոսահամար"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"տեքստ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"ժամանակ"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Ձայնային մուտքագրման ստեղն"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Հիմնական ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Նշանների ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Անջատված"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Բարձրախոս հիմնական ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Բարձրախոս նշանների ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Ձայնային մուտքագրումն անջատված է"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Կարգավորել մուտքագրման մեթոդները"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Մուտքագրման լեզուներ"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Արձագանքել"</string>
+ <string name="select_language" msgid="3693815588777926848">"Մուտքագրման լեզուներ"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Պահպանելու համար կրկին հպեք"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Բառարանն առկա է"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Միացնել օգտվողի արձագանքը"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Օգնել բարելավել այս մուտքագրման եղանակի խմբագրիչը՝ ինքնուրույն ուղարկելով Google-ին օգտագործման վիճակագրությունն ու վթարների հաշվետվությունները:"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Ստեղնաշարի թեման"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"Անգլերեն (ՄԹ)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"Անգլերեն (ԱՄՆ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"Իսպաներեն (ԱՄՆ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Անգլերեն (ՄԹ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Անգլերեն (ԱՄՆ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Իսպաներեն (ԱՄՆ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (ավանդական)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Ոչ մի լեզվով (Այբուբեն)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Այբուբեն (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Այբուբեն (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Այբուբեն (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Այբուբեն (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Այբուբեն (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Այբուբեն (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Զմայլիկներ"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Մուտքագրման հատուկ ոճեր"</string>
+ <string name="add_style" msgid="6163126614514489951">"Ավելացնել ոճ"</string>
+ <string name="add" msgid="8299699805688017798">"Ավելացնել"</string>
+ <string name="remove" msgid="4486081658752944606">"Հեռացնել"</string>
+ <string name="save" msgid="7646738597196767214">"Պահել"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Lեզու"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Դասավորություն"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Մուտքագրման ձեր հատուկ ոճը պետք է միացված լինի նախքան դուք կսկսեք օգտագործել այն: Ցանկանո՞ւմ եք միացնել այն հիմա:"</string>
+ <string name="enable" msgid="5031294444630523247">"Միացնել"</string>
+ <string name="not_now" msgid="6172462888202790482">"Ոչ հիմա"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Մուտքագրման այսպիսի ոճ արդեն գոյություն ունի՝ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Հարմարավետության ուսումնասիրության ռեժիմ"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ստեղնի երկար սեղմման ուշացում"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Սեղմման թրթռոցի տևողություն"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Սեղմման ձայնի բարձրությունը"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Կարդալ արտաքին բառարանի ֆայլը"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Ներբեռնումների թղթապանակում բառարանային ֆայլեր չկան"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Ընտրեք բառարանային ֆայլը տեղադրման համար"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Իրո՞ք ուզում եք տեղադրել այս ֆայլը <xliff:g id="LOCALE_NAME">%s</xliff:g>-ում:"</string>
+ <string name="error" msgid="8940763624668513648">"Տեղի է ունեցել սխալ"</string>
+ <string name="button_default" msgid="3988017840431881491">"Լռելյայնը"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Բարի գալուստ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"Ժեստային մուտքագրմամբ"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Սկսել"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Հաջորդ քայլը"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"Տեղադրվում է <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ը"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"Միացնել <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ը"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Խնդրում ենք ստուգել «<xliff:g id="APPLICATION_NAME">%s</xliff:g>»-ը ձեր Լեզվի &amp; մուտքագրման կարգավորումներում: Դա կլիազորի նրան գործարկվել ձեր սարքում:"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-ն արդեն միացված է ձեր Լեզվի &amp; մուտքագրման կարգավորումներում, ուստի այս քայլն արված է: Անցնել հաջորդին:"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Միացնել կարգավորումներից"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"Փոխարկել <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ին"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Հաջորդիվ, ընտրեք «<xliff:g id="APPLICATION_NAME">%s</xliff:g>»-ը որպես ձեր ակտիվ տեքստային մուտքագրման եղանակ:"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Փոխարկել մուտքագրման եղանակները"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Շնորհավորում ենք, դուք տեղադրեցիք բոլորը:"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Այժմ դուք կարող եք մուտքագրել ձեր բոլոր սիրելի հավելվածներում <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ով:"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Կարգավորել լրացուցիչ լեզուները"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Ավարտված"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Ցույց տալ հավելվածի պատկերակը"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Ցուցադրել հավելվածի պատկերակը թողարկչում"</string>
+ <string name="app_name" msgid="6320102637491234792">"Բառարանի մատակարար"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Բառարանի մատակարար"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Բառարանի ծառայություն"</string>
+ <string name="download_description" msgid="6014835283119198591">"Տեղեկություններ բառարանների թարմացման մասին"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Ավելացնել բառարաններ"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Բառարանն առկա է"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Բառարանների կարգավորումներ"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"Օգտվողի բառարաններ"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"Օգտվողի բառարան"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Բառարանն առկա է"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Այս պահին ներբեռնվում է"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Տեղադրված է"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Տեղադրված է, անջատված է"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Բառարանային ծառայությանը միացման խնդիր կա"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Բառարաններ չկան"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Թարմացնել"</string>
+ <string name="last_update" msgid="730467549913588780">"Վերջին անգամ թարմացվել է"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Ստուգվում է թարմացումների առկայությունը"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Բեռնվում է..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Հիմնական բառարան"</string>
+ <string name="cancel" msgid="6830980399865683324">"Չեղարկել"</string>
+ <string name="install_dict" msgid="180852772562189365">"Տեղադրել"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Չեղարկել"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Ջնջել"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Ձեր բջջային սարքում ընտրված լեզվով առկա է բառարան:<br/> Խորհուրդ ենք տալիս &lt;b&gt;ներբեռնել&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> բառարանը ձեր մուտքագրման հմտությունների բարելավման համար:&lt;br/&gt; &lt;br/&gt; Ներբեռնումը կարող է խլել մեկ կամ երկու րոպե 3G-ի դեպքում: Հնարավոր է գանձում կատարվի, եթե դուք չունեք &lt;b&gt;տվյալների անսահմանափակ փաթեթ&lt;/b&gt;.&lt;br/&gt; Եթե դուք վստահ չեք, թե տվյալների որ փաթեթն ունեք, խորհուրդ ենք տալիս գտնել Wi-Fi կապ՝ ներբեռնումն ավտոմատ սկսելու համար:&lt;br/&gt; &lt;br/&gt; Հուշում. դուք կարող եք ներբեռնել և հեռացնել բառարաններ՝ գնալով ձեր բջջային սարքի &lt;b&gt;Կարգավորումներ ցանկի Լեզու &amp; մուտքագրման&lt;/b&gt; բաժինը:"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Ներբեռնել հիմա (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>Մբ)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Ներբեռնել Wi-Fi-ով"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g>-ով առկա է մի բառարան"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Սեղմեք՝ վերանայելու և ներբեռնելու համար"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Ներբեռնվում է. <xliff:g id="LANGUAGE">%1$s</xliff:g>-ի համար առաջարկները շուտով պատրաստ կլինեն:"</string>
+ <string name="version_text" msgid="2715354215568469385">"Տարբերակ <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Ավելացնել"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Ավելացնել բառարանում"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Արտահայտություն"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Այլ ընտրանքներ"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Սակավ ընտրանքներ"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"Լավ"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Բառը՝"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Դյուրանցումը՝"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Lեզուն՝"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Մուտքագրեք բառը"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Ընտրովի դյուրանցում"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Խմբագրել բառը"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Խմբագրել"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Ջնջել"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"Դուք չունեք ոչ մի բառ օգտվողի բառարանում: Ավելացնել բառեր՝ հպելով Ավելացնել (+) կոճակը:"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Բոլոր լեզուներով"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Ավելի շատ լեզուներով..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Ջնջել"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
+</resources>
diff --git a/java/res/values-hy/strings-appname.xml b/java/res/values-hy/strings-appname.xml
new file mode 100644
index 000000000..dc3c0c678
--- /dev/null
+++ b/java/res/values-hy/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Ստեղնաշար (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android տառասխալների ուղղիչ (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android ստեղնաշարի կարգավորումներ (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android տառասխալների ուղղիչի կարգավորումներ (AOSP)"</string>
+</resources>
diff --git a/java/res/values-hy/strings.xml b/java/res/values-hy/strings.xml
new file mode 100644
index 000000000..ec4eb4651
--- /dev/null
+++ b/java/res/values-hy/strings.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Ներածման ընտրանքներ"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Հետազոտական գրառումների հրամաններ"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Փնտրել կոնտակտային անուններ"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Տառասխալների ուղղիչն օգտագործում է ձեր կոնտակտների ցանկի տվյալները"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Թրթռալ սեղմման ժամանակ"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Ձայնը սեղմման ժամանակ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Ելնող պատուհան՝ ստեղնի հպման դեպքում"</string>
+ <string name="general_category" msgid="1859088467017573195">"Ընդհանուր"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Տեքստի ուղղում"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Ժեստերով մուտքագրում"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Այլ ընտրանքներ"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Ընդլայնված կարգավորումներ"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Ընտրանքներ փորձագետների համար"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Անցնել մուտքագրման այլ եղանակների"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Լեզվի փոխարկման բանալին ընդգրկում է այլ մուտքագրման եղանակներ ևս"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Լեզվի փոխարկման ստեղն"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Ցույց տալ, երբ մուտքագրման մի քանի լեզուներ են միացված"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Ցուցադրել սահքի ցուցիչը"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Ցուցադրել տեսողական հուշումը Shift-ի կամ նշանների ստեղներից սահեցման ընթացքում"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Ելնող պատուհանի հեռացման հետաձգման ստեղն"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Առանց հետաձգման"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Նախնականը"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>մվ"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Համակարգի լռելյայնները"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Առաջարկել կոնտակտների անունները"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Օգտագործել կոնտակտների անունները՝ առաջարկների և ուղղումների համար"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Կրկնաբացակի վերջակետ"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Բացակի ստեղնի կրկնակի հպումը բացակից հետո վերջակետ է դնում"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Ավտոմատ գլխատառացում"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Գլխատառել յուրաքանչյուր նախադասության առաջին բառը"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Անհատական բառարան"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ավելացնել բառարաններ"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Հիմնական բառարան"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Ցուցադրել ուղղումների առաջարկներ"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Ցուցադրել առաջարկվող բառերը մուտքագրման ընթացքում"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Միշտ ցուցադրել"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Ցուցադրել դիմանկարային ռեժիմում"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Միշտ թաքցնել"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Արգելափակել վիրավորական բառերը"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Չառաջարկել հավանական վիրավորական բառերը"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Ինքնուղղում"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Տպագրական սխալով բառերում ավտոմատ տեղադրել բացակներն ու կետադրական նշանները"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Անջատված"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Համեստ"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Ագրեսիվ"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Շատ ագրեսիվ"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Հաջորդ բառի առաջարկներ"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Առաջարկներ կազմելու համար օգտագործել նախորդ բառը"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Միացնել ժեստերով մուտքագրումը"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Մուտքագրեք բառ` սահեցնելով տառերը"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Ցույց տալ ժեստի հետագիծը"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Դինամիկ սահող նախատեսք"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Տեսեք առաջարկված բառը՝ ժեստի միջոցով"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>` պահված է"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Առաջ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Հաջորդը"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Նխրդ"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Կատարված է"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Ուղարկել"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Դադար"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Սպասել"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Միացրեք ականջակալը՝ բարձրաձայն արտասանվող գաղտնաբառը լսելու համար:"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Տվյալ տեքստը %s է"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Տեքստ չի մուտքագրվել"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Բանալու կոդը՝ %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift-ը միացված է (հպել անջատելու համար)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps lock-ը միացված է (հպել՝ անջատելու համար)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Ջնջել"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Նշաններ"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Տառեր"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Թվեր"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Կարգավորումներ"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Բացակ"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Ձայնային մուտքագրում"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Ժպիտ"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Վերադարձ"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Որոնել"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Կետ"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Փոխել լեզուն"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Հաջորդը"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Նախորդը"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift-ը միացված է"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock-ը միացված է"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift-ն անջատված է"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Նշանների ռեժիմ"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Տառերի ռեժիմ"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Հեռախոսային ռեժիմ"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Հեռախոսի նշանների ռեժիմ"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Ստեղնաշարը թաքցված է"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"Ցուցադրված է <xliff:g id="MODE">%s</xliff:g> ստեղնաշարը"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"ամսաթիվ"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"ամսաթիվ և ժամ"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"էլփոստ"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"նամակագրություն"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"թվեր"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"հեռախոսահամար"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"տեքստ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"ժամանակ"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Ձայնային մուտքագրման ստեղն"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Հիմնական ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Նշանների ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Անջատված"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Բարձրախոս հիմնական ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Բարձրախոս նշանների ստեղնաշարի վրա"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Ձայնային մուտքագրումն անջատված է"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Կարգավորել մուտքագրման մեթոդները"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Մուտքագրման լեզուներ"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Արձագանքել"</string>
+ <string name="select_language" msgid="3693815588777926848">"Մուտքագրման լեզուներ"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Պահպանելու համար կրկին հպեք"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Բառարանն առկա է"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Միացնել օգտվողի արձագանքը"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Օգնել բարելավել այս մուտքագրման եղանակի խմբագրիչը՝ ինքնուրույն ուղարկելով Google-ին օգտագործման վիճակագրությունն ու վթարների հաշվետվությունները:"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Ստեղնաշարի թեման"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"Անգլերեն (ՄԹ)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"Անգլերեն (ԱՄՆ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"Իսպաներեն (ԱՄՆ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Անգլերեն (ՄԹ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Անգլերեն (ԱՄՆ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Իսպաներեն (ԱՄՆ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Ոչ մի լեզվով (Այբուբեն)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Այբուբեն (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Այբուբեն (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Այբուբեն (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Այբուբեն (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Այբուբեն (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Այբուբեն (PC)"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Մուտքագրման հատուկ ոճեր"</string>
+ <string name="add_style" msgid="6163126614514489951">"Ավելացնել ոճ"</string>
+ <string name="add" msgid="8299699805688017798">"Ավելացնել"</string>
+ <string name="remove" msgid="4486081658752944606">"Հեռացնել"</string>
+ <string name="save" msgid="7646738597196767214">"Պահել"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Lեզու"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Դասավորություն"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Մուտքագրման ձեր հատուկ ոճը պետք է միացված լինի նախքան դուք կսկսեք օգտագործել այն: Ցանկանո՞ւմ եք միացնել այն հիմա:"</string>
+ <string name="enable" msgid="5031294444630523247">"Միացնել"</string>
+ <string name="not_now" msgid="6172462888202790482">"Ոչ հիմա"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Մուտքագրման այսպիսի ոճ արդեն գոյություն ունի՝ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Հարմարավետության ուսումնասիրության ռեժիմ"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ստեղնի երկար սեղմման ուշացում"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Սեղմման թրթռոցի տևողություն"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Սեղմման ձայնի բարձրությունը"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Կարդալ արտաքին բառարանի ֆայլը"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Ներբեռնումների թղթապանակում բառարանային ֆայլեր չկան"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Ընտրեք բառարանային ֆայլը տեղադրման համար"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Իրո՞ք ուզում եք տեղադրել այս ֆայլը <xliff:g id="LOCALE_NAME">%s</xliff:g>-ում:"</string>
+ <string name="error" msgid="8940763624668513648">"Տեղի է ունեցել սխալ"</string>
+ <string name="button_default" msgid="3988017840431881491">"Լռելյայնը"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Բարի գալուստ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"Ժեստային մուտքագրմամբ"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Սկսել"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Հաջորդ քայլը"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"Տեղադրվում է <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ը"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"Միացնել <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ը"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Խնդրում ենք ստուգել «<xliff:g id="APPLICATION_NAME">%s</xliff:g>»-ը ձեր Լեզվի &amp; մուտքագրման կարգավորումներում: Դա կլիազորի նրան գործարկվել ձեր սարքում:"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-ն արդեն միացված է ձեր Լեզվի &amp; մուտքագրման կարգավորումներում, ուստի այս քայլն արված է: Անցնել հաջորդին:"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Միացնել կարգավորումներից"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"Փոխարկել <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ին"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Հաջորդիվ, ընտրեք «<xliff:g id="APPLICATION_NAME">%s</xliff:g>»-ը որպես ձեր ակտիվ տեքստային մուտքագրման եղանակ:"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Փոխարկել մուտքագրման եղանակները"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Շնորհավորում ենք, դուք տեղադրեցիք բոլորը:"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Այժմ դուք կարող եք մուտքագրել ձեր բոլոր սիրելի հավելվածներում <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ով:"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Կարգավորել լրացուցիչ լեզուները"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Ավարտված"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Ցույց տալ հավելվածի պատկերակը"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Ցուցադրել հավելվածի պատկերակը թողարկչում"</string>
+ <string name="app_name" msgid="6320102637491234792">"Բառարանի մատակարար"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Բառարանի մատակարար"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Բառարանի ծառայություն"</string>
+ <string name="download_description" msgid="6014835283119198591">"Տեղեկություններ բառարանների թարմացման մասին"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Ավելացնել բառարաններ"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Բառարանն առկա է"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Բառարանների կարգավորումներ"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"Օգտվողի բառարաններ"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"Օգտվողի բառարան"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Բառարանն առկա է"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Այս պահին ներբեռնվում է"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Տեղադրված է"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Տեղադրված է, անջատված է"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Բառարանային ծառայությանը միացման խնդիր կա"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Բառարաններ չկան"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Թարմացնել"</string>
+ <string name="last_update" msgid="730467549913588780">"Վերջին անգամ թարմացվել է"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Ստուգվում է թարմացումների առկայությունը"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Բեռնվում է..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Հիմնական բառարան"</string>
+ <string name="cancel" msgid="6830980399865683324">"Չեղարկել"</string>
+ <string name="install_dict" msgid="180852772562189365">"Տեղադրել"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Չեղարկել"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Ջնջել"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Ձեր բջջային սարքում ընտրված լեզվով առկա է բառարան:<br/> Խորհուրդ ենք տալիս &lt;b&gt;ներբեռնել&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> բառարանը ձեր մուտքագրման հմտությունների բարելավման համար:&lt;br/&gt; &lt;br/&gt; Ներբեռնումը կարող է խլել մեկ կամ երկու րոպե 3G-ի դեպքում: Հնարավոր է գանձում կատարվի, եթե դուք չունեք &lt;b&gt;տվյալների անսահմանափակ փաթեթ&lt;/b&gt;.&lt;br/&gt; Եթե դուք վստահ չեք, թե տվյալների որ փաթեթն ունեք, խորհուրդ ենք տալիս գտնել Wi-Fi կապ՝ ներբեռնումն ավտոմատ սկսելու համար:&lt;br/&gt; &lt;br/&gt; Հուշում. դուք կարող եք ներբեռնել և հեռացնել բառարաններ՝ գնալով ձեր բջջային սարքի &lt;b&gt;Կարգավորումներ ցանկի Լեզու &amp; մուտքագրման&lt;/b&gt; բաժինը:"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Ներբեռնել հիմա (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>Մբ)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Ներբեռնել Wi-Fi-ով"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g>-ով առկա է մի բառարան"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Սեղմեք՝ վերանայելու և ներբեռնելու համար"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Ներբեռնվում է. <xliff:g id="LANGUAGE">%1$s</xliff:g>-ի համար առաջարկները շուտով պատրաստ կլինեն:"</string>
+ <string name="version_text" msgid="2715354215568469385">"Տարբերակ <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Ավելացնել"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Ավելացնել բառարանում"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Արտահայտություն"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Այլ ընտրանքներ"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Սակավ ընտրանքներ"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"Լավ"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Բառը՝"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Դյուրանցումը՝"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Lեզուն՝"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Մուտքագրեք բառը"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Ընտրովի դյուրանցում"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Խմբագրել բառը"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Խմբագրել"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Ջնջել"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"Դուք չունեք ոչ մի բառ օգտվողի բառարանում: Ավելացնել բառեր՝ հպելով Ավելացնել (+) կոճակը:"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Բոլոր լեզուներով"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Ավելի շատ լեզուներով..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Ջնջել"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
+</resources>
diff --git a/java/res/values-ka-rGE/strings-appname.xml b/java/res/values-ka-rGE/strings-appname.xml
new file mode 100644
index 000000000..703c66aac
--- /dev/null
+++ b/java/res/values-ka-rGE/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android-ის კლავიატურა (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android-ის მართლწერის შემმოწმებელი (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android-ის კლავიატურის პარამეტრები (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android-ის მართლწერის შემმოწმებლის პარამეტრები (AOSP)"</string>
+</resources>
diff --git a/java/res/values-ka/strings-appname.xml b/java/res/values-ka/strings-appname.xml
new file mode 100644
index 000000000..703c66aac
--- /dev/null
+++ b/java/res/values-ka/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android-ის კლავიატურა (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android-ის მართლწერის შემმოწმებელი (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android-ის კლავიატურის პარამეტრები (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android-ის მართლწერის შემმოწმებლის პარამეტრები (AOSP)"</string>
+</resources>
diff --git a/java/res/values-kk/strings-appname.xml b/java/res/values-kk/strings-appname.xml
new file mode 100644
index 000000000..1e201fa9e
--- /dev/null
+++ b/java/res/values-kk/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android пернетақтасы (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android емлені тексеру құралы (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android пернетақтасының параметрлері (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android емлені тексеру құралының параметрлері (AOSP)"</string>
+</resources>
diff --git a/java/res/values-km-rKH/strings-appname.xml b/java/res/values-km-rKH/strings-appname.xml
new file mode 100644
index 000000000..e7b27072e
--- /dev/null
+++ b/java/res/values-km-rKH/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"ក្ដារចុច Android (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"កម្មវិធី​ពិនិត្យ​អក្ខរាវិរុទ្ធ Android (AOSP​)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"ការ​កំណត់​ក្ដារ​ចុច Android (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"កំណត់​​កម្មវិធី​ពិនិត្យ​​អក្ខរាវិរុទ្ធ​សម្រាប់ ​​Android (AOSP)"</string>
+</resources>
diff --git a/java/res/values-km-rKH/strings.xml b/java/res/values-km-rKH/strings.xml
new file mode 100644
index 000000000..aa40a7a02
--- /dev/null
+++ b/java/res/values-km-rKH/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ជម្រើស​​បញ្ចូល"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"ពាក្យ​បញ្ជា​កំណត់​ហេតុ​​ការ​ស្រាវជ្រាវ"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"រក​មើល​ឈ្មោះ​ទំនាក់ទំនង"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"កម្មវិធី​ពិនិត្យ​អក្ខរាវិរុទ្ធ​ប្រើ​ធាតុ​ពី​​ក្នុង​បញ្ជី​ទំនាក់ទំនង​របស់​អ្នក"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"ញ័រ​នៅ​ពេល​ចុច​គ្រាប់ចុច"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"សំឡេង​នៅ​ពេល​ចុច​គ្រាប់ចុច"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"លេច​ឡើង​នៅ​​ពេល​ចុច​គ្រាប់​ចុច"</string>
+ <string name="general_category" msgid="1859088467017573195">"ទូទៅ"</string>
+ <string name="correction_category" msgid="2236750915056607613">"ការ​កែ​អត្ថបទ"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"បញ្ចូល​ដោយ​ប្រើ​កាយវិការ"</string>
+ <string name="misc_category" msgid="6894192814868233453">"ជម្រើស​ផ្សេងទៀត"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"ការ​កំណត់​កម្រិត​ខ្ពស់"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"ជម្រើស​សម្រាប់​អ្នក​ជំនាញ"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"ប្ដូរ​ទៅ​​​វិធីសាស្ត្រ​បញ្ចូល​​​ផ្សេង​ទៀត"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"គ្រាប់ចុច​ប្ដូរ​ភាសា​តាម​វិធីសាស្ត្រ​បញ្ចូល​ផ្សេងទៀត"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"គ្រាប់​ចុច​ប្ដូរ​​ភាសា"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"បង្ហាញ​នៅ​ពេល​ដែល​បើក​ភាសា​បញ្ចូល​ច្រើន"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"បង្ហាញ​ទ្រនិច​បង្ហាញ​ស្លាយ"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"បង្ហាញ​​សញ្ញា​មើល​​ឃើញ​ខណៈ​ពេល​ដែល​រុញ​ពី​ឆ្វេង ឬ​​គ្រាប់​ចុច​​និមិត្ត​សញ្ញា"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"​សោ​លេចឡើង​បោះបង់​ការ​​ពន្យារពេល"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"គ្មាន​ការ​ពន្យារពេល"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"លំនាំដើម"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> មិល្លី​វិនាទី"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"លំនាំ​ដើម​​​ប្រព័ន្ធ"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"ស្នើ​ឈ្មោះ​ទំនាក់ទំនង"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ប្រើ​ឈ្មោះ​ពី​ទំនាក់ទំនង​សម្រាប់​ការ​​ស្នើ និង​​​កែ"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"រយៈ​ពេល​ចុច​ដកឃ្លា​ពីរដង"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"ប៉ះ​ដកឃ្លា​ពីរ​​ដង​បញ្ចូល​​​រយៈ​ពេល​ដែល​អនុវត្ត​តាម​ដកឃ្លា"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ការ​សរសេរ​ជា​អក្សរ​ធំ​​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"សរសេរ​ពាក្យ​ដំបូង​​​ជា​អក្សរ​ធំ​​នៃ​ប្រយោគ​នីមួយ​ៗ"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"វចនានុក្រម​ផ្ទាល់ខ្លួន"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"ផ្នែក​បន្ថែម​វចនានុក្រម"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"វចនានុក្រម​ចម្បង"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"បង្ហាញ​ការ​ស្នើ​​កែ"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"បង្ហាញ​ពាក្យ​​បាន​​ផ្ដល់​​ស្នើ​​ខណៈ​ពេល​​​វាយ​បញ្ចូល"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"បង្ហាញ​ជា​និច្ច"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"បង្ហាញ​នៅ​ក្នុង​របៀប​បញ្ឈរ"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"លាក់​ជានិច្ច"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"ទប់ស្កាត់​​ពាក្យ​​បំពាន"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"កុំ​ស្នើ​ឲ្យ​ពាក្យ​បំពាន​មាន​សក្ដានុពល"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ការ​កែ​​​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"ចន្លោះ​មិន​ឃើញ ​និង​សញ្ញា​​វណ្ណយុត្ត​កែ​ពាក្យ​ដែល​បាន​វាយ​ខុស​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"បិទ"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ល្មម"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"បំពាន"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"បំពាន​ខ្លាំង"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"ការ​ស្នើ​ពាក្យ​បន្ទាប់"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"ប្រើ​ពាក្យ​មុន​​នៅ​ពេល​ធ្វើ​ការ​​​ស្នើ"</string>
+ <string name="gesture_input" msgid="826951152254563827">"បើក​ការ​​បញ្ចូល​​កាយវិការ"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"បញ្ចូល​ពាក្យ​ដោយ​រំកិល​​​តាម​​អក្សរ"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"បង្ហាញ​ដាន​កាយវិការ"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"មើល​ការ​​អណ្ដែត​ដែល​មាន​ចលនា​ជា​មុន"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"​មើល​ពាក្យ​​​ដែល​បាន​ស្នើ​​​ខណៈ​ពេល​កំពុង​ធ្វើ​កាយ​វិការ"</string>
+ <string name="added_word" msgid="8993883354622484372">"បាន​រក្សាទុក <xliff:g id="WORD">%s</xliff:g> ៖"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"ទៅ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"បន្ទាប់"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"មុន"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"រួចរាល់"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"ផ្ញើ"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"ផ្អាក"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"រង់ចាំ"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"ដោត​កាស ដើម្បី​ស្ដាប់​ពាក្យ​សម្ងាត់។"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"អត្ថបទ​បច្ចុប្បន្ន​គឺ %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"គ្មាន​អត្ថបទ​​​បាន​បញ្ចូល"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"កូដ​គ្រាប់​ចុច %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"បើក Shift (​ប៉ះ​ដើម្បី​បិទ)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"បើក Caps lock (ប៉ះ​​ដើម្បី​បិទ)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"និមិត្ត​សញ្ញា"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"អក្សរ"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"លេខ"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"ការ​កំណត់"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"ដកឃ្លា"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"បញ្ចូលសំឡេង"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"មុខ​ញញឹម"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"ស្វែងរក"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"ប្ដូរ​​ភាសា"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"បន្ទាប់"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"មុន"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"បាន​បើក Shift"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"បាន​បើក Caps lock"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"បាន​បិទ Shift"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"របៀប​និមិត្តសញ្ញា"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"របៀប​អក្សរ"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"របៀប​ទូរស័ព្ទ"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"​របៀប​និមិត្ត​សញ្ញា​ទូរស័ព្ទ"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"បាន​លាក់​ក្ដារចុច"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"បង្ហាញ​ក្ដារ​ចុច <xliff:g id="MODE">%s</xliff:g>"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"កាលបរិច្ឆេទ"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"កាល​បរិច្ឆេទ​ និង​ពេល​វេលា"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"អ៊ីមែល"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"​ផ្ញើ​សារ"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"លេខ"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"ទូរស័ព្ទ"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"អត្ថបទ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"ពេលវេលា"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"គ្រាប់​ចុច​បញ្ចូល​​សំឡេង"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"នៅ​លើ​ក្ដារចុច​ចម្បង"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"នៅ​លើ​ក្ដារចុច​​និមិត្ត​សញ្ញា"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"បិទ"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"មីក្រូហ្វូន​នៅ​លើ​​ក្ដារចុច​ចម្បង"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"មីក្រូហ្វូន​នៅ​លើ​​ក្ដារចុច​និមិត្ត​សញ្ញា"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"បាន​បិទ​ការ​បញ្ចូល​សំឡេង"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"កំណត់​រចនាសម្ព័ន្ធ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"បញ្ចូល​ភាសា"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"ផ្ញើ​មតិ​អ្នក​ប្រើ"</string>
+ <string name="select_language" msgid="3693815588777926848">"​​បញ្ចូល​ភាសា"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"ប៉ះ​ម្ដង​ទៀត​ ដើម្បី​រក្សា​ទុក"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"មាន​វចនានុក្រម"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"បើក​មតិត្រឡប់"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"ជំនួយ​​​ធ្វើ​ឲ្យ​​ប្រសើរ​ឡើង​​នៃ​កម្មវិធី​កែ​​វិធី​សាស្ត្រ​​បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ​ ដោយ​ផ្ញើ​ស្ថិតិ​​ប្រើ​ប្រាស់​ ​និង​របាយការណ៍​គាំង"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"រូបរាង​ក្ដារចុច"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"អង់គ្លេស (​អង់គ្លេស)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"អង់គ្លេស (សហរដ្ឋ​អាមេរិក)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"អេស្ប៉ាញ (សហរដ្ឋ​អាមេរិក​)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"អង់គ្លេស (ចក្រភព​អង់គ្លេស) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"អង់គ្លេស (អាមេរិក) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"អេស្ប៉ាញ (អាមេរិក​) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (អក្សរ​ពេញ​)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"គ្មាន​ភាសា (អក្សរ​ក្រម)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"តាម​លំដាប់​អក្សរក្រម (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"តាម​លំដាប់​អក្សរក្រម (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"តាម​លំដាប់​អក្សរក្រម (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"តាម​លំដាប់​អក្សរក្រម (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"តាម​លំដាប់​អក្សរក្រម (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"តាម​លំដាប់​អក្សរក្រម (កុំព្យូទ័រ)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"សញ្ញា​អារម្មណ៍"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"រចនាប័ទ្ម​បញ្ចូល​ផ្ទាល់ខ្លួន"</string>
+ <string name="add_style" msgid="6163126614514489951">"បន្ថែម​រចនាប័ទ្ម"</string>
+ <string name="add" msgid="8299699805688017798">"បន្ថែម"</string>
+ <string name="remove" msgid="4486081658752944606">"លុប​ចេញ"</string>
+ <string name="save" msgid="7646738597196767214">"រក្សាទុក"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"ភាសា"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"ប្លង់"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"ចាំបាច់​ត្រូវ​បើក​រចនាប័ទ្ម​បញ្ចូល​ផ្ទាល់​ខ្លួន​របស់​អ្នក មុន​ពេល​អ្នក​ចាប់ផ្ដើម​ប្រើ​វា។ តើ​អ្នក​ចង់​បើក​វា​ឥឡូវ​នេះ​ឬ?"</string>
+ <string name="enable" msgid="5031294444630523247">"បើក"</string>
+ <string name="not_now" msgid="6172462888202790482">"មិនមែន​ឥឡូវ"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"មាន​រចនាប័ទ្ម​បញ្ចូល​ដូច​គ្នា​ដូច​ហើយ៖ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"របៀប​ការ​សិក្សា​ដែល​អាច​ប្រើ​បាន"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"ពន្យារពេល​​​ចុច​គ្រាប់​ចុច​ឲ្យ​​យូរ"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ថិរវេលា​​ញ័រ​​ពេល​ចុច​គ្រាប់ចុច"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"កម្រិត​សំឡេង​ពេល​ចុច​គ្រាប់​ចុច"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"អាន​ឯកសារ​វចនានុក្រម​ខាង​ក្រៅ"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"គ្មាន​ឯកសារ​វចនានុក្រម​នៅ​ក្នុង​ថត​ទាញ​យក"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ជ្រើស​ឯកសារ​វចនានុក្រម​ ដើម្បី​ដំឡើង"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"ពិត​ជា​ដំឡើង​ឯកសារ​នេះ​សម្រាប់ <xliff:g id="LOCALE_NAME">%s</xliff:g> ឬ?"</string>
+ <string name="error" msgid="8940763624668513648">"មាន​កំហុស"</string>
+ <string name="button_default" msgid="3988017840431881491">"លំនាំដើម"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"សូម​ស្វាគមន៍​មក​កាន់ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ជាមួយ​​​ការ​វាយ​បញ្ចូល​ដោយ​ប្រើ​​​កាយវិការ"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"បាន​ចាប់ផ្ដើម"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"ជំហាន​បន្ទាប់"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"រៀបចំ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"បើក <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"សូម​ពិនិត្យ​ \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" នៅ​ក្នុង​ការ​កំណត់​ភាសា &amp; និង​ការ​បញ្ចូល​របស់​អ្នក។ វា​នឹង​ដំណើរការ​នៅ​លើ​ឧបករណ៍​របស់​អ្នក។"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>បាន​បើក​នៅ​ក្នុង​​ការ​កំណត់​​ភាសា​ &amp; ការ​បញ្ចូល​របស់ ដូច្នេះ​ជំហាន​នេះ​រួចរាល់​ហើយ។ បន្ត​ទៅ​ជំហាន​បន្ទាប់!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"បើក​នៅ​ក្នុង​ការ​កំណត់"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"ប្ដូរ​ទៅ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"បន្ទាប់ ជ្រើស \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" ជា​វិធី​សាស្ត្រ​បញ្ចូល​អត្ថបទ​សកម្ម​របស់​អ្នក។"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"ប្ដូរ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"សូម​អបអរ​សាទរ,​ អ្នក​​បាន​កំណត់​​រួចរាល់​ហើយ!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"ឥឡូវ​​អ្នក​អាច​​វាយ​បញ្ចូល​នៅ​ក្នុង​​កម្មវិធី​​ពេញ​ចិត្ត​របស់​អ្នក​ទាំងអស់​ជាមួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ។"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"កំណត់​រចនា​សម្ព័ន្ធ​ភាសា​បន្ថែម"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"បាន​បញ្ចប់"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"បង្ហាញ​រូប​តំណាង​កម្មវិធី"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"បង្ហាញ​រូប​តំណាង​កម្មវិធី​នៅ​ក្នុង​កម្ម​​វិធី​ចាប់ផ្ដើម"</string>
+ <string name="app_name" msgid="6320102637491234792">"កម្មវិធី​ផ្ដល់​វចនានុក្រម"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"កម្មវិធី​ផ្ដល់​វចនានុក្រម"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"សេវាកម្ម​​វចនានុក្រម"</string>
+ <string name="download_description" msgid="6014835283119198591">"ព័ត៌មាន​បច្ចុប្បន្នភាព​វចនានុក្រម"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ផ្នែក​បន្ថែម​វចនានុក្រម"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"វចនានុក្រម​​​​​អាច​ប្រើ​បាន"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ការ​កំណត់​សម្រាប់​វចនានុក្រម"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"វចនានុក្រម​​​អ្នក​ប្រើ"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"វចនានុក្រម​អ្នកប្រើ"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"វចនានុក្រម​​​អាច​ប្រើ​បាន"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"បច្ចុប្បន្ន​កំពុង​ទាញ​យក"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"បាន​ដំឡើង"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"បាន​ដំឡើង បាន​បិទ"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"មាន​បញ្ហា​ក្នុង​ការ​​ភ្ជាប់​ទៅ​​សេវា​កម្ម​វចនានុក្រម"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"គ្មាន​វចនានុក្រម"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"ផ្ទុក​ឡើងវិញ"</string>
+ <string name="last_update" msgid="730467549913588780">"បាន​ធ្វើ​បច្ចុប្បន្នភាព​ចុងក្រោយ"</string>
+ <string name="message_updating" msgid="4457761393932375219">"ពិនិត្យមើល​បច្ចុប្បន្នភាព"</string>
+ <string name="message_loading" msgid="8689096636874758814">"កំពុង​ផ្ទុក..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"វចនានុក្រម​ចម្បង"</string>
+ <string name="cancel" msgid="6830980399865683324">"បោះ​បង់"</string>
+ <string name="install_dict" msgid="180852772562189365">"ដំឡើង"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"បោះ​បង់"</string>
+ <string name="delete_dict" msgid="756853268088330054">"លុប"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"ភាសា​ដែល​បាន​ជ្រើស​នៅ​លើ​ឧបករណ៍​របស់​អ្នក​មាន​វចនានុក្រម។ &lt;br/&gt; យើង​បាន​ផ្ដល់​អនុសាសន៍ &lt;b&gt;ទាញ​យក​&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> វចនានុក្រម ដើម្បី​ធ្វើ​ឲ្យ​ការ​វាយ​បញ្ចូល​របស់​អ្នក​ប្រសើរ​ឡើង។ &lt;br/&gt; &lt;br/&gt; ការ​ទាញ​យក​អាច​ចំណាយ​ពេល​​មួយ ឬ​ពីរ​នាទី​​​តាម 3G ។ ការ​​កាត់​លុយ​អាច​អនុវត្ត​ ប្រសិន​​​បើ​អ្នក​​បាន​​ &lt;b&gt;កំណត់​ទិន្នន័យ​គ្មាន​ដែន​កំណត់ &lt;/b&gt;.&lt;br/&gt; ប្រសិនបើ​​អ្នក​មិន​ប្រាកដ​​ថា​ទិន្នន័យ​អ្នក​​មិន​បាន​​កំណត់ យើង​បាន​ផ្ដល់​អនុសាសន៍​ដោយ​ស្វែងរក​ការ​ភ្ជាប់​​វ៉ាយហ្វាយ ដើម្បី​ចាប់ផ្ដើម​ទាញ​យក​ដោយ​ស្វ័យប្រវត្តិ។&lt;br/&gt; &lt;br/&gt; ព័ត៌មាន​ជំនួយ៖ អ្នក​អាច​ទាញ​យក និង​លុប​​វចនានុក្រម​​ដោយ​ចូល​ទៅ​ &lt;b&gt;ភាសា&amp; បញ្ចូល&lt;/b&gt;​នៅ​ក្នុង​ម៉ឺនុយ &lt;b&gt;ការ​កំណត់ &lt;/b&gt; របស់​ឧបករណ៍​ចល័ត។"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"ទាញ​យក​ឥឡូវ​នេះ (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> មេកាបៃ)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"ទាញ​យក​តាម​វ៉ាយហ្វាយ"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"វចនានុក្រម​​អាច​ប្រើ​បាន​​សម្រាប់ <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"ចុច​ ដើម្បី​ពិនិត្យ​មើល​ឡើង​​វិញ​ និង​ទាញ​យក"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"ទាញ​យក៖ ការ​​ស្នើ​សម្រាប់ <xliff:g id="LANGUAGE">%1$s</xliff:g> នឹង​បញ្ចប់​ឆាប់ៗ។"</string>
+ <string name="version_text" msgid="2715354215568469385">"កំណែ <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"បន្ថែម"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"បន្ថែម​ទៅ​វចនានុក្រម"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"ឃ្លា"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"ជម្រើស​ច្រើន"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"ជម្រើស​តិច"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"យល់ព្រម"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"ពាក្យ៖"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"ផ្លូវកាត់​៖"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ភាសា៖"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"វាយ​បញ្ចូល​ពាក្យ"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"ផ្លូវកាត់​ជា​ជម្រើស"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"កែ​ពាក្យ"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"កែ"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"លុប"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"អ្នក​មិន​មាន​ពាក្យ​ណាមួយ​នៅ​ក្នុង​វចនានុក្រម​អ្នក​ប្រើ​ទេ។ បន្ថែម​ពាក្យ​ដោយ​​​​ប៉ះ​ប៊ូតុង​ បន្ថែម ​ (+)។"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"សម្រាប់​ភាសា​ទាំងអស់"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"ភាសា​ច្រើន​ទៀត…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"លុប"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-km/strings-appname.xml b/java/res/values-km/strings-appname.xml
new file mode 100644
index 000000000..e7b27072e
--- /dev/null
+++ b/java/res/values-km/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"ក្ដារចុច Android (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"កម្មវិធី​ពិនិត្យ​អក្ខរាវិរុទ្ធ Android (AOSP​)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"ការ​កំណត់​ក្ដារ​ចុច Android (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"កំណត់​​កម្មវិធី​ពិនិត្យ​​អក្ខរាវិរុទ្ធ​សម្រាប់ ​​Android (AOSP)"</string>
+</resources>
diff --git a/java/res/values-km/strings.xml b/java/res/values-km/strings.xml
new file mode 100644
index 000000000..03b973885
--- /dev/null
+++ b/java/res/values-km/strings.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ជម្រើស​ការ​បញ្ចូល"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"ពាក្យ​បញ្ជា​កំណត់​ហេតុ​​ការ​ស្រាវជ្រាវ"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"រក​មើល​ឈ្មោះ​ទំនាក់ទំនង"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"កម្មវិធី​ពិនិត្យ​អក្ខរាវិរុទ្ធ​ប្រើ​ធាតុ​ពី​​ក្នុង​បញ្ជី​ទំនាក់ទំនង​របស់​អ្នក"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"ញ័រ​នៅ​ពេល​ចុច​គ្រាប់ចុច"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"សំឡេង​នៅ​ពេល​ចុច​គ្រាប់ចុច"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"លេច​ឡើង​នៅ​​ពេល​ចុច​គ្រាប់​ចុច"</string>
+ <string name="general_category" msgid="1859088467017573195">"ទូទៅ"</string>
+ <string name="correction_category" msgid="2236750915056607613">"ការ​កែ​អត្ថបទ"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"វាយ​ដោយ​ប្រើ​កាយវិការ"</string>
+ <string name="misc_category" msgid="6894192814868233453">"ជម្រើស​ផ្សេងទៀត"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"ការ​កំណត់​កម្រិត​ខ្ពស់"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"ជម្រើស​សម្រាប់​អ្នក​ជំនាញ"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"ប្ដូរ​ទៅ​​​វិធីសាស្ត្រ​បញ្ចូល​​​ផ្សេង​ទៀត"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"គ្រាប់ចុច​ប្ដូរ​ភាសា​តាម​វិធីសាស្ត្រ​បញ្ចូល​ផ្សេងទៀត"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"គ្រាប់​ចុច​ប្ដូរ​​ភាសា"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"បង្ហាញ​នៅ​ពេល​ដែល​បើក​ភាសា​បញ្ចូល​ច្រើន"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"បង្ហាញ​ទ្រនិច​បង្ហាញ​ស្លាយ"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"បង្ហាញ​អត្ថបទ​ដែល​មើល​ឃើញ​ខណៈ​ពេល​ដែល sliding ពី​គ្រាប់ចុច​ប្ដូរ​ឬ​និមិត្ត​សញ្ញា"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"កូនសោ​លេចឡើង​បោះបង់​ការ​​ពន្យារពេល"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"គ្មាន​ការ​ពន្យារពេល"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"លំនាំដើម"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"លំនាំ​ដើម​​​ប្រព័ន្ធ"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"ស្នើ​ឈ្មោះ​ទំនាក់ទំនង"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ប្រើ​ឈ្មោះ​ពី​ទំនាក់ទំនង​សម្រាប់​ការ​​ស្នើ និង​ការ​កែ"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"រយៈ​ពេល​ចុច space ពីរដង"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"ចុច​ tap ពីរ​​ដង​លើ​ spacebar រយៈ​ពេល​​បញ្ចូល​​​ដែល​បាន​អនុវត្ត​ដោយ​ចុច space"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ការ​សរសេរ​ជា​អក្សរ​ធំ​​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"សរសេរ​ពាក្យ​ដំបូង​​​ជា​អក្សរ​ធំ​​នៃ​ប្រយោគ​នីមួយ"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"វចនានុក្រម​ផ្ទាល់ខ្លួន"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"ផ្នែក​បន្ថែម​វចនានុក្រម"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"វចនានុក្រម​ចម្បង"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"បង្ហាញ​ការ​ស្នើ​ការ​កែ"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"បង្ហាញ​ពាក្យ​ដែល​បាន​​ផ្ដល់​យោបល់​ខណៈ​ពេល​​​វាយ​បញ្ចូល"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"បង្ហាញ​ជា​និច្ច"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"បង្ហាញ​នៅ​ក្នុង​របៀប​បញ្ឈរ"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"លាក់​ជានិច្ច"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"ប្លុក​ពាក្យ​ប្រមាថ​មើលងាយ"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"កុំ​ស្នើ​ឲ្យ​ពាក្យ​ប្រមាថ​មើលងាយ​មាន​សក្ដានុពល"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ការ​កែ​​​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Spacebar ​និង​សញ្ញា​​វណ្ណយុត្ត​កែ​ពាក្យ​ដែល​បាន​វាយ​ខុស​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"បិទ"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"តិចតួច"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"បំពាន"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"បំពាន​ខ្លាំង"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"ការ​ស្នើ​ពាក្យ​បន្ទាប់"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"ប្រើ​ពាក្យ​មុន​​នៅ​ពេល​ធ្វើ​ការ​​​ស្នើ"</string>
+ <string name="gesture_input" msgid="826951152254563827">"បើក​ការ​​បញ្ចូល​​កាយវិការ"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"បញ្ចូល​ពាក្យ​ដោយ​អនុវត្ត​​តាម​​អក្សរ"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"បង្ហាញ​ដាន​កាយវិការ"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"មើល​ការ​​អណ្ដែត​ដែល​មាន​ចលនា"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"​មើល​ពាក្យ​​​ដែល​បាន​ស្នើ​​​ខណៈ​ពេល​កំពុង​ធ្វើ​កាយ​វិការ"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : បាន​រក្សាទុក"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"ទៅ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"បន្ទាប់"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"មុន"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"រួចរាល់"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"ផ្ញើ"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"ផ្អាក"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"រង់ចាំ"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"ដោត​កាស ដើម្បី​ស្ដាប់​ពាក្យ​សម្ងាត់។"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"អត្ថបទ​បច្ចុប្បន្ន​គឺ %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"គ្មាន​អត្ថបទ​ដែល​បាន​បញ្ចូល"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"កូដ​គ្រាប់​ចុច %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"បើក Shift (ចុច tap ដើម្បី​បិទ)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"បើក Caps lock (ចុច​ tap ដើម្បី​បិទ)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"និមិត្ត​សញ្ញា"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letters"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"លេខ"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"ការ​កំណត់"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"ការ​បញ្ចូល​សំឡេង"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"មុខ​ញញឹម"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"ស្វែងរក"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"ប្ដូរ​​ភាសា"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"បន្ទាប់"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"មុន"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"បាន​បើក Shift"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"បាន​បើក Caps lock"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"បាន​បិទ Shift"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"របៀប​និមិត្តសញ្ញា"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"របៀប​អក្សរ"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"របៀប​ទូរស័ព្ទ"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"​របៀប​និមិត្ត​សញ្ញា​ទូរស័ព្ទ"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"បាន​លាក់​ក្ដារចុច"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"បង្ហាញ​ក្ដារ​ចុច <xliff:g id="MODE">%s</xliff:g>"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"កាលបរិច្ឆេទ"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"កាល​បរិច្ឆេទ​ និង​ពេល​វេលា"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"អ៊ីមែល"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"ការ​ផ្ញើ​សារ"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"លេខ"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"ទូរស័ព្ទ"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"អត្ថបទ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"ពេលវេលា"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"គ្រាប់​ចុច​បញ្ចូល​​សំឡេង"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"នៅ​លើ​ក្ដារចុច​ចម្បង"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"នៅ​លើ​ក្ដារចុច​​និមិត្ត​សញ្ញា"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"បិទ"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"មីក្រូហ្វូន​នៅ​លើ​​ក្ដារចុច​ចម្បង"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"មីក្រូហ្វូន​នៅ​លើ​​ក្ដារចុច​និមិត្ត​សញ្ញា"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"បាន​បិទ​ការ​បញ្ចូល​សំឡេង"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"កំណត់​រចនាសម្ព័ន្ធ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"បញ្ចូល​ភាសា"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"ផ្ញើ​មតិ​អ្នក​ប្រើ"</string>
+ <string name="select_language" msgid="3693815588777926848">"បញ្ចូល​ភាសា"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"ប៉ះ​ម្ដង​ទៀត​ដើម្បី​រក្សា​ទុក"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"មាន​វចនានុក្រម"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"បើក​មតិ​អ្នកប្រើ"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"ជំនួយ​​​ធ្វើ​ឲ្យ​​ប្រសើរ​ឡើង​​នៃ​កម្មវិធី​កែ​​វិធី​សាស្ត្រ​​បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ​ដោយ​ការ​ផ្ញើ​ស្ថិតិ​ការ​ប្រើ​ប្រាស់​ ​និង​របាយការណ៍​គាំង"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"រូបរាង​ក្ដារចុច"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"អង់គ្លេស (ចក្រភព​អង់គ្លេស)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"អង់គ្លេស (សហរដ្ឋ​អាមេរិក)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"អេស្ប៉ាញ (សហរដ្ឋ​អាមេរិក​)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"អង់គ្លេស (ចក្រភព​អង់គ្លេស) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"អង់គ្លេស (អាមេរិក) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"អេស្ប៉ាញ (អាមេរិក​) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"គ្មាន​ភាសា (អក្សរ​ក្រម)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"អក្សរ​ក្រម (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"អក្សរ​ក្រម (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"អក្សរ​ក្រម (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"អក្សរ​ក្រម (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"អក្សរ​ក្រម (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"អក្សរ​ក្រម (កុំព្យូទ័រ)"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"បញ្ចូល​រចនាប័ទ្ម​ផ្ទាល់​ខ្លួន"</string>
+ <string name="add_style" msgid="6163126614514489951">"បន្ថែម​រចនាប័ទ្ម"</string>
+ <string name="add" msgid="8299699805688017798">"បន្ថែម"</string>
+ <string name="remove" msgid="4486081658752944606">"លុប​ចេញ"</string>
+ <string name="save" msgid="7646738597196767214">"រក្សាទុក"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"ភាសា"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"ប្លង់"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"ចាំបាច់​ត្រូវ​បើក​រចនាប័ទ្ម​បញ្ចូល​ផ្ទាល់​ខ្លួន​របស់​អ្នក មុន​ពេល​អ្នក​ចាប់ផ្ដើម​ប្រើ​វា។ តើ​អ្នក​ចង់​បើក​វា​ឥឡូវ​នេះ​ឬ?"</string>
+ <string name="enable" msgid="5031294444630523247">"បើក"</string>
+ <string name="not_now" msgid="6172462888202790482">"មិនមែន​ឥឡូវ"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"បញ្ចូល​រចនាប័ទ្ម​ដូចគ្នា​រួច​ហើយ​: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"របៀប​ការ​សិក្សា​ដែល​អាច​ប្រើ​បាន"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"ពន្យារពេល​​​ចុច​គ្រាប់​ចុច​ឲ្យ​​យូរ"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"​ពេលវេលា​ញ័រ​​ពេល​ចុច​គ្រាប់ចុច"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"កម្រិត​សំឡេង​ពេល​ចុច​គ្រាប់​ចុច"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"អាន​ឯកសារ​វចនានុក្រម​ខាង​ក្រៅ"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"គ្មាន​ឯកសារ​វចនានុក្រម​នៅ​ក្នុង​ថត​ទាញ​យក​ទេ"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ជ្រើស​ឯកសារ​វចនានុក្រម​ដើម្បី​ដំឡើង"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"ពិត​ជា​ដំឡើង​ឯកសារ​នេះ​សម្រាប់ <xliff:g id="LOCALE_NAME">%s</xliff:g> ឬ?"</string>
+ <string name="error" msgid="8940763624668513648">"មាន​កំហុស"</string>
+ <string name="button_default" msgid="3988017840431881491">"លំនាំដើម"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"សូម​ស្វាគមន៍​មក​កាន់ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ជាមួយ​​​ការ​វាយ​ដោយ​ប្រើ​​​កាយវិការ"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"បាន​ចាប់ផ្ដើម"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"ជំហាន​បន្ទាប់"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"រៀបចំ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"បើក <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"សូម​ពិនិត្យមើល \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" នៅ​ក្នុង​ការ​កំណត់​ភាសា &amp; និង​ការ​បញ្ចូល​របស់​អ្នក។ វា​នឹង​ដំណើរការ​នៅ​លើ​ឧបករណ៍​របស់​អ្នក។"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> បាន​បើក​នៅ​ក្នុង​​ការ​កំណត់​​ភាសា​ &amp; ការ​បញ្ចូល​របស់ ដូច្នេះ​ជំហាន​នេះ​រួចរាល់​ហើយ។ បន្ត​ទៅ​ជំហាន​បន្ទាប់!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"បើក​នៅ​ក្នុង​ការ​កំណត់"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"ប្ដូរ​ទៅ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"បន្ទាប់ ជ្រើស \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" ជា​វិធី​សាស្ត្រ​បញ្ចូល​អត្ថបទ​សកម្ម​របស់​អ្នក។"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"ប្ដូរ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"អបអរ​សាទរ​ អ្នក​​បាន​កំណត់​ទាំងអស់​ហើយ!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"ឥឡូវ​នេះ​អ្នក​អាច​​វាយ​បញ្ចូល​នៅ​ក្នុង​​កម្មវិធី​សំណព្វ​របស់​អ្នក​ទាំងអស់​ជាមួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ។"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"កំណត់​រចនា​សម្ព័ន្ធ​ភាសា​បន្ថែម"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"បាន​បញ្ចប់"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"បង្ហាញ​រូប​តំណាង​កម្មវិធី"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"បង្ហាញ​រូប​តំណាង​កម្មវិធី​នៅ​ក្នុង​កម្ម​​វិធី​ចាប់ផ្ដើម"</string>
+ <string name="app_name" msgid="6320102637491234792">"កម្មវិធី​ផ្ដល់​វចនានុក្រម"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"កម្មវិធី​ផ្ដល់​វចនានុក្រម"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"សេវា​វចនានុក្រម"</string>
+ <string name="download_description" msgid="6014835283119198591">"ព័ត៌មាន​បច្ចុប្បន្នភាព​វចនានុក្រម"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ផ្នែក​បន្ថែម​វចនានុក្រម"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"វចនានុក្រម​ដែល​​​អាច​ប្រើ​បាន"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ការ​កំណត់​សម្រាប់​វចនានុក្រម"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"វចនានុក្រម​​​អ្នក​ប្រើ"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"វចនានុក្រម​អ្នក​ប្រើ"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"វចនានុក្រម​​ដែល​អាច​ប្រើ​បាន"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"បច្ចុប្បន្ន​កំពុង​ទាញយក"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"បាន​ដំឡើង"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"បាន​ដំឡើង បាន​បិទ"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"មាន​បញ្ហា​ក្នុង​ការ​តភ្ជាប់​ទៅ​​សេវា​វចនានុក្រម"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"គ្មាន​វចនានុក្រម"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"ធ្វើ​ឲ្យ​ស្រស់"</string>
+ <string name="last_update" msgid="730467549913588780">"បាន​ធ្វើ​បច្ចុប្បន្នភាព​ចុងក្រោយ"</string>
+ <string name="message_updating" msgid="4457761393932375219">"ពិនិត្យមើល​បច្ចុប្បន្នភាព"</string>
+ <string name="message_loading" msgid="8689096636874758814">"កំពុង​ផ្ទុក..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"វចនានុក្រម​ចម្បង"</string>
+ <string name="cancel" msgid="6830980399865683324">"បោះ​បង់"</string>
+ <string name="install_dict" msgid="180852772562189365">"ដំឡើង"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"បោះ​បង់"</string>
+ <string name="delete_dict" msgid="756853268088330054">"លុប"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"ភាសា​ដែល​បាន​ជ្រើស​នៅ​លើ​ឧបករណ៍​របស់​អ្នក​មាន​វចនានុក្រម។ &lt;br/&gt; យើង​បាន​ផ្ដល់​អនុសាសន៍ &lt;b&gt; ទាញ​យក​ &lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> វចនានុក្រម ដើម្បី​ធ្វើ​ឲ្យ​ការ​វាយ​បញ្ចូល​របស់​អ្នក​ប្រសើរ​ឡើង។ &lt;br/&gt; &lt;br/&gt; ការ​ទាញ​យក​អាច​ចំណាយ​ពេល​​មួយ ឬ​ពីរ​នាទី​​​តាម 3G ។ អាច​អនុវត្ត​ប្រសិនបើ​អ្នក​មិន​​បាន​ &lt;b&gt; កំណត់​ទិន្នន័យ​គ្មាន​ដែន​កំណត់ &lt;/b&gt;.&lt;br/&gt; ប្រសិនបើ​​អ្នក​មិន​ប្រាកដ​​ថា​ទិន្នន័យ​អ្នក​​មិន​បាន​​កំណត់ យើង​បាន​ផ្ដល់​អនុសាសន៍​ដោយ​ស្វែងរក​ការ​តភ្ជាប់​​វ៉ាយហ្វាយ ដើម្បី​ចាប់ផ្ដើម​ទាញ​យក​ដោយ​ស្វ័យប្រវត្តិ។&lt;br/&gt; &lt;br/&gt; ព័ត៌មាន​ជំនួយ៖ អ្នក​អាច​ទាញ​យក ហើយ​យក​វចនានុក្រម​ចេញ​ដោយ​ចូល​ទៅ​កាន់ &lt;b&gt; ភាសា &amp; បញ្ចូល &lt;/b&gt; នៅ​ក្នុង &lt;b&gt; ការ​កំណត់ &lt;/b&gt; ម៉ឺនុយ​របស់​ឧបករណ៍​ចល័ត។"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"ទាញ​យក​ឥឡូវ​នេះ (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"ទាញ​យក​តាម​វ៉ាយហ្វាយ"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"វចនានុក្រម​​​ដែល​អាច​ប្រើ​បាន​​សម្រាប់ <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"ចុច​ដើម្បី​ពិនិត្យ​មើល​ឡើង​​វិញ​ និង​ទាញ​យក"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"ទាញ​យក៖ ការ​​ស្នើ <xliff:g id="LANGUAGE">%1$s</xliff:g> នឹង​បញ្ចប់​ឆាប់ៗ។"</string>
+ <string name="version_text" msgid="2715354215568469385">"កំណែ <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"បន្ថែម"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"បន្ថែម​ទៅ​វចនានុក្រម"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"ឃ្លា"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"ជម្រើស​ច្រើន"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"ជម្រើស​តិច"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"យល់​ព្រម"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"ពាក្យ៖"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"ផ្លូវកាត់​៖"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ភាសា៖"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"វាយ​បញ្ចូល​ពាក្យ​មួយ"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"ផ្លូវកាត់​ជា​ជម្រើស"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"កែ​ពាក្យ"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"កែ"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"លុប"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"អ្នក​មិន​មាន​ពាក្យ​ណាមួយ​នៅ​ក្នុង​វចនានុក្រម​អ្នក​ប្រើ​ទេ។ បន្ថែម​ពាក្យ​ដោយ​​​​ប៉ះ​ប៊ូតុង​ (+) បន្ថែម។"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"សម្រាប់​ភាសា​ទាំងអស់"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"ភាសា​ច្រើន…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"លុប"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index 42a746b60..b874d4881 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -77,7 +77,7 @@
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">10%p</fraction>
<fraction name="emoji_keyboard_row_height">50%p</fraction>
- <fraction name="emoji_keyboard_key_letter_size">60%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">54%p</fraction>
<integer name="emoji_keyboard_max_key_count">20</integer>
</resources>
diff --git a/java/res/values-lo-rLA/strings-appname.xml b/java/res/values-lo-rLA/strings-appname.xml
new file mode 100644
index 000000000..17a009483
--- /dev/null
+++ b/java/res/values-lo-rLA/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"ແປ້ນພິມ Android (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"ໂຕກວດການສະກົດຄຳໃນ Android (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"ຕັ້ງຄ່າແປ້ນພິມ Android (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Spell Checker Settings (AOSP)"</string>
+</resources>
diff --git a/java/res/values-lo-rLA/strings.xml b/java/res/values-lo-rLA/strings.xml
new file mode 100644
index 000000000..f848a8ff3
--- /dev/null
+++ b/java/res/values-lo-rLA/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ຕົວເລືອກການປ້ອນຂໍ້ມູນ"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"ເບິ່ງທີ່ຊື່ຂອງລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"ໂຕຊ່ວຍສະກົດໃຊ້ຂໍ້ມູນຈາກລາຍການຂອງລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"ສັ່ນເຕືອນເມື່ອພິມ"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"ສຽງໃນການກົດປຸ່ມ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"ໂຕອັກສອນເວລາພິມ"</string>
+ <string name="general_category" msgid="1859088467017573195">"ທົ່ວໄປ"</string>
+ <string name="correction_category" msgid="2236750915056607613">"ໂຕຊ່ວຍແປງຂໍ້ຄວາມ"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"ການພິມແບບ Gesture"</string>
+ <string name="misc_category" msgid="6894192814868233453">"ໂຕເລືອກ​ອື່ນໆ"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"ການຕັ້ງຄ່າຂັ້ນສູງ"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"ຕົວເລືອກສຳລັບຜູ່ທີ່ຊຳນານ"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"ປ່ຽນໄປໃຊ້ການປ້ອນຂໍ້ມູນແບບອື່ນ"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"ໂຕປ່ຽນພາສາເປັນທັງໂຕປ່ຽນຮູບແບບການປ້ອນຂໍ້ມູນເຊັ່ນກັນ"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"ປຸ່ມປ່ຽນພາສາ"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"ສະແດງໃນເວລາທີ່ຕົວເລືອກການປ້ອນຂໍ້ມູນຫຼາຍໂຕຖືກເປີດຢູ່"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"ສະແດງໂຕບົ່ງບອກການສະໄລ້"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"ສະແດງແນວທາງໃນຂະນະທີ່ສະໄລ້ຈາກ Shift ຫຼື ປຸ່ມເຄື່ອງໝາຍ"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"ໄລຍະເວລາການສະແດງໂຕອັກສອນ"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ບໍ່ຕ້ອໜ່ວງເວລາ"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ຄ່າເລີ່ມຕົ້ນ"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"ແນະນຳລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ໃຊ້ຊື່ຈາກລາຍຊື່ຜູ່ຕິດຕໍ່ສຳລັບການແນະນຳ ແລະ ການຊ່ວຍແກ້ຄຳ"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"ຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດ"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"ກົດທີ່ປຸ່ມຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດແລ້ວຕາມດ້ວຍການຍະຫວ່າງ"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ເຮັດໂຕພິມໃຫຍ່ອັດຕະໂນມັດ"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"ເຮັດໂຕພິມໃຫຍ່ໃຫ້ໂຕອັກສອນທຳອິດຂອງແຕ່ລໃນປະໂຫຍກ"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"ວັດຈະນານຸກົມສ່ວນໂຕ"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"ໂຕເສີມວັດຈະນານຸກົມ"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"ວັດຈະນານຸກົມຫຼັກ"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"ສະແດງການແນະນຳຄຳທີ່ຖືກຕ້ອງ"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"ສະແດງຄຳສັບທີ່ແນະນຳໃນເວລາທີ່ກຳລັງພິມ"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"ສະແດງຕະຫລອດ"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"ກົດທີ່ຄຳສັບທີ່ພິມລົງໄປເພື່ອແປງໃຫ້ມັນຖືກຕ້ອງ"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"ເຊື່ອງໄວ້ຕະຫລອດ"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"ປິດກັ້ນຄຳທີ່ບໍ່ສຸພາບ"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"ຫ້າມແນະນຳຄຳທີ່ບໍ່ສຸພາບ"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ໂຕຊ່ວຍສະກົດຄຳ"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"ການຍະຫວ່າງ ແລະ ການໃສ່ເຄື່ອງໝາຍຈະຖືກປ່ຽນແປງໃຫ້ຖືກຕ້ອງ ໃນຄຳທີ່ພິມຜິດໂດຍອັດຕະໂນມັດ"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ປິດ"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ປານກາງ"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"ສູງ"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ສູງສຸດ"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"ການແນະນຳຄຳຕໍ່ໄປ"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"ໃຊ້ຄຳທີ່ຜ່ານມາໃນການແນະນຳຄຳ"</string>
+ <string name="gesture_input" msgid="826951152254563827">"ເປີດນຳໃຊ້ການພິມແບບ Gesture"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"ໃສ່ຄຳສັບລົງໄປໂດຍການສະໄລ້ຜ່ານໂຕອັກສອນ"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"ສະແດງຫາງຂອງ Gesture"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"ມີຄຳຕົວຢ່າງລອຍຂຶ້ນມາ"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"ເບິ່ງຄຳທີ່ຖືກແນະນຳໃນເວລາທີ່ກຳລັງຊີ້"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ບັນທຶກແລ້ວ"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"ໄປ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"ຕໍ່ໄປ"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"ກ່ອນໜ້າ"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"ແລ້ວໆ"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"ສົ່ງ"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"ຄ້າງໄວ້"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"ລໍຖ້າ"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"ສຽບສາຍຫູຟັງເພື່ອຟັງລະຫັດຜ່ານ."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"ຂໍ້ຄວາມປະຈຸບັນແມ່ນ %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"ບໍ່ມີການໃສ່ຂໍ້ຄວາມ"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"ລະຫັດກະແຈ %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift ເປີດນຳໃຊ້ຢູ່ (ກົດເພື່ອປິດນຳໃຊ້)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps lock ເປີດຢູ່ (ກົດເພື່ອປິດນຳໃຊ້)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"ລຶບ"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"ສັນຍາລັກ"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"ໂຕອັກ​ສອນ"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"ໂຕເລກ"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"ການຕັ້ງຄ່າ"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"ແທັບ"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"ຍະຫວ່າງ"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"ການປ້ອນຂໍ້ມູນດ້ວຍສຽງ"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"ຮອຍຍິ້ມ"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"ກັບຄືນ"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"ຊອກຫາ"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"ຈ້ຳ"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"ສະລັບພາສາ"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"ຕໍ່ໄປ"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"ກ່ອນໜ້າ"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ເປີດນຳໃຊ້ຢູ່"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock ເປີດນຳໃຊ້ຢູ່"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift ປິດນຳໃຊ້ຢູ່"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"ໂຫມດສັນຍາລັກ"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"ໂຫມດ​ໂຕອັກ​ສອນ"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"ໂຫມດໂທລະສັບ"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"ໂຫມດສັນຍາລັກໂທລະສັບ"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"ແປ້ນ​ພິມ​ເຊື່ອງ​ໄວ້"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"ກຳລັງສະແດງແປ້ນພິມ <xliff:g id="MODE">%s</xliff:g>"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"ວັນທີ"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"ວັນ​ທີ​ແລະ​ເວ​ລາ"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"email"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"ຂໍ້ຄວາມ"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"ໂຕເລກ"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"ໂທລະສັບ"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"ຂໍ້ຄວາມ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"ເວລາ"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"ປຸ່ມປ້ອນຂໍ້ມູນດ້ວຍສຽງ"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"ແປ້ນພິມຫຼັກ"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"ໃນແປ້ນພິມສັນຍາລັກ"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"ປິດ"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"ໄມໃນແປ້ນພິມຫຼັກ"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"ໄມໃນແປ້ນພິມສັນຍາລັກ"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"ການປ້ອນຂໍ້ມູນດ້ວຍສຽງປິດນຳໃຊ້ຢູ່"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"ຕັ້ງຄ່າຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"ພາສາການປ້ອນຂໍ້ມູນ"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"ສົ່ງຄຳຕິຊົມ"</string>
+ <string name="select_language" msgid="3693815588777926848">"ພາສາການປ້ອນຂໍ້ມູນ"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"ກົດອີກຄັ້ງເພື່ອບັນທຶກ"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"ມີວັດຈະນານຸກົມ"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"ເປີດນຳໃຊ້ຄຳຕິຊົມຈາກຜູ່ໃຊ້"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"ຊ່ວຍເພີ່ມປະສິດທິພາບໂຕແກ້ໄຂການປ້ອນຂໍ້ມູນ ໂດຍການສົ່ງສະຖິຕິການນຳໃຊ້ ແລະການລາຍການຂໍ້ຜິດພາດໂດຍອັດຕະໂນມັດ"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"ສີສັນແປ້ນພິມ"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"ອັງກິດ (ສະຫະລາດຊະອານາຈັກ)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"ອັງກິດ (ສະຫະລັດຯ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"ສະເປນ (ອາເມລິກາ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"ພາສາອັງກິດ (ອັງກິດ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"ອັງກິດ (ອາເມລິກາ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ແອສປາໂຍນ (ສະ​ຫະ​ລັດ​) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (ດັ້ງເດີມ)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ບໍ່ມີພາສາ (ໂຕອັກສອນ)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ໂຕອັກສອນ (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ໂຕອັກສອນ (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"ໂຕອັກສອນ (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"ໂຕອັກສອນ (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"ໂຕອັກສອນ (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"ໂຕອັກສອນ (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"ອີໂມຈິ"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"ຮູບແບບການປ້ອນຂໍ້ມູນສ່ວນຕົວ"</string>
+ <string name="add_style" msgid="6163126614514489951">"ເພີ່ມຮູບແບບ"</string>
+ <string name="add" msgid="8299699805688017798">"ເພີ່ມ"</string>
+ <string name="remove" msgid="4486081658752944606">"ລຶບອອກ"</string>
+ <string name="save" msgid="7646738597196767214">"ບັນທຶກ"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"ພາສາ"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"ຮູບແບບ"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"ຮູບແບບການປ້ອນຂໍ້ມູນແບບສ່ວນຕົວຂອງທ່ານ ຕ້ອງຖືກເປີດນຳໃຊ້ຢູ່ກ່ອນທີ່ທ່ານຈະສາມາດໃຊ້ມັນໄດ້. ທ່ານຕ້ອງການທີ່ຈະເປີດໃຊ້ມັນດຽວນີ້ບໍ່?"</string>
+ <string name="enable" msgid="5031294444630523247">"ເປີດນຳໃຊ້"</string>
+ <string name="not_now" msgid="6172462888202790482">"ບໍ່ແມ່ນຕອນນີ້"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"ຮູບແບບການປ້ອນຂໍ້ມູນທີ່ຄືກັນມີຢູ່ແລ້ວ: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"ໂໝດການສຶກສາ Usability"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"ໄລຍະເວລາຂອງການກົດປຸ່ມ"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ໄລຍະເວລາຂອງການສັ່ນໃນການກົດປຸ່ມ"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"ລະດັບສຽງຂອງການກົດປຸ່ມ"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"ອ່ານໄຟລ໌ວັດຈະນານຸກົມພາຍນອກ"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"ບໍ່ມີໄຟລ໌ວັດຈະນານຸກົມໃນໂຟນເດີຂອງການດາວໂຫລດ"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ເລືອກໄຟລ໌ວັດຈະນານຸກົມເພື່ອຕິດຕັ້ງ"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"ຕິດຕັ້ງໄຟລ໌ນີ້ສຳລັບ <xliff:g id="LOCALE_NAME">%s</xliff:g> ແທ້ບໍ່?"</string>
+ <string name="error" msgid="8940763624668513648">"ມີຂໍ້ຜິດພາດເກີດຂຶ້ນ"</string>
+ <string name="button_default" msgid="3988017840431881491">"ຄ່າເລີ່ມຕົ້ນ"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"ຍິນ​ດີ​ຕ້ອນ​ຮັບສູ່ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ດ້ວຍການພິມແບບ Gesture"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"ເລີ່ມຕົ້ນ"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"ຂັ້ນຕອນຕໍ່ໄປ"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"ຕັ້ງຄ່າ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"ເປີດນຳໃຊ້ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"ກະລຸນາກວດເບິ່ງ \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" ໃນການຕັ້ງຄ່າພາສາ &amp; ການປ້ອນຂໍ້ມູນຂອງທ່ານ. ນີ້ຈະເປັນການອະນຸຍາດໃຫ້ມັນເຮັດວຽກໃນອຸປະກອນຂອງທ່ານ"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ຖືກເປີດນຳໃຊ້ໃນການຕັ້ງຄ່າພາສາ &amp; ການປ້ອນຂໍ້ມູນຂອງທ່ານແລ້ວ, ສະນັ້ນຂັ້ນຕອນນີ້ແມ່ນສຳເລັດໄປແລ້ວ. ໄປທີ່ຂັ້ນຕອນຕໍ່ໄປ!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"ເປີດນຳໃຊ້ໃນການຕັ້ງຄ່າ"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"ປ່ຽນເປັນ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"ຕໍ່ໄປ, ເລືອກເອົາ \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" ເປັນຮູບແບບການປ້ອນຂໍ້ມູນຂອງທ່ານ."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"ປ່ຽນຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"ຍິນດີດ້ວຍ, ທ່ານເຮັດແລ້ວໆ!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"ຕອນນີ້ທ່ານສາມາດພິມໃນແອັບຯທີ່ທ່ານມັກໄດ້ທຸກແອັບຯດ້ວຍ <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"ປັບຄ່າພາສາເພີ່ມເຕີມ"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"ສຳເລັດແລ້ວ"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"ສະແດງໄອຄອນຂອງແອັບຯ"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"ສະແດງໄອຄອນຂອງແອັບຯໃນ Launcher"</string>
+ <string name="app_name" msgid="6320102637491234792">"ຜູ່​ສະ​ຫນອງ​ວັດຈະ​ນາ​ນຸ​ກົມ"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"ຜູ່​ສະ​ຫນອງ​ວັດຈະ​ນາ​ນຸ​ກົມ"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"ບໍລິການວັດຈະນານຸກົມ"</string>
+ <string name="download_description" msgid="6014835283119198591">"ຂໍ້ມູນການອັບເດດວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ໂຕເສີມວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"ມີວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ການຕັ້ງຄ່າສຳລັບວັດຈະນານຸກົມ"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"ວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"ວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"ມີວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"ກຳລັງດາວໂຫລດ"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"ຕິດຕັ້ງແລ້ວ"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"ຕິດຕັ້ງແລ້ວ, ປິດການນຳໃຊ້ແລ້ວ"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"ມີປັນຫາໃນການເຊື່ອມຕໍ່ກັບບໍລິການວັດຈະນານຸກົມ"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"ບໍ່ມີວັດຈະນານຸກົມ"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"ດຶງຂໍ້ມູນໃຫມ່"</string>
+ <string name="last_update" msgid="730467549913588780">"ອັບເດດຫຼ້າສຸດ"</string>
+ <string name="message_updating" msgid="4457761393932375219">"ກຳລັງກວດການອັບເດດ"</string>
+ <string name="message_loading" msgid="8689096636874758814">"ກຳລັງໂຫລດ..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"ວັດຈະນານຸກົມຫຼັກ"</string>
+ <string name="cancel" msgid="6830980399865683324">"ຍົກເລີກ"</string>
+ <string name="install_dict" msgid="180852772562189365">"ຕິດຕັ້ງ"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"ຍົກເລີກ"</string>
+ <string name="delete_dict" msgid="756853268088330054">"ລຶບ"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"ພາສາທີ່ທ່ານເລືອກໃຊ້ໃນອຸປະກອນຂອງທ່ານນັ້ນ ມີວັດຈະນານຸກົມໃຫ້ໃຊ້ພ້ອມ.&lt;br/&gt; ພວກເຮົາແນະນຳໃຫ້ &lt;b&gt;ດາວໂຫລດ&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> ວັດຈະນານຸກົມດັ່ງກ່າວ ເພື່ອເພີ່ມປະສົບການໃນການພິມຂອງທ່ານ.&lt;br/&gt; &lt;br/&gt; ການດາວໂຫລດອາດຈະໃຊ້ເວລາພຽງໜຶ່ງເຖິງສອງນາທີ ໂດຍການໃຊ້ 3G. ທ່ານອາດຈະເສຍຄ່າບໍລິການສຳລັບອິນເຕີເນັດ ຫາກທ່ານບໍ່ມີ &lt;b&gt;ການນຳໃຊ້ອິນເຕີເນັດແບບບໍ່ຈຳກັດ&lt;/b&gt;.&lt;br/&gt; ຫາກທ່ານບໍ່ແນ່ໃຈວ່າຮູບແບບການໃຊ້ໃດທີ່ທ່ານມີຢູ່ ພວກເຮົາແນະນຳໃຫ້ຊອກຫາການເຊື່ອມຕໍ່ Wi-Fi ເພື່ອດາວໂຫລດມັນໂດຍອັດຕະໂນມັດ.&lt;br/&gt; &lt;br/&gt; ເຄັດລັບ: ທ່ານສາມາດດາວໂຫລດ ແລະ ລຶບວັດຈະນານຸກົມໄດ້ທີ່ &lt;b&gt;ພາສາ &amp; ການປ້ອນຂໍ້ມູນ&lt;/b&gt; ຢູ່ໃນເມນູ &lt;b&gt;ການຕັ້ງຄ່າ&lt;/b&gt; ຂອງອຸປະກອນພົກພາຂອງທ່ານ."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"ດາວໂຫລດດຽວນີ້ (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"ດາວ​ໂຫລດຜ່ານ Wi-Fi"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"ວັດຈະນານຸກົມສາມາດໃຊ້ໄດ້ກັບ <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"ກົດທີ່ກວດຄືນ ແລະ ດາວໂຫລດ"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"ກຳລັງດາວໂຫລດ: ການແນະນຳສຳລັບ <xliff:g id="LANGUAGE">%1$s</xliff:g> ແລະມັນຈະພ້ອມນຳໃຊ້ໄວໆນີ້"</string>
+ <string name="version_text" msgid="2715354215568469385">"ເວີຊັນ <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"ເພີ່ມ"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"ເພີ່ມໄປທີ່ວັດຈະນານຸກົມ"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"ປະໂຫຍກ"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"ຕົວເລືອກໜ້ອຍລົງ"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"ຕົກລົງ"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"ຄຳສັບ:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"ທາງລັດ:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ພາສາ:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"ພິມ​ຄໍາ​ສັບ​ໃດ​ນຶ່ງ"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"ໂຕເລືອກທາງລັດ"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"ແກ້ໄຂຄຳສັບ"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"ແກ້ໄຂ"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"ລຶບ"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"ທ່ານບໍ່ມີຄຳສັບໃດໆໃນວັດຈະນານຸກົມຜູ່ໃຊ້ເທື່ອ. ເພີ່ມຄຳສັບໄດ້ໂດຍການສຳພັດທີ່ປຸ່ມ ເພີ່ມ (+)."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"ສໍາ​ລັບ​ທຸກໆ​ພາ​ສາ"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"ພາສາອື່ນໆ..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"ລຶບ"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-lo/strings-appname.xml b/java/res/values-lo/strings-appname.xml
new file mode 100644
index 000000000..17a009483
--- /dev/null
+++ b/java/res/values-lo/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"ແປ້ນພິມ Android (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"ໂຕກວດການສະກົດຄຳໃນ Android (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"ຕັ້ງຄ່າແປ້ນພິມ Android (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Spell Checker Settings (AOSP)"</string>
+</resources>
diff --git a/java/res/values-lo/strings.xml b/java/res/values-lo/strings.xml
new file mode 100644
index 000000000..cc15a4226
--- /dev/null
+++ b/java/res/values-lo/strings.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ຕົວເລືອກການປ້ອນຂໍ້ມູນ"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"ເບິ່ງທີ່ຊື່ຂອງລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"ໂຕຊ່ວຍສະກົດໃຊ້ຂໍ້ມູນຈາກລາຍການຂອງລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"ການສັ່ນໃນການພິມ"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"ສຽງໃນການກົດປຸ່ມ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"ໂຕອັກສອນເວລາພິມ"</string>
+ <string name="general_category" msgid="1859088467017573195">"ທົ່ວໄປ"</string>
+ <string name="correction_category" msgid="2236750915056607613">"ໂຕຊ່ວຍແປງຂໍ້ຄວາມ"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"ການພິມແບບ Gesture"</string>
+ <string name="misc_category" msgid="6894192814868233453">"ໂຕເລືອກ​ອື່ນໆ"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"ການຕັ້ງຄ່າຂັ້ນສູງ"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"ຕົວເລືອກສຳລັບຜູ່ທີ່ຊຳນານ"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"ປ່ຽນໄປໃຊ້ການປ້ອນຂໍ້ມູນແບບອື່ນ"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"ໂຕປ່ຽນພາສາເປັນທັງໂຕປ່ຽນຮູບແບບການປ້ອນຂໍ້ມູນເຊັ່ນກັນ"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"ປຸ່ມປ່ຽນພາສາ"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"ສະແດງໃນເວລາທີ່ຕົວເລືອກການປ້ອນຂໍ້ມູນຫຼາຍໂຕຖືກເປີດຢູ່"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"ສະແດງໂຕບົ່ງບອກການສະໄລ້"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"ສະແດງແນວທາງໃນຂະນະທີ່ສະໄລ້ຈາກ Shift ຫຼື ປຸ່ມເຄື່ອງໝາຍ"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"ໄລຍະເວລາການສະແດງໂຕອັກສອນ"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ບໍ່ຕ້ອໜ່ວງເວລາ"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ຄ່າເລີ່ມຕົ້ນ"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"ແນະນຳລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ໃຊ້ຊື່ຈາກລາຍຊື່ຜູ່ຕິດຕໍ່ສຳລັບການແນະນຳ ແລະ ການຊ່ວຍແກ້ຄຳ"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"ຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດ"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"ກົດທີ່ປຸ່ມຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດແລ້ວຕາມດ້ວຍການຍະຫວ່າງ"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ເຮັດໂຕພິມໃຫຍ່ອັດຕະໂນມັດ"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"ເຮັດໂຕພິມໃຫຍ່ໃຫ້ໂຕອັກສອນທຳອິດຂອງແຕ່ລະຄຳໃນປະໂຫຍກ"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"ວັດຈະນານຸກົມສ່ວນໂຕ"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"ໂຕເສີມວັດຈະນານຸກົມ"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"ວັດຈະນານຸກົມຫຼັກ"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"ສະແດງການແນະນຳຄຳທີ່ຖືກຕ້ອງ"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"ສະແດງຄຳສັບທີ່ແນະນຳໃນເວລາທີ່ກຳລັງພິມ"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"ສະແດງຕະຫລອດ"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"ສະແດງໃນໂຫມດແນວຕັ້ງ"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"ເຊື່ອງໄວ້ຕະຫລອດ"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"ປິດກັ້ນຄຳທີ່ບໍ່ສຸພາບ"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"ຫ້າມແນະນຳຄຳທີ່ບໍ່ສຸພາບ"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ໂຕຊ່ວຍສະກົດຄຳ"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"ການຍະຫວ່າງ ແລະ ການໃສ່ເຄື່ອງໝາຍຈະຖືກປ່ຽນແປງໃຫ້ຖືກຕ້ອງ ໃນຄຳທີ່ພິມຜິດໂດຍອັດຕະໂນມັດ"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ປິດ"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ປານກາງ"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"ສູງ"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ສູງສຸດ"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"ການແນະນຳຄຳຕໍ່ໄປ"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"ໃຊ້ຄຳທີ່ຜ່ານມາໃນການແນະນຳຄຳ"</string>
+ <string name="gesture_input" msgid="826951152254563827">"ເປີດນຳໃຊ້ການພິມແບບ Gesture"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"ໃສ່ຄຳສັບລົງໄປໂດຍການສະໄລ້ຜ່ານໂຕອັກສອນ"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"ສະແດງຫາງຂອງ Gesture"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"ມີຄຳຕົວຢ່າງລອຍຂຶ້ນມາ"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"ເບິ່ງຄຳທີ່ຖືກແນະນຳໃນເວລາທີ່ກຳລັງຊີ້"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ບັນທຶກແລ້ວ"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"ໄປ"</string>
+ <string name="label_next_key" msgid="362972844525672568">"ຕໍ່ໄປ"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"ກ່ອນໜ້າ"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"ແລ້ວໆ"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"ສົ່ງ"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"ຄ້າງໄວ້"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"ລໍຖ້າ"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"ສຽບສາຍຫູຟັງເພື່ອຟັງລະຫັດຜ່ານ."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"ຂໍ້ຄວາມປະຈຸບັນແມ່ນ %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"ບໍ່ມີການໃສ່ຂໍ້ຄວາມ"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"ລະຫັດກະແຈ %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift ເປີດນຳໃຊ້ຢູ່ (ກົດເພື່ອປິດນຳໃຊ້)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps lock ເປີດຢູ່ (ກົດເພື່ອປິດນຳໃຊ້)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"ລຶບ"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"ສັນ​ຍາ​ລັກ"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"ໂຕອັກ​ສອນ"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"ໂຕເລກ"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"ການຕັ້ງຄ່າ"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"ແທັບ"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"ຍະຫວ່າງ"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"ການປ້ອນຂໍ້ມູນດ້ວຍສຽງ"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"ຮອຍຍິ້ມ"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"ກັບຄືນ"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"ຊອກຫາ"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"ຈ້ຳ"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"ສະລັບພາສາ"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"ຕໍ່ໄປ"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"ກ່ອນໜ້າ"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ເປີດນຳໃຊ້ຢູ່"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock ເປີດນຳໃຊ້ຢູ່"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift ປິດນຳໃຊ້ຢູ່"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"ໂຫມດສັນຍາລັກ"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"ໂຫມດ​ໂຕອັກ​ສອນ"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"ໂຫມດໂທລະສັບ"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"ໂຫມດສັນຍາລັກໂທລະສັບ"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"ແປ້ນ​ພິມ​ເຊື່ອງ​ໄວ້"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"ກຳລັງສະແດງແປ້ນພິມ <xliff:g id="MODE">%s</xliff:g>"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"ວັນທີ"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"ວັນ​ທີ​ແລະ​ເວ​ລາ"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"ອີເມວ"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"ຂໍ້ຄວາມ"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"ໂຕເລກ"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"ໂທລະສັບ"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"ຂໍ້ຄວາມ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"ເວລາ"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"ປຸ່ມປ້ອນຂໍ້ມູນດ້ວຍສຽງ"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"ແປ້ນພິມຫຼັກ"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"ໃນແປ້ນພິມສັນຍາລັກ"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"ປິດ"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"ໄມໃນແປ້ນພິມຫຼັກ"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"ໄມໃນແປ້ນພິມສັນຍາລັກ"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"ການປ້ອນຂໍ້ມູນດ້ວຍສຽງປິດນຳໃຊ້ຢູ່"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"ຕັ້ງຄ່າຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"ພາສາການປ້ອນຂໍ້ມູນ"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"ສົ່ງຄຳຕິຊົມ"</string>
+ <string name="select_language" msgid="3693815588777926848">"ພາສາການປ້ອນຂໍ້ມູນ"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"ກົດອີກຄັ້ງເພື່ອບັນທຶກ"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"ມີວັດຈະນານຸກົມ"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"ເປີດນຳໃຊ້ຄຳຕິຊົມຈາກຜູ່ໃຊ້"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"ຊ່ວຍເພີ່ມປະສິດທິພາບໂຕແກ້ໄຂການປ້ອນຂໍ້ມູນ ໂດຍການສົ່ງສະຖິຕິການນຳໃຊ້ ແລະການລາຍການຂໍ້ຜິດພາດໂດຍອັດຕະໂນມັດ"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"ສີສັນແປ້ນພິມ"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"ອັງກິດ (UK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"ອັງກິດ (ອາເມລິກາ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"ສະເປນ (ອາເມລິກາ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"ພາສາອັງກິດ (ອັງກິດ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"ອັງກິດ (ອາເມລິກາ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ແອສປາໂຍນ (ສະ​ຫະ​ລັດ​) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ບໍ່ມີພາສາ (ໂຕອັກສອນ)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ໂຕອັກສອນ (QWERTY​)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ໂຕອັກສອນ (QWERTZ​)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"ໂຕອັກສອນ (AZERTY​)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"ໂຕອັກສອນ (Dvorak​)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"ໂຕອັກສອນ (Colemak​)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"ໂຕອັກສອນ (PC)"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"ຮູບແບບການປ້ອນຂໍ້ມູນສ່ວນຕົວ"</string>
+ <string name="add_style" msgid="6163126614514489951">"ເພີ່ມຮູບແບບ"</string>
+ <string name="add" msgid="8299699805688017798">"ເພີ່ມ"</string>
+ <string name="remove" msgid="4486081658752944606">"ລຶບອອກ"</string>
+ <string name="save" msgid="7646738597196767214">"ບັນທຶກ"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"ພາສາ"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"ຮູບແບບ"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"ຮູບແບບການປ້ອນຂໍ້ມູນແບບສ່ວນຕົວຂອງທ່ານ ຕ້ອງຖືກເປີດນຳໃຊ້ຢູ່ກ່ອນທີ່ທ່ານຈະສາມາດໃຊ້ມັນໄດ້. ທ່ານຕ້ອງການທີ່ຈະເປີດໃຊ້ມັນດຽວນີ້ບໍ່?"</string>
+ <string name="enable" msgid="5031294444630523247">"ເປີດນຳໃຊ້"</string>
+ <string name="not_now" msgid="6172462888202790482">"ບໍ່ແມ່ນຕອນນີ້"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"ຮູບແບບການປ້ອນຂໍ້ມູນທີ່ຄືກັນມີຢູ່ແລ້ວ: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"ໂໝດການສຶກສາ Usability"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"ໄລຍະເວລາຂອງການກົດປຸ່ມ"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ໄລຍະເວລາຂອງການສັ່ນໃນການກົດປຸ່ມ"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"ລະດັບສຽງຂອງການກົດປຸ່ມ"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"ອ່ານໄຟລ໌ວັດຈະນານຸກົມພາຍນອກ"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"ບໍ່ມີໄຟລ໌ວັດຈະນານຸກົມໃນໂຟນເດີຂອງການດາວໂຫລດ"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ເລືອກໄຟລ໌ວັດຈະນານຸກົມເພື່ອຕິດຕັ້ງ"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"ຕິດຕັ້ງໄຟລ໌ນີ້ສຳລັບ <xliff:g id="LOCALE_NAME">%s</xliff:g> ແທ້ບໍ່?"</string>
+ <string name="error" msgid="8940763624668513648">"ມີຂໍ້ຜິດພາດເກີດຂຶ້ນ"</string>
+ <string name="button_default" msgid="3988017840431881491">"ຄ່າເລີ່ມຕົ້ນ"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"ຍິນ​ດີ​ຕ້ອນ​ຮັບສູ່ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ດ້ວຍການພິມແບບ Gesture"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"ເລີ່ມກັນເລີຍ!"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"ຂັ້ນຕອນຕໍ່ໄປ"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"ຕັ້ງຄ່າ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"ເປີດນຳໃຊ້ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"ກະລຸນາກວດເບິ່ງ \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" ໃນການຕັ້ງຄ່າພາສາ &amp; ການປ້ອນຂໍ້ມູນຂອງທ່ານ. ນີ້ຈະເປັນການອະນຸຍາດໃຫ້ມັນເຮັດວຽກໃນອຸປະກອນຂອງທ່ານ"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ຖືກເປີດນຳໃຊ້ໃນການຕັ້ງຄ່າພາສາ &amp; ການປ້ອນຂໍ້ມູນຂອງທ່ານແລ້ວ, ສະນັ້ນຂັ້ນຕອນນີ້ແມ່ນສຳເລັດໄປແລ້ວ. ໄປທີ່ຂັ້ນຕອນຕໍ່ໄປ!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"ເປີດນຳໃຊ້ໃນການຕັ້ງຄ່າ"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"ປ່ຽນເປັນ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"ຕໍ່ໄປ, ເລືອກເອົາ \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" ເປັນຮູບແບບການປ້ອນຂໍ້ມູນຂອງທ່ານ."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"ປ່ຽນຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"ຍິນດີດ້ວຍ, ທ່ານເຮັດແລ້ວໆ!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"ຕອນນີ້ທ່ານສາມາດພິມໃນແອັບຯທີ່ທ່ານມັກໄດ້ທຸກແອັບຯດ້ວຍ <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"ປັບຄ່າພາສາເພີ່ມເຕີມ"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"ສຳເລັດແລ້ວ"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"ສະແດງໄອຄອນຂອງແອັບຯ"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"ສະແດງໄອຄອນຂອງແອັບຯໃນ Launcher"</string>
+ <string name="app_name" msgid="6320102637491234792">"ຜູ່​ສະ​ຫນອງ​ວັດຈະ​ນາ​ນຸ​ກົມ"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"ຜູ່​ສະ​ຫນອງ​ວັດຈະ​ນາ​ນຸ​ກົມ"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"ບໍລິການວັດຈະນານຸກົມ"</string>
+ <string name="download_description" msgid="6014835283119198591">"ຂໍ້ມູນການອັບເດດວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ໂຕເສີມວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"ມີວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ການຕັ້ງຄ່າສຳລັບວັດຈະນານຸກົມ"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"ວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"ວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"ມີວັດຈະນານຸກົມ"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"ກຳລັງດາວໂຫລດ"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"ຕິດຕັ້ງແລ້ວ"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"ຕິດຕັ້ງແລ້ວ, ປິດການນຳໃຊ້ແລ້ວ"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"ມີປັນຫາໃນການເຊື່ອມຕໍ່ກັບບໍລິການວັດຈະນານຸກົມ"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"ບໍ່ມີວັດຈະນານຸກົມ"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"ດຶງຂໍ້ມູນໃຫມ່"</string>
+ <string name="last_update" msgid="730467549913588780">"ອັບເດດຫຼ້າສຸດ"</string>
+ <string name="message_updating" msgid="4457761393932375219">"ກຳລັງກວດການອັບເດດ"</string>
+ <string name="message_loading" msgid="8689096636874758814">"ກຳລັງໂຫລດ..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"ວັດຈະນານຸກົມຫຼັກ"</string>
+ <string name="cancel" msgid="6830980399865683324">"ຍົກເລີກ"</string>
+ <string name="install_dict" msgid="180852772562189365">"ຕິດຕັ້ງ"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"ຍົກເລີກ"</string>
+ <string name="delete_dict" msgid="756853268088330054">"ລຶບ"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"ພາສາທີ່ທ່ານເລືອກໃຊ້ໃນອຸປະກອນຂອງທ່ານນັ້ນ ມີວັດຈະນານຸກົມໃຫ້ໃຊ້ພ້ອມ.&lt;br/&gt; ພວກເຮົາແນະນຳໃຫ້ &lt;b&gt;ດາວໂຫລດ&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> ວັດຈະນານຸກົມດັ່ງກ່າວ ເພື່ອເພີ່ມປະສົບການໃນການພິມຂອງທ່ານ.&lt;br/&gt; &lt;br/&gt; ການດາວໂຫລດອາດຈະໃຊ້ເວລາພຽງໜຶ່ງເຖິງສອງນາທີ ໂດຍການໃຊ້ 3G. ທ່ານອາດຈະເສຍຄ່າບໍລິການສຳລັບອິນເຕີເນັດ ຫາກທ່ານບໍ່ມີ &lt;b&gt;ການນຳໃຊ້ອິນເຕີເນັດແບບບໍ່ຈຳກັດ&lt;/b&gt;.&lt;br/&gt; ຫາກທ່ານບໍ່ແນ່ໃຈວ່າຮູບແບບການໃຊ້ໃດທີ່ທ່ານມີຢູ່ ພວກເຮົາແນະນຳໃຫ້ຊອກຫາການເຊື່ອມຕໍ່ Wi-Fi ເພື່ອດາວໂຫລດມັນໂດຍອັດຕະໂນມັດ.&lt;br/&gt; &lt;br/&gt; ເຄັດລັບ: ທ່ານສາມາດດາວໂຫລດ ແລະ ລຶບວັດຈະນານຸກົມໄດ້ທີ່ &lt;b&gt;ພາສາ &amp; ການປ້ອນຂໍ້ມູນ&lt;/b&gt; ຢູ່ໃນເມນູ &lt;b&gt;ການຕັ້ງຄ່າ&lt;/b&gt; ຂອງອຸປະກອນພົກພາຂອງທ່ານ."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"ດາວໂຫລດດຽວນີ້ (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"ດາວ​ໂຫລດຜ່ານ Wi-Fi"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"ວັດຈະນານຸກົມສາມາດໃຊ້ໄດ້ກັບ <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"ກົດທີ່ກວດຄືນ ແລະ ດາວໂຫລດ"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"ກຳລັງດາວໂຫລດ: ການແນະນຳສຳລັບ <xliff:g id="LANGUAGE">%1$s</xliff:g> ແລະມັນຈະພ້ອມນຳໃຊ້ໄວໆນີ້"</string>
+ <string name="version_text" msgid="2715354215568469385">"ເວີຊັນ <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"ເພີ່ມ"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"ເພີ່ມໄປທີ່ວັດຈະນານຸກົມ"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"ປະໂຫຍກ"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"ຕົວເລືອກໜ້ອຍລົງ"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"ຕົກລົງ"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"ຄຳສັບ:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"ທາງລັດ:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ພາສາ:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"ພິມ​ຄໍາ​ສັບ​ໃດ​ນຶ່ງ"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"ໂຕເລືອກທາງລັດ"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"ແກ້ໄຂຄຳ"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"ແກ້ໄຂ"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"ລຶບ"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"ທ່ານບໍ່ມີຄຳສັບໃດໆໃນວັດຈະນານຸກົມຜູ່ໃຊ້ເທື່ອ. ເພີ່ມຄຳສັບໄດ້ໂດຍການສຳພັດທີ່ປຸ່ມ ເພີ່ມ (+)."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"ສໍາ​ລັບ​ທຸກໆ​ພາ​ສາ"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"ພາສາອື່ນໆ..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"ລຶບ"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-mn-rMN/strings-appname.xml b/java/res/values-mn-rMN/strings-appname.xml
new file mode 100644
index 000000000..6c27e3d34
--- /dev/null
+++ b/java/res/values-mn-rMN/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Андройд Гар (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Андройд Алдаа Шалгагч (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Андройд Гарын Тохиргоо (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Андройд Алдаа Шалгагчийн Тохиргоо (AOSP)"</string>
+</resources>
diff --git a/java/res/values-ms-rMY/strings-appname.xml b/java/res/values-ms-rMY/strings-appname.xml
new file mode 100644
index 000000000..76d1d294c
--- /dev/null
+++ b/java/res/values-ms-rMY/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Papan Kekunci Android (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Penyemak Ejaan Android (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Tetapan Papan Kekunci Android (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Tetapan Penyemak Ejaan Android (AOSP)"</string>
+</resources>
diff --git a/java/res/values-ne-rNP/strings-appname.xml b/java/res/values-ne-rNP/strings-appname.xml
new file mode 100644
index 000000000..5ad5eae66
--- /dev/null
+++ b/java/res/values-ne-rNP/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Keyboard (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android Spell Checker (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android Keyboard Settings (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Spell Checker Settings (AOSP)"</string>
+</resources>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
new file mode 100644
index 000000000..5aa676a10
--- /dev/null
+++ b/java/res/values-ne-rNP/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"इनपुट विकल्पहरू"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"लग निर्देशनहरू शोध गर्नुहोस्"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"सम्पर्क नामहरू हेर्नुहोस्"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"तपाईँको सम्पर्क सूचीबाट हिज्जे परीक्षकले प्रविष्टिहरूको प्रयोग गर्छ"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"कुञ्जी थिच्दा भाइब्रेट"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"कुञ्जी थिच्दा आवाज"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"कुञ्जी दबाउँदा पपअप"</string>
+ <string name="general_category" msgid="1859088467017573195">"सामान्य"</string>
+ <string name="correction_category" msgid="2236750915056607613">"पाठ सुधार"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"इशारा टाइप गर्ने"</string>
+ <string name="misc_category" msgid="6894192814868233453">"अन्य विकल्पहरू"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"जटिल सेटिङहरू"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"विज्ञहरूका लागि विकल्पहरू"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"अन्य इनपुट विधिमा स्विच गर्नुहोस्"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"भाषा स्विच किले अन्य इनपुट विधि पनि समेट्छ"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"भाषा स्विच कुञ्जी"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"जब बहुसङ्ख्यक इनपुट भाषाहरू सक्षम भएपछि देखाउनुहोस्"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"स्लाइड सूचक देखाउनुहोस्"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"सिफ्ट वा प्रतिक कुञ्जीमा स्लाइड गर्ने बेला दृश्य सङ्केत देखाउनुहोस्"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"कि पपअप खारेजी ढिलाइ"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ढिलाइ छैन"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"पूर्वनिर्धारित"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> मिलिसेकेन्ड"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"प्रणाली पूर्वनिर्धारित"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"सम्पर्क नामहरू सुझाव गर्नुहोस्"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव र सुधारका लागि सम्पर्कबाट नामहरू प्रयोग गर्नुहोस्"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"डबल-स्पेस पूर्णविराम"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबारमा डबल ट्याप गर्नाले पूर्णविरामपछि स्पेस राख्दछ"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"स्वतः पूँजिकरण"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"प्रत्येक वाक्यको पहिलो शब्द क्यापिटल गर्नुहोस्"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"व्यक्तिगत शब्दकोश"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"एड-अन शब्दकोश"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"मुख्य शब्दकोश"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"सुधार सुझावहरू देखाउने"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"टाइप गर्ने बेलामा सुझाव शब्दहरू देखाउनुहोस्"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"सधैँ देखाउने"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"चित्र मोडमा देखाउनुहोस्"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"सधैँ लुकाउने"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"आपत्तिजनक शब्दहरूलाई रोक्नुहोस्"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"सम्भावित आपत्तिजनक शब्दहरू सुझाव नगर्नुहोस्"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"स्वतः सुधार"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"गल्ती टाइप भएका शब्दहरूलाई स्पेसबार र पङ्चुएसनले स्वचालित रूपमा सच्याउँछन्।"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"बन्द"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"सामान्य"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"आक्रामक"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ज्यादै आक्रामक"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"अर्को शब्द सुझाव"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"सुझावहरू निर्माण गर्न अघिल्लो शब्द प्रयोग गर्नुहोस्"</string>
+ <string name="gesture_input" msgid="826951152254563827">"इशारा टाइप गर्ने सक्षम पार्नुहोस्"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"अक्षर स्लाइड गरी शब्द इनपुट गर्नुहोस्"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"इशारा ट्रेल देखाउनुहोस्"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"गतिशील फ्लोटिङ पूर्वावलोकन"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"इशारा गर्दा सुझाव दिइएको शब्द हेर्नुहोस्"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : बचत गरियो"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"जानुहोस्"</string>
+ <string name="label_next_key" msgid="362972844525672568">"अर्को"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"अघिल्लो"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"भयो"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"पठाउनुहोस्"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"रोक्नुहोस्"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"प्रतीक्षा गर्ने"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"हेडसेट प्लग इन गर्नुहोस्"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"वर्तमान पाठ %s हो"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"कुनै पाठ प्रविष्टि गरिएको छैन"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"कुञ्जी कोड %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"सिफ्ट"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"सिप्ट सक्रिय (असक्षम पार्न ट्याप गर्नुहोस्)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"क्याप्स लक सक्रिय छ (असक्षम पार्न ट्याप गर्नुहोस्)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"मेट्ने"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"प्रतिकहरू"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"अक्षरहरू"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"नम्बरहरू"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"सेटिङहरू"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"ट्याब"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"स्पेस"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"आवाज इनपुट"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"मुस्कुराएको अनुहार"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"फर्कनुहोस्"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"खोज्नुहोस्"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"डट"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"भाषा स्विच गर्नुहोस्"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"अर्को"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"अघिल्लो"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"सिफ्ट सक्षम पारिएको छ"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"क्याप्स लक सक्षम पारिएको छ"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"सिफ्ट असक्षम पारिएको छ"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"प्रतिक मोड"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"अक्षर मोड"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"फोन मोड"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"फोन प्रतिक मोड"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"किबोर्ड लुकाइएको छ"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> किबोर्ड देखाइँदै"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"मिति"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"मिति र समय"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"इमेल"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"सन्देश गर्दै"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"सङ्ख्या"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"फोन"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"पाठ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"समय"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"आवाज इनपुट कुञ्जी"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"मुख्य किबोर्डमा"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"प्रतिकहरू किबोर्डमा"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"बन्द"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"मुख्य किबोर्डमा माइक"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"प्रतिकहरू किबोर्डमा माइक"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"आवाज इनपुट असक्षम पारियो"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"इनपुट विधिहरू कन्फिगर गर्नुहोस्"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"इनपुट भाषाहरू"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"प्रतिक्रिया पठाउनुहोस्"</string>
+ <string name="select_language" msgid="3693815588777926848">"इनपुट भाषाहरू"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"बचत गर्न पुनः छुनुहोस्"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"उपलब्ध शब्दकोश"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"प्रयोगकर्ता प्रतिक्रिया सक्षम पार्नुहोस्"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"स्वचालित रूपमा प्रयोग तथ्याङ्कहरू र क्यास रिपोर्टहरू पठाएर यस इनपुट विधि सम्पादकलाई सुधार्न सहयोग गर्नुहोस्।"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"किबोर्ड थिम"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेजी (युके)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेजी (युएस्)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"स्पेनिस (युएस्)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"अंग्रेजी (युके) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"अंग्रेजी (युएस्) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"स्पेनेली (युएस्) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (परम्परागत)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"कुनै भाषा होइन (वर्णमाला)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णमाला (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णमाला (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"वर्णमाला (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"वर्णमाला (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"वर्णमाला (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"वर्णमाला (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"इमोजी"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"अनुकूलन इनपुट शैली"</string>
+ <string name="add_style" msgid="6163126614514489951">"शैली थप्नुहोस्"</string>
+ <string name="add" msgid="8299699805688017798">"थप्नुहोस्"</string>
+ <string name="remove" msgid="4486081658752944606">"हटाउनुहोस्"</string>
+ <string name="save" msgid="7646738597196767214">"बचत गर्नुहोस्"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"भाषा"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"लेआउट"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"तपाईँले प्रयोग गर्न सुरु गर्न अघि तपाईँको अनुकूलन इनपुट शैली सक्षम पारिनु पर्छ। के तपाईँ यसलाई अहिले सक्षम पार्न चाहनु हुन्छ?"</string>
+ <string name="enable" msgid="5031294444630523247">"सक्षम पार्नुहोस्"</string>
+ <string name="not_now" msgid="6172462888202790482">"अहिले होइन"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"यस्तो इनपुट शैली पहिले नै अवस्थित छ: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"प्रयोग अध्ययन मोड"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"कुञ्जी लामो थिचाइ ढिलाइ"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"कुञ्जी थिचाइ भाइब्रेसन अवधि"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"कुञ्जी थिचाइ आवाज भोल्युम"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"बाह्य शब्दकोश फाइल पढ्नुहोस्"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"डाउनलोड फोल्डरमा कुनै शब्दकोश फाइलहरू छैनन्।"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"स्थापना गर्न कुनै शब्दकोश फाइल चयन गर्नुहोस्"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"<xliff:g id="LOCALE_NAME">%s</xliff:g>का लागि साँच्चिकै यो फाइल स्थापना गर्ने हो?"</string>
+ <string name="error" msgid="8940763624668513648">"कुनै त्रुटि भयो"</string>
+ <string name="button_default" msgid="3988017840431881491">"पूर्वनिर्धारित"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"तपाईँलाई स्वागत छ<xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"इशारा टाइप गर्नेसँग"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"सुरु गरौं"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"अर्को चरण"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"स्थापना गर्दै <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"सक्षम पार्नुहोस् <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"कृपया जाँच गर्नुहोस् \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" तपाईँको भाषा र इनपुट सेटिङमा। यसले तपाईँलाई तपाईँको उपकरणमा सञ्चालन गर्न आधिकारिकता प्रदान गर्छ।"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> पहिले नै तपाईँको भाषा र इनपुट सेटिङमा सक्षम पारिएको छ, त्यसैले यो कदम सकिसकिएको छ। अर्कोमा जानुहोस्!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"सेटिङहरूमा सक्षम पार्नुहोस्"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>मा स्विच गर्नुहोस्"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"त्यसपछि, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" लाई तपाईँको सक्रिय पाठ इनपुट विधिका रूपमा चयन गर्नुहोस्।"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"इनपुट विधि स्विच गर्नुहोस्"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"बधाई छ, तपाईँले सेट पुरा गर्नुभयो!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"अब तपाईँ <xliff:g id="APPLICATION_NAME">%s</xliff:g>का साथ तपाईँका सम्पूर्ण मनपर्ने अनुप्रयोगहरू टाइप गर्न सक्नुहुन्छ।"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"थप भाषाहरू कन्फिगर गर्नुहोस्"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"समाप्त भयो"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"अनुप्रयोग आइकन देखाउनुहोस्"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"लन्चरमा अनुप्रयोग आइकन देखाउनुहोस्"</string>
+ <string name="app_name" msgid="6320102637491234792">"शब्दकोश प्रदायक"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"शब्दकोश प्रदायक"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"शब्दकोश सेवा"</string>
+ <string name="download_description" msgid="6014835283119198591">"शब्दकोश अद्यावधिक जानकारी"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"एड-अन शब्दकोश"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"उपलब्ध शब्दकोश"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"शब्दकोशहरूका लागि सेटिङहरू"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"प्रयोगकर्ता शब्दकोशहरू"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"प्रयोगकर्ता शब्दकोश"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"उपलब्ध शब्दकोश"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"हाल डाउनलोड गर्दै"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"स्थापित"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"स्थापित, असक्षम पारिएको"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"शब्दकोश सेवासँग जोड्न समस्या"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"शब्दकोशहरू उपलब्ध छैनन्"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"पुनः ताजा गर्नुहोस्"</string>
+ <string name="last_update" msgid="730467549913588780">"पछिल्लो अद्यावधिक"</string>
+ <string name="message_updating" msgid="4457761393932375219">"अद्यावधिकको लागि जाँच गर्दै"</string>
+ <string name="message_loading" msgid="8689096636874758814">"लोड हुँदै..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"मुख्य शब्दकोश"</string>
+ <string name="cancel" msgid="6830980399865683324">"रद्द गर्नुहोस्"</string>
+ <string name="install_dict" msgid="180852772562189365">"स्थापना गर्नुहोस्"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"रद्द गर्नुहोस्"</string>
+ <string name="delete_dict" msgid="756853268088330054">"मेट्नुहोस्"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"तपाईँको मोबाइल उपकरणमा चयन गरिएको भाषामा शब्दकोश उपलब्ध छ। हामी सिफारिश गर्छौं <xliff:g id="LANGUAGE">%1$s</xliff:g> शब्दकोश डाउनलोड गर्नका लागि तपाईँको टाइपिङ अनुभव सुधार्न। यस डाउनलोड 3G मा एक वा दुई मिनेट लाग्छ। शुल्कहरू लाग्न सक्छ यदि तपाईँसँग असीमित डेटा योजना छैन भने। यदि आफूसँग कुन डेटा योजना छ तपाईँ यकिन हुनुहुन्न भने हामी स्वचालित रूपमा डाउनलोड सुरु गर्न वाइ-फाइ जडान खोज्न सिफारिस गर्छौं। सल्लाह: तपाईँको मोबाइल उपकरणको भाषा र इनपुट सेटिङ मेनुमा गई तपाईँ शब्दकोशलाई डाउनलोड वा हटाउन सक्नुहुन्छ।"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"(अब डाउनलोड गर्नुहोस्<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"वाइ-फाइको माध्ययमद्वार डाउनलोड गर्नुहोस्"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"एक शब्दकोश <xliff:g id="LANGUAGE">%1$s</xliff:g> का लागि उपलब्ध छ"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"समीक्षा गर्न थिच्नुहोस् र डाउनलोड गर्नुहोस्"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"डाउनलोड गरिदै: <xliff:g id="LANGUAGE">%1$s</xliff:g>का लागि सुझावहरू चाँडै तयार हुने छन्।"</string>
+ <string name="version_text" msgid="2715354215568469385">"संस्करण <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"थप्नुहोस्"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"शब्दकोशमा थप्नुहोस्"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"पदावली"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"थप विकल्पहरू"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"कम विकल्पहरू"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"ठीक छ"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"शब्द:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"सर्टकट:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"भाषा:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"एउटा शब्द टाइप गर्नुहोस्"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"वैकल्पिक सर्टकट"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"शब्द सम्पादन गर्नुहोस्"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"सम्पादन गर्नुहोस्"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"मेट्नुहोस्"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"तपाईँसँग प्रयोगकर्ता शब्दकोशमा कुनै शब्द छैन।\"थप्नुहोस्\"(+) बटनमा छोएर एउटा शब्द थप्नुहोस्।"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"सबै भाषाहरूका लागि"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"थप भाषाहरू..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"मेट्नुहोस्"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-ne/strings-appname.xml b/java/res/values-ne/strings-appname.xml
new file mode 100644
index 000000000..5ad5eae66
--- /dev/null
+++ b/java/res/values-ne/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android Keyboard (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android Spell Checker (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android Keyboard Settings (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Spell Checker Settings (AOSP)"</string>
+</resources>
diff --git a/java/res/values-ne/strings.xml b/java/res/values-ne/strings.xml
new file mode 100644
index 000000000..6c149456d
--- /dev/null
+++ b/java/res/values-ne/strings.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"इनपुट विकल्पहरू"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"लग निर्देशनहरू शोध गर्नुहोस्"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"सम्पर्क नामहरू हेर्नुहोस्"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"तपाईँको सम्पर्क सूचीबाट हिज्जे परीक्षकले प्रविष्टिहरूको प्रयोग गर्छ"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"कुञ्जी थिच्दा भाइब्रेट"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"कुञ्जी थिच्दा आवाज"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"कुञ्जी दबाउँदा पपअप"</string>
+ <string name="general_category" msgid="1859088467017573195">"सामान्य"</string>
+ <string name="correction_category" msgid="2236750915056607613">"पाठ सुधार"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"इशारा टाइप गर्ने"</string>
+ <string name="misc_category" msgid="6894192814868233453">"अन्य विकल्पहरू"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"जटिल सेटिङहरू"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"विज्ञहरूका लागि विकल्पहरू"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"अन्य इनपुट विधिमा स्विच गर्नुहोस्"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"भाषा स्विच किले अन्य इनपुट विधि पनि समेट्छ"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"भाषा स्विच कुञ्जी"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"जब बहुसङ्ख्यक इनपुट भाषाहरू सक्षम भएपछि देखाउनुहोस्"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"स्लाइड सूचक देखाउनुहोस्"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"सिफ्ट वा प्रतिक कुञ्जीमा स्लाइड गर्ने बेला दृश्य सङ्केत देखाउनुहोस्"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"कि पपअप खारेजी ढिलाइ"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ढिलाइ छैन"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"पूर्वनिर्धारित"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> मिलिसेकेन्ड"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"प्रणाली पूर्वनिर्धारित"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"सम्पर्क नामहरू सुझाव गर्नुहोस्"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव र सुधारका लागि सम्पर्कबाट नामहरू प्रयोग गर्नुहोस्"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"डबल-स्पेस पूर्णविराम"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबारमा डबल ट्याप गर्नाले पूर्णविरामपछि स्पेस राख्दछ"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"स्वतः पूँजिकरण"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"प्रत्येक वाक्यको पहिलो शब्द क्यापिटल गर्नुहोस्"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"व्यक्तिगत शब्दकोश"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"एड-अन शब्दकोश"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"मुख्य शब्दकोश"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"सुधार सुझावहरू देखाउनुहोस्"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"टाइप गर्ने बेलामा सुझाव शब्दहरू देखाउनुहोस्"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"सधैँ देखाउनुहोस्"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"चित्र मोडमा देखाउनुहोस्"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"सधैँ लुकाउनुहोस्"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"आपत्तिजनक शब्दहरूलाई रोक्नुहोस्"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"सम्भावित आपत्तिजनक शब्दहरू सुझाव नगर्नुहोस्"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"स्वतः सुधार"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"गल्ती टाइप भएका शब्दहरूलाई स्पेसबार र पङ्चुएसनले स्वचालित रूपमा सच्याउँछन्।"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"बन्द"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"सामान्य"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"आक्रामक"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ज्यादै आक्रामक"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"अर्को शब्द सुझाव"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"सुझावहरू निर्माण गर्न अघिल्लो शब्द प्रयोग गर्नुहोस्"</string>
+ <string name="gesture_input" msgid="826951152254563827">"इशारा टाइप गर्ने सक्षम पार्नुहोस्"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"अक्षर स्लाइड गरी शब्द इनपुट गर्नुहोस्"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"इशारा ट्रेल देखाउनुहोस्"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"गतिशील फ्लोटिङ पूर्वावलोकन"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"इशारा गर्दा सुझाव दिइएको शब्द हेर्नुहोस्"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : बचत गरियो"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"जानुहोस्"</string>
+ <string name="label_next_key" msgid="362972844525672568">"अर्को"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"अघिल्लो"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"भयो"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"पठाउनुहोस्"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"रोक्नुहोस्"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"प्रतीक्षा गर्नुहोस्"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"हेडसेट प्लग इन गर्नुहोस्"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"वर्तमान पाठ %s हो"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"कुनै पाठ प्रविष्टि गरिएको छैन"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"कुञ्जी कोड %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"सिफ्ट"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"सिप्ट सक्रिय (असक्षम पार्न ट्याप गर्नुहोस्)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"क्याप्स लक सक्रिय छ (असक्षम पार्न ट्याप गर्नुहोस्)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"मेट्नुहोस्"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"प्रतिकहरू"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"अक्षरहरू"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"नम्बरहरू"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"सेटिङहरू"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"ट्याब"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"स्पेस"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"आवाज इनपुट"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"मुस्कुराएको अनुहार"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"फर्कनुहोस्"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"खोज्नुहोस्"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"डट"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"भाषा स्विच गर्नुहोस्"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"अर्को"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"अघिल्लो"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"सिफ्ट सक्षम पारिएको छ"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"क्याप्स लक सक्षम पारिएको छ"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"सिफ्ट असक्षम पारिएको छ"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"प्रतिक मोड"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"अक्षर मोड"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"फोन मोड"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"फोन प्रतिक मोड"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"किबोर्ड लुकाइएको छ"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> किबोर्ड देखाइँदै"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"मिति"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"मिति र समय"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"इमेल"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"सन्देश गर्दै"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"सङ्ख्या"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"फोन"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"पाठ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"समय"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"आवाज इनपुट कुञ्जी"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"मुख्य किबोर्डमा"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"प्रतिकहरू किबोर्डमा"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"बन्द"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"मुख्य किबोर्डमा माइक"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"प्रतिकहरू किबोर्डमा माइक"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"आवाज इनपुट असक्षम पारियो"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"इनपुट विधिहरू कन्फिगर गर्नुहोस्"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"इनपुट भाषाहरू"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"प्रतिक्रिया पठाउनुहोस्"</string>
+ <string name="select_language" msgid="3693815588777926848">"इनपुट भाषाहरू"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"बचत गर्न पुनः छुनुहोस्"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"उपलब्ध शब्दकोश"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"प्रयोगकर्ता प्रतिक्रिया सक्षम पार्नुहोस्"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"स्वचालित रूपमा प्रयोग तथ्याङ्कहरू र क्यास रिपोर्टहरू पठाएर यस इनपुट विधि सम्पादकलाई सुधार्न सहयोग गर्नुहोस्।"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"किबोर्ड थिम"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेजी (युके)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेजी (युएस्)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"स्पेनिस (युएस्)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"अंग्रेजी (युके) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"अंग्रेजी (युएस्) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"स्पेनेली (युएस्) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"कुनै भाषा होइन (वर्णमाला)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णमाला (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णमाला (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"वर्णमाला (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"वर्णमाला (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"वर्णमाला (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"वर्णमाला (PC)"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"अनुकूलन इनपुट शैली"</string>
+ <string name="add_style" msgid="6163126614514489951">"शैली थप्नुहोस्"</string>
+ <string name="add" msgid="8299699805688017798">"थप्नुहोस्"</string>
+ <string name="remove" msgid="4486081658752944606">"हटाउनुहोस्"</string>
+ <string name="save" msgid="7646738597196767214">"बचत गर्नुहोस्"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"भाषा"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"लेआउट"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"तपाईँले प्रयोग गर्न सुरु गर्न अघि तपाईँको अनुकूलन इनपुट शैली सक्षम पारिनु पर्छ। के तपाईँ यसलाई अहिले सक्षम पार्न चाहनु हुन्छ?"</string>
+ <string name="enable" msgid="5031294444630523247">"सक्षम पार्नुहोस्"</string>
+ <string name="not_now" msgid="6172462888202790482">"अहिले होइन"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"यस्तो इनपुट शैली पहिले नै अवस्थित छ: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"प्रयोग अध्ययन मोड"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"कुञ्जी लामो थिचाइ ढिलाइ"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"कुञ्जी थिचाइ भाइब्रेसन अवधि"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"कुञ्जी थिचाइ आवाज भोल्युम"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"बाह्य शब्दकोश फाइल पढ्नुहोस्"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"डाउनलोड फोल्डरमा कुनै शब्दकोश फाइलहरू छैनन्।"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"स्थापना गर्न कुनै शब्दकोश फाइल चयन गर्नुहोस्"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"<xliff:g id="LOCALE_NAME">%s</xliff:g>का लागि साँच्चिकै यो फाइल स्थापना गर्ने हो?"</string>
+ <string name="error" msgid="8940763624668513648">"कुनै त्रुटि भयो"</string>
+ <string name="button_default" msgid="3988017840431881491">"पूर्वनिर्धारित"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"तपाईँलाई स्वागत छ<xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"इशारा टाइप गर्नेसँग"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"सुरु गरौं"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"अर्को चरण"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"स्थापना गर्दै <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"सक्षम पार्नुहोस् <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"कृपया जाँच गर्नुहोस् \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" तपाईँको भाषा र इनपुट सेटिङमा। यसले तपाईँलाई तपाईँको उपकरणमा सञ्चालन गर्न आधिकारिकता प्रदान गर्छ।"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> पहिले नै तपाईँको भाषा र इनपुट सेटिङमा सक्षम पारिएको छ, त्यसैले यो कदम सकिसकिएको छ। अर्कोमा जानुहोस्!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"सेटिङहरूमा सक्षम पार्नुहोस्"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>मा स्विच गर्नुहोस्"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"त्यसपछि, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" लाई तपाईँको सक्रिय पाठ इनपुट विधिका रूपमा चयन गर्नुहोस्।"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"इनपुट विधि स्विच गर्नुहोस्"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"बधाई छ, तपाईँले सेट पुरा गर्नुभयो!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"अब तपाईँ <xliff:g id="APPLICATION_NAME">%s</xliff:g>का साथ तपाईँका सम्पूर्ण मनपर्ने अनुप्रयोगहरू टाइप गर्न सक्नुहुन्छ।"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"थप भाषाहरू कन्फिगर गर्नुहोस्"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"समाप्त भयो"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"अनुप्रयोग आइकन देखाउनुहोस्"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"लन्चरमा अनुप्रयोग आइकन देखाउनुहोस्"</string>
+ <string name="app_name" msgid="6320102637491234792">"शब्दकोश प्रदायक"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"शब्दकोश प्रदायक"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"शब्दकोश सेवा"</string>
+ <string name="download_description" msgid="6014835283119198591">"शब्दकोश अद्यावधिक जानकारी"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"एड-अन शब्दकोश"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"उपलब्ध शब्दकोश"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"शब्दकोशहरूका लागि सेटिङहरू"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"प्रयोगकर्ता शब्दकोशहरू"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"प्रयोगकर्ता शब्दकोश"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"उपलब्ध शब्दकोश"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"हाल डाउनलोड गर्दै"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"स्थापित"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"स्थापित, असक्षम पारिएको"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"शब्दकोश सेवासँग जोड्न समस्या"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"शब्दकोशहरू उपलब्ध छैनन्"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"पुनः ताजा गर्नुहोस्"</string>
+ <string name="last_update" msgid="730467549913588780">"पछिल्लो अद्यावधिक"</string>
+ <string name="message_updating" msgid="4457761393932375219">"अद्यावधिकको लागि जाँच गर्दै"</string>
+ <string name="message_loading" msgid="8689096636874758814">"लोड हुँदै..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"मुख्य शब्दकोश"</string>
+ <string name="cancel" msgid="6830980399865683324">"रद्द गर्नुहोस्"</string>
+ <string name="install_dict" msgid="180852772562189365">"स्थापना गर्नुहोस्"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"रद्द गर्नुहोस्"</string>
+ <string name="delete_dict" msgid="756853268088330054">"मेट्नुहोस्"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"तपाईँको मोबाइल उपकरणमा चयन गरिएको भाषामा शब्दकोश उपलब्ध छ। हामी सिफारिश गर्छौं <xliff:g id="LANGUAGE">%1$s</xliff:g> शब्दकोश डाउनलोड गर्नका लागि तपाईँको टाइपिङ अनुभव सुधार्न। यस डाउनलोड 3G मा एक वा दुई मिनेट लाग्छ। शुल्कहरू लाग्न सक्छ यदि तपाईँसँग असीमित डेटा योजना छैन भने। यदि आफूसँग कुन डेटा योजना छ तपाईँ यकिन हुनुहुन्न भने हामी स्वचालित रूपमा डाउनलोड सुरु गर्न वाइ-फाइ जडान खोज्न सिफारिस गर्छौं। सल्लाह: तपाईँको मोबाइल उपकरणको भाषा र इनपुट सेटिङ मेनुमा गई तपाईँ शब्दकोशलाई डाउनलोड वा हटाउन सक्नुहुन्छ।"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"(अब डाउनलोड गर्नुहोस्<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"वाइ-फाइको माध्ययमद्वार डाउनलोड गर्नुहोस्"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"एक शब्दकोश <xliff:g id="LANGUAGE">%1$s</xliff:g> का लागि उपलब्ध छ"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"समीक्षा गर्न थिच्नुहोस् र डाउनलोड गर्नुहोस्"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"डाउनलोड गरिदै: <xliff:g id="LANGUAGE">%1$s</xliff:g>का लागि सुझावहरू चाँडै तयार हुने छन्।"</string>
+ <string name="version_text" msgid="2715354215568469385">"संस्करण <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"थप्नुहोस्"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"शब्दकोशमा थप्नुहोस्"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"पदावली"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"थप विकल्पहरू"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"कम विकल्पहरू"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"ठीक छ"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"शब्द:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"सर्टकट:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"भाषा:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"एउटा शब्द टाइप गर्नुहोस्"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"वैकल्पिक सर्टकट"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"शब्द सम्पादन गर्नुहोस्"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"सम्पादन गर्नुहोस्"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"मेट्नुहोस्"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"तपाईँसँग प्रयोगकर्ता शब्दकोशमा कुनै शब्द छैन।\"थप्नुहोस्\"(+) बटनमा छोएर एउटा शब्द थप्नुहोस्।"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"सबै भाषाहरूका लागि"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"थप भाषाहरू..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"मेट्नुहोस्"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-si-rLK/strings-appname.xml b/java/res/values-si-rLK/strings-appname.xml
new file mode 100644
index 000000000..108104872
--- /dev/null
+++ b/java/res/values-si-rLK/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android යතුරු පුවරුව (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android අක්ෂර වින්‍යාස පරීක්ෂක (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android යතුරු පුවරු සැකසීම් (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android අක්ෂර වින්‍යාස පරීක්ෂක සැකසීම් (AOSP)"</string>
+</resources>
diff --git a/java/res/values-si-rLK/strings.xml b/java/res/values-si-rLK/strings.xml
new file mode 100644
index 000000000..23896b2e8
--- /dev/null
+++ b/java/res/values-si-rLK/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ආදාන විකල්ප"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"පර්යේෂණ ලොග් විධාන"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"සබඳතා නම් විමසන්න"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"අක්ෂර වින්‍යාස පරික්ෂකය ඔබගේ සබඳතා ලැයිස්තුව වෙතින් ඇතුළත් කිරීම් භාවිතා කරයි"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"යතුර එබීමට කම්පනය කිරීම සක්‍රියයි"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"යතුරු එබිම මත හඬ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"යතුරු එබීම මත උත්පතනය"</string>
+ <string name="general_category" msgid="1859088467017573195">"සාමාන්‍ය"</string>
+ <string name="correction_category" msgid="2236750915056607613">"පෙළ නිවැරදි කිරීම"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"ඉංගිතයෙන් ටයිප් කිරීම"</string>
+ <string name="misc_category" msgid="6894192814868233453">"වෙනත් විකල්ප"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"උසස් සැකසීම්"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"ප්‍රවීනයන් සඳහා විකල්ප"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"වෙනත් ආදාන ක්‍රම වෙත මාරුවන්න"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"භාෂා මාරු යතුර වෙනත් ආදාන ක්‍රමද ආවරණය කරයි"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"භාෂා මාරු යතුර"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"බහුවිධ ආදාන භාෂා සබල කර ඇති විට පෙන්වන්න"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"සර්පණ දර්ශකය පෙන්වන්න"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"ෂිෆ්ට් හෝ සංකේත යතුරු වෙතින් සර්පණය කරන අතරතුර දෘෂ්‍ය ඉඟි දර්ශනය කරන්න"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"යතුරු උත්පතන ඉවත් කිරීමේ ප්‍රමාදය"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ප්‍රමාද නැත"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"සුපුරුදු"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"පද්ධති සුපුරුදු"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"සබඳතා නම් යෝජනා කරන්න"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"යෝජනා සහ නිවැරදි කිරීම් සඳහා සබඳතා වෙතින් නම් භාවිතා කරන්න"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"දෙවරක්-ඉඩ නැවතීමේ ලකුණ"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"ඉඩ යතුර මත දෙවරක් තට්ටු කිරීම හිස් තැනකට අනුගාමිව නැවතීමේ ලකුණක් ඇතුළත් කරයි."</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ස්වයං-ලොකු අකුරු කරණය"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"එක් එක් වාක්‍යයේ පළමු වචනය ලොකු අකුරු කරන්න"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"පුද්ගලික ශබ්ද කෝෂය"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"ඈඳුම් ශබ්දකෝෂ"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"ප්‍රධාන ශබ්ද කෝෂය"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"නිවැරදි කිරීම් යෝජනා පෙන්වන්න"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"ටයිප් කරන අතරතුර යෝජිත වචන දර්ශනය කරන්න"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"සැමවිටම පෙන්වන්න"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"සිරස් ආකෘති ප්‍රකාරය තුළ පෙන්වන්න"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"සැමවිට සඟවන්න"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"අප්‍රසන්න වචන අවහිර කරන්න"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"විභව්‍යව අප්‍රසන්න වචන යෝජනා නොකරන්න"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ස්වයං-නිවැරදි කිරීම"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"ඉඩ යතුර සහ විරාම ලකුණ වැරදියට ටයිප් කළ වචන ස්වයංක්‍රියව නිවැරදි කරයි"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"අක්‍රියයි"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"මධ්‍යස්"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"ආක්‍රමණකාරී"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ඉතා ආක්‍රමණකාරී"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"ඊළඟ-වචනයේ යෝජනා"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"යෝජනා කිරීමේදී පෙර වචනය භාවිතා කරන්න"</string>
+ <string name="gesture_input" msgid="826951152254563827">"ඉංගිතයෙන් ටයිප් කිරීම සබල කරන්න"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"අකුරු ඔස්සේ සර්පණය කිරීමෙන් වචනයක් ආදානය කරන්න"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"ඉංගිතයෙන් මඟ පෙන්වන්න"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"ගතිකව ඉපිලෙන පෙරදසුන"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"ඉංගිතය කරන අතරතුර යෝජිත වචන බලන්න"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : සුරැකිණි"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"යන්න"</string>
+ <string name="label_next_key" msgid="362972844525672568">"ඊළඟ"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"පෙර"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"හරි"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"යවන්න"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"විරාම කරන්න"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"රැඳී සිටින්න"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"හඬ නගා කථනය කරන මුරපද යතුරු ඇසීමට හෙඩ්සෙට් එකක් පේනුගත කරන්න."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"වර්තමාන පෙළ %s ය"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"පෙළ ඇතුළු කර නැත"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"යතුරු කේතය %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"ෂිෆ්ට්"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"ෂිෆ්ට් සක්‍රියයි (අබල කිරීමට තට්ටු කරන්න)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"කැප්ස් ලොක් සක්‍රියයි (අබල කිරීමට තට්ටු කරන්න)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"මකන්න"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"සංකේත"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"අකුරු"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"අංක"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"සැකසීම්"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"ටැබය"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"හිඩස"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"හඬ ආදානය"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"සිනහ මුහුණ"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"ආපසු එවන්න"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"සෙවීම"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"තිත"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"භාෂාව මාරු කරන්න"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"ඊළඟ"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"පෙර"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"ෂිෆ්ට් සබල කර ඇත"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"කැප්ස් ලොක් සබල කර ඇත"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"ෂිෆ්ට් අබල කර ඇත"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"සංකේත ආකාරය"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"අකුරු ආකාරය"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"දුරකථන ආකාරය"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"දුරකථන සංකේත ආකාරය"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"යතුරු පුවරුව සැඟවී ඇත"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> යතුරු පුවරුව පෙන්නුම් කෙරේ"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"දිනය"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"දිනය සහ වේලාව"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"ඊ-තැපෑල"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"පණිවිඩ යැවීම"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"අංකය"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"දුරකථනය"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"පෙළ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"කාලය"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"හඬ ආදාන යතුර"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"ප්‍රධාන යතුරු පුවරුව මත"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"සංකේත යතුරු පුවරුව මත"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"අක්‍රියයි"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"ප්‍රධාන යතුරු පුවරුව මත මයික්‍රෆෝනය"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"සංකේත යතුරු පුවරුව මත මයික්‍රෆෝනය"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"හඬ ආදානය අබල කර ඇත"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"ආදාන ක්‍රම වින්‍යාස කරන්න"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"ආදාන භාෂා"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"ප්‍රතිපෝෂණ යවන්න"</string>
+ <string name="select_language" msgid="3693815588777926848">"ආදාන භාෂා"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"සුරැකීමට නැවත ස්පර්ශ කරන්න"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"ශබ්ද කෝෂය ලබාගත හැක"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"පරිශීලක ප්‍රතිපෝෂණ සබල කරන්න"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"භාවිතය පිළිබඳ සංඛ්‍යාලේඛන සහ බිඳ වැටීම් වාර්තා ස්වයංක්‍රියව යැවීම මගින් ආදාන ක්‍රම සංස්කාරක වැඩි දියුණු කිරීමට උදව් වන්න."</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"යතුරු පුවරු තේමාව"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"ඉංග්‍රීසි (UK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"ඉංග්‍රීසි (US)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"ස්පාඤ්ඤ (US)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"ඉංග්‍රිසි (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"ඉංග්‍රීසි (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ස්පාඤ්ඤ (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (සාම්ප්‍රදායික)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"භාෂාවක් නැත (අකාරාදිය)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"අකාරාදිය (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"අකාරාදිය (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"අකාරාදිය (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"අකාරාදිය (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"අකාරාදිය (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"අකාරාදිය (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"ඉමොජි"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"අභිරුචි ආදාන විලාස"</string>
+ <string name="add_style" msgid="6163126614514489951">"විලාසය එක් කරන්න"</string>
+ <string name="add" msgid="8299699805688017798">"එක් කරන්න"</string>
+ <string name="remove" msgid="4486081658752944606">"ඉවත් කරන්න"</string>
+ <string name="save" msgid="7646738597196767214">"සුරකින්න"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"භාෂාව"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"පිරිසැලසුම"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"ඔබ එය භාවිතය ආරම්භ කිරීමට පෙර ඔබගේ අභිරුචි ආදාන විලාසය සබල කිරීමට අවශ්‍යය. ඔබට එය දැන් සබල කිරීමට අවශ්‍යද?"</string>
+ <string name="enable" msgid="5031294444630523247">"සබල කරන්න"</string>
+ <string name="not_now" msgid="6172462888202790482">"දැන් නොවේ"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"සමාන ආදාන විලාසය දැනටමත් පවතී: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"උපයෝජ්‍යතා අධ්‍යයන ආකාරය"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"යතුරු දිගු එබීම් ප්‍රමාදය"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"යතුරු එබිම් කම්පන කාලපරිච්ඡේදය"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"යතුරු එබීම් හඬ තීව්‍රතාවය"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"බාහිර ශබ්ද කෝෂ ගොනුව කියවන්න"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"බාගැනීම් ෆෝල්ඩරය තුළ ශබ්දකෝෂ ගොනු නොමැත"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ස්ථාපනය කිරීමට ශබ්ද කෝෂ ගොනුවක් තෝරන්න"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"<xliff:g id="LOCALE_NAME">%s</xliff:g> සඳහා මෙම ගොනුව ස්ථාපනය කරන්නද?"</string>
+ <string name="error" msgid="8940763624668513648">"දෝෂයක් ඇති විය"</string>
+ <string name="button_default" msgid="3988017840431881491">"සුපුරුදු"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> වෙත සාදරයෙන් පිළිගනිමු"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ඉංගිත ටයිප් කිරීම් සමග"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"අරඹන්න"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"ඊළඟ පියවර"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> සැකසෙමින් පවතී"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> සබල කරන්න"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"කරණාකර ඔබගේ භාෂවෙහි සහ ආදාන සැකසීම් වල \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" පරික්ෂා කරන්න. මෙය ඔබගේ උපාංගය මත එයට ධාවනය වීමට අනුමැතිය දෙනු ඇත."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> දැනටමත් ඔබගේ භාෂාවෙන් සහ ආදාන සැකසීම්වල සබල කර ඇත, එම නිසා මෙම පියවර නිමයි. ඊළග එක වෙතට!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"සැකසීම් තුළ සබල කරන්න"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> වෙත මාරුවන්න"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"ඊළඟට, ඔබගේ සක්‍රිය පෙළ-ආදාන ක්‍රමය ලෙස \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" තෝරන්න."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"ආදාන ක්‍රම මාරු කරන්න"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"සුබපැතුම්, ඔබ සියල්ල පිහිටුවා ඇත!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"දැන් ඔබට <xliff:g id="APPLICATION_NAME">%s</xliff:g> සමගින් ඔබගේ සියළුම ප්‍රියතම යෙදුම් වලින් ටයිප් කළ හැක."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"අතිරේක භාෂා වින්‍යාස කරන්න"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"අවසන්"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"යෙදුම් නිරූපකය පෙන්වන්න"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"දියත්කරනය තුළ යෙදුම් නිරූපකය දර්ශනය කරන්න"</string>
+ <string name="app_name" msgid="6320102637491234792">"ශබ්දකෝෂ සැපයුම්කරු"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"ශබ්දකෝෂ සැපයුම්කරු"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"ශබ්ද කෝෂ සේවාව"</string>
+ <string name="download_description" msgid="6014835283119198591">"ශබ්ද කෝෂ යාවත්කාලීන තොරතුරු"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ඈඳුම් ශබ්ද කෝෂ"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"ශබ්දකෝෂය ලබාගත හැක"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ශබ්ද කෝෂ සඳහා සැකසීම්"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"පරිශීලක ශබ්ද කෝෂ"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"පරිශීලක ශබ්ද කෝෂය"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"ශබ්දකෝෂය ලබාගත හැක"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"දැනට බාගැනේ"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"ස්ථාපිතයි"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"ස්ථාපනය කළ, අබල කළ"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"ශබ්දකෝෂ සේවාව වෙත සම්බන්ධ වීමට ගැටලුවක්ද"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"ශබ්ද කෝෂ ලබාගත නොහැක"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"නැවුම් කරන්න"</string>
+ <string name="last_update" msgid="730467549913588780">"අවසන් වරට යාවත්කාලීන කළේ"</string>
+ <string name="message_updating" msgid="4457761393932375219">"යාවත්කාලීන සඳහා පරික්ෂා කෙරේ"</string>
+ <string name="message_loading" msgid="8689096636874758814">"පූරණය වෙමින්..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"ප්‍රධාන ශබ්ද කෝෂය"</string>
+ <string name="cancel" msgid="6830980399865683324">"අවලංගු කරන්න"</string>
+ <string name="install_dict" msgid="180852772562189365">"ස්ථාපනය"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"අවලංගු කරන්න"</string>
+ <string name="delete_dict" msgid="756853268088330054">"මකන්න"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"ඔබගේ ජංගම උපාංගය මත තෝරාගත් භාෂාවට ලබාගත හැකි ශබ්ද කෝෂයක් ඇත.&lt;br/&gt; අප ඔබගේ ටයිප් කිරීමේ පළපුරුද්ද වැඩි දියුණු කිරීමට <xliff:g id="LANGUAGE">%1$s</xliff:g> ශබ්ද කෝෂය &lt;b&gt;බාගැනීම&lt;/b&gt; නිර්දේශ කරමු.&lt;br/&gt; &lt;br/&gt; 3G හරහා බාගැනීම මිනිත්තුවක් හෝ දෙකක් ගත හැකිය. ඔබට &lt;b&gt;සීමාරහිත දත්ත සැලසුමක්&lt;/b&gt; නොමැති නම් ගාස්තු අදාළ විය හැක.&lt;br/&gt; ඔබට තිබෙන්නේ කුමන දත්ත සැලසුමක්ද යන්න පිළිබඳ විශ්වාසයක් නොමැති නම්, බාගැනීම ස්වයංක්‍රියව ආරම්භ කිරීමට Wi-Fi සම්බන්ධයක් සොයා ගැනීම අප නිර්දේශ කරමු.&lt;br/&gt; &lt;br/&gt; ඉඟිය: ඔබට ඔබගේ ජංගම උපාංගයේ &lt;b&gt;සැකසීම්&lt;/b&gt; මෙනුව තුළ &lt;b&gt;භාෂාව සහ ආදානය&lt;/b&gt; වෙත යාම මගින් ශබ්දකෝෂ බාගැනීමට සහ ඉවත් කිරීමට හැක."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"දැන් බාගන්න (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi හරහා බාගන්න"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g> සඳහා ශබ්දකෝෂයක් ලබාගත හැක"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"සමාලෝචනය කිරීමට සහ බාගැනීමට ඔබන්න"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"බාගැනේ: <xliff:g id="LANGUAGE">%1$s</xliff:g> සඳහා යෝජනා ඉක්මනින් සුදානම් වනු ඇත."</string>
+ <string name="version_text" msgid="2715354215568469385">"<xliff:g id="VERSION_NUMBER">%1$s</xliff:g> අනුවාදය"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"එක් කරන්න"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"ශබ්ද කෝෂය වෙත එක් කරන්න"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"වාක්‍ය ඛණ්ඩය"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"තවත් විකල්ප"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"අඩු විකල්ප"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"හරි"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"වචනය:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"කෙටිමග:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"භාෂාව:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"වචනයක් ටයිප් කරන්න"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"විකල්පමය කෙටිමග"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"වචනය සංස්කරණය කරන්න"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"සංස්කරණය කරන්න"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"මකන්න"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"ඔබට පරිශීලක ශබ්ද කෝෂය තුළ වචන කිසිවක් නැත. එක් කරන්න (+) බොත්තම ස්පර්ශ කිරීම මගින් වචනයක් එක් කරන්න."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"සියලු භාෂාවන් සඳහා"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"තවත් භාෂා…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"මකන්න"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-si/strings-appname.xml b/java/res/values-si/strings-appname.xml
new file mode 100644
index 000000000..108104872
--- /dev/null
+++ b/java/res/values-si/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android යතුරු පුවරුව (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android අක්ෂර වින්‍යාස පරීක්ෂක (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android යතුරු පුවරු සැකසීම් (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android අක්ෂර වින්‍යාස පරීක්ෂක සැකසීම් (AOSP)"</string>
+</resources>
diff --git a/java/res/values-si/strings.xml b/java/res/values-si/strings.xml
new file mode 100644
index 000000000..6d2a6f61b
--- /dev/null
+++ b/java/res/values-si/strings.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"ආදාන විකල්ප"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"පර්යේෂණ ලොග් විධාන"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"සබඳතා නම් විමසන්න"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"අක්ෂර වින්‍යාස පරික්ෂකය ඔබගේ සබඳතා ලැයිස්තුව වෙතින් ඇතුළත් කිරීම් භාවිතා කරයි"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"යතුර එබීමට කම්පනය කිරීම සක්‍රියයි"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"යතුරු එබිම මත හඬ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"යතුරු එබීම මත උත්පතනය"</string>
+ <string name="general_category" msgid="1859088467017573195">"සාමාන්‍ය"</string>
+ <string name="correction_category" msgid="2236750915056607613">"පෙළ නිවැරදි කිරීම"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"ඉංගිතයෙන් ටයිප් කිරීම"</string>
+ <string name="misc_category" msgid="6894192814868233453">"වෙනත් විකල්ප"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"උසස් සැකසීම්"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"ප්‍රවීනයන් සඳහා විකල්ප"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"වෙනත් ආදාන ක්‍රම වෙත මාරුවන්න"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"භාෂා මාරු යතුර වෙනත් ආදාන ක්‍රමද ආවරණය කරයි"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"භාෂා මාරු යතුර"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"බහුවිධ ආදාන භාෂා සබල කර ඇති විට පෙන්වන්න"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"සර්පණ දර්ශකය පෙන්වන්න"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"ෂිෆ්ට් හෝ සංකේත යතුරු වෙතින් සර්පණය කරන අතරතුර දෘෂ්‍ය ඉඟි දර්ශනය කරන්න"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"යතුරු උත්පතන ඉවත් කිරීමේ ප්‍රමාදය"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ප්‍රමාද නැත"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"සුපුරුදු"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"පද්ධති සුපුරුදු"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"සබඳතා නම් යෝජනා කරන්න"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"යෝජනා සහ නිවැරදි කිරීම් සඳහා සබඳතා වෙතින් නම් භාවිතා කරන්න"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"දෙවරක්-ඉඩ නැවතීමේ ලකුණ"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"ඉඩ යතුර මත දෙවරක් තට්ටු කිරීම හිස් තැනකට අනුගාමිව නැවතීමේ ලකුණක් ඇතුළත් කරයි."</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ස්වයං-ලොකු අකුරු කරණය"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"එක් එක් වාක්‍යයේ පළමු වචනය ලොකු අකුරු කරන්න"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"පුද්ගලික ශබ්ද කෝෂය"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"ඈඳුම් ශබ්දකෝෂ"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"ප්‍රධාන ශබ්ද කෝෂය"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"නිවැරදි කිරීම් යෝජනා පෙන්වන්න"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"ටයිප් කරන අතරතුර යෝජිත වචන දර්ශනය කරන්න"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"සැමවිටම පෙන්වන්න"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"සිරස් ආකෘති ආකාරය තුළ පෙන්වන්න"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"සැමවිට සඟවන්න"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"අප්‍රසන්න වචන අවහිර කරන්න"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"විභව්‍යව අප්‍රසන්න වචන යෝජනා නොකරන්න"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ස්වයං-නිවැරදි කිරීම"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"ඉඩ යතුර සහ විරාම ලකුණ වැරදියට ටයිප් කළ වචන ස්වයංක්‍රියව නිවැරදි කරයි"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"අක්‍රිය කරන්න"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"මධ්‍යස්ථ"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"ආක්‍රමණකාරී"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ඉතා ආක්‍රමණකාරී"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"ඊළඟ-වචනයේ යෝජනා"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"යෝජනා කිරීමේදී පෙර වචනය භාවිතා කරන්න"</string>
+ <string name="gesture_input" msgid="826951152254563827">"ඉංගිතයෙන් ටයිප් කිරීම සබල කරන්න"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"අකුරු ඔස්සේ සර්පණය කිරීමෙන් වචනයක් ආදානය කරන්න"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"ඉංගිතයෙන් මඟ පෙන්වන්න"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"ගතිකව ඉපිලෙන පෙරදසුන"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"ඉංගිතය කරන අතරතුර යෝජිත වචන බලන්න"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : සුරැකිණි"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"යන්න"</string>
+ <string name="label_next_key" msgid="362972844525672568">"මීලඟ"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"පෙර"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"හරි"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"යවන්න"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"විරාම කරන්න"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"රැඳී සිටින්න"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"හඬ නගා කථනය කරන මුරපද යතුරු ඇසීමට හෙඩ්සෙට් එකක් පේනුගත කරන්න."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"වර්තමාන පෙළ %s ය"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"පෙළ ඇතුළු කර නැත"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"යතුරු කේතය %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"ෂිෆ්ට්"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"ෂිෆ්ට් සක්‍රියයි (අබල කිරීමට තට්ටු කරන්න)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"කැප්ස් ලොක් සක්‍රියයි (අබල කිරීමට තට්ටු කරන්න)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"මකන්න"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"සංකේත"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"අකුරු"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"අංක"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"සැකසීම්"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"ටැබය"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"හිඩස"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"හඬ ආදානය"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"සිනහ මුහුණ"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"ආපසු එවන්න"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"සෙවීම"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"තිත"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"භාෂාව මාරු කරන්න"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"මීලඟ"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"පෙර"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"ෂිෆ්ට් සබල කර ඇත"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"කැප්ස් ලොක් සබල කර ඇත"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"ෂිෆ්ට් අබල කර ඇත"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"සංකේත ප්‍රකාරය"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"අකුරු ආකාරය"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"දුරකථන ආකාරය"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"දුරකථන සංකේත ආකාරය"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"යතුරු පුවරුව සැඟවී ඇත"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> යතුරු පුවරුව පෙන්නුම් කෙරේ"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"දිනය"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"දිනය සහ වේලාව"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"ඊ-තැපෑල"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"පණිවිඩ යැවීම"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"අංකය"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"දුරකථනය"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"පෙළ"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"කාලය"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"හඬ ආදාන යතුර"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"ප්‍රධාන යතුරු පුවරුව මත"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"සංකේත යතුරු පුවරුව මත"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"අක්‍රිය කරන්න"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"ප්‍රධාන යතුරු පුවරුව මත මයික්‍රෆෝනය"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"සංකේත යතුරු පුවරුව මත මයික්‍රෆෝනය"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"හඬ ආදානය අබල කර ඇත"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"ආදාන ක්‍රම වින්‍යාස කරන්න"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"ආදාන භාෂා"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"ප්‍රතිපෝෂණ යවන්න"</string>
+ <string name="select_language" msgid="3693815588777926848">"ආදාන භාෂා"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"සුරැකීමට නැවත ස්පර්ශ කරන්න"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"ශබ්ද කෝෂය ලබාගත හැක"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"පරිශීලක ප්‍රතිපෝෂණ සබල කරන්න"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"භාවිතය පිළිබඳ සංඛ්‍යාලේඛන සහ බිඳ වැටීම් වාර්තා ස්වයංක්‍රියව යැවීම මගින් ආදාන ක්‍රම සංස්කාරක වැඩි දියුණු කිරීමට උදව් වන්න."</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"යතුරු පුවරු තේමාව"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"ඉංග්‍රීසි (බ්‍රිතාන්‍ය)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"ඉංග්‍රීසි (ඇමෙරිකානු)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"ස්පාඤ්ඤ (එජ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"ඉංග්‍රිසි (එරා) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"ඉංග්‍රීසි (එජ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ස්පාඤ්ඤ (එජ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"භාෂාවක් නැත (අකාරාදිය)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"අකාරාදිය (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"අකාරාදිය (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"අකාරාදිය (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"අකාරාදිය (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"අකාරාදිය (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"අකාරාදිය (PC)"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"අභිරුචි ආදාන විලාස"</string>
+ <string name="add_style" msgid="6163126614514489951">"විලාසය එක් කරන්න"</string>
+ <string name="add" msgid="8299699805688017798">"එක් කරන්න"</string>
+ <string name="remove" msgid="4486081658752944606">"ඉවත් කරන්න"</string>
+ <string name="save" msgid="7646738597196767214">"සුරකින්න"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"භාෂාව"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"පිරිසැලසුම"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"ඔබ එය භාවිතය ආරම්භ කිරීමට පෙර ඔබගේ අභිරුචි ආදාන විලාසය සබල කිරීමට අවශ්‍යය. ඔබට එය දැන් සබල කිරීමට අවශ්‍යද?"</string>
+ <string name="enable" msgid="5031294444630523247">"සබල කරන්න"</string>
+ <string name="not_now" msgid="6172462888202790482">"දැන් නොවේ"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"සමාන ආදාන විලාසය දැනටමත් පවතී: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"උපයෝජ්‍යතා අධ්‍යයන ආකාරය"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"යතුරු දිගු එබීම් ප්‍රමාදය"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"යතුරු එබිම් කම්පන කාලපරිච්ඡේදය"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"යතුරු එබීම් හඬ තීව්‍රතාවය"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"බාහිර ශබ්ද කෝෂ ගොනුව කියවන්න"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"බාගැනීම් ෆෝල්ඩරය තුළ ශබ්දකෝෂ ගොනු නොමැත"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ස්ථාපනය කිරීමට ශබ්ද කෝෂ ගොනුවක් තෝරන්න"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"<xliff:g id="LOCALE_NAME">%s</xliff:g> සඳහා මෙම ගොනුව ස්ථාපනය කරන්නද?"</string>
+ <string name="error" msgid="8940763624668513648">"දෝෂයක් ඇති විය"</string>
+ <string name="button_default" msgid="3988017840431881491">"සුපුරුදු"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> වෙත සාදරයෙන් පිළිගනිමු"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ඉංගිතයෙන් ටයිප් කිරීම් සමග"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"ආරම්භ කර ගැනීම"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"ඊළඟ පියවර"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> සැකසෙමින් පවතී"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> සබල කරන්න"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"කරණාකර ඔබගේ භාෂවෙහි සහ ආදාන සැකසීම් වල \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" පරික්ෂා කරන්න. මෙය ඔබගේ උපාංගය මත එයට ධාවනය වීමට අනුමැතිය දෙනු ඇත."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> දැනටමත් ඔබගේ භාෂාවෙන් සහ ආදාන සැකසීම්වල සබල කර ඇත, එමනිසා මෙම පියවර නිමයි. ඊළග එක වෙතට!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"සැකසීම් තුළ සබල කරන්න"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> වෙත මාරුවන්න"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"ඊළඟට, ඔබගේ සක්‍රිය පෙළ-ආදාන ක්‍රමය ලෙස \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" තෝරන්න."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"ආදාන ක්‍රම මාරු කරන්න"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"සුබපැතුම්, ඔබ සියල්ල පිහිටුවා ඇත!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"දැන් ඔබට <xliff:g id="APPLICATION_NAME">%s</xliff:g> සමගින් ඔබගේ සියළුම ප්‍රියතම යෙදුම් වලින් ටයිප් කළ හැක."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"අතිරේක භාෂා වින්‍යාස කරන්න"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"අවසන්ය"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"යෙදුම් අයිකනය පෙන්වන්න"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"දියත්කරනය තුළ යෙදුම් අයිකනය දර්ශනය කරන්න"</string>
+ <string name="app_name" msgid="6320102637491234792">"ශබ්දකෝෂ සැපයුම්කරු"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"ශබ්දකෝෂ සැපයුම්කරු"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"ශබ්ද කෝෂ සේවාව"</string>
+ <string name="download_description" msgid="6014835283119198591">"ශබ්ද කෝෂ යාවත්කාලීන තොරතුරු"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ඈඳුම් ශබ්ද කෝෂ"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"ශබ්දකෝෂය ලබාගත හැක"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ශබ්ද කෝෂ සඳහා සැකසීම්"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"පරිශීලක ශබ්ද කෝෂ"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"පරිශීලක ශබ්ද කෝෂය"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"ශබ්දකෝෂය ලබාගත හැක"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"දැනට බාගැනේ"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"පිහිටුවා ඇත"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"ස්ථාපනය කළ, අබල කළ"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"ශබ්දකෝෂ සේවාව වෙත සම්බන්ධ වීමට ගැටලුවක්ද"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"ශබ්ද කෝෂ ලබාගත නොහැක"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"නැවුම් කරන්න"</string>
+ <string name="last_update" msgid="730467549913588780">"අවසන් වරට යාවත්කාලීන කළේ"</string>
+ <string name="message_updating" msgid="4457761393932375219">"යාවත්කාලීන සඳහා පරික්ෂා කෙරේ"</string>
+ <string name="message_loading" msgid="8689096636874758814">"පූරණය වෙමින්..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"ප්‍රධාන ශබ්ද කෝෂය"</string>
+ <string name="cancel" msgid="6830980399865683324">"අවලංගු කරන්න"</string>
+ <string name="install_dict" msgid="180852772562189365">"ස්ථාපනය"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"අවලංගු කරන්න"</string>
+ <string name="delete_dict" msgid="756853268088330054">"මකන්න"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"ඔබගේ ජංගම උපාංගය මත තෝරාගත් භාෂාවට ලබාගත හැකි ශබ්ද කෝෂයක් ඇත.&lt;br/&gt; අප ඔබගේ ටයිප් කිරීමේ පළපුරුද්ද වැඩි දියුණු කිරීමට <xliff:g id="LANGUAGE">%1$s</xliff:g> ශබ්ද කෝෂය &lt;b&gt;බාගැනීම&lt;/b&gt; නිර්දේශ කරමු.&lt;br/&gt; &lt;br/&gt; 3G හරහා බාගැනීම මිනිත්තුවක් හෝ දෙකක් ගත හැකිය. ඔබට &lt;b&gt;සීමාරහිත දත්ත සැලසුමක්&lt;/b&gt; නොමැති නම් ගාස්තු අදාළ විය හැක.&lt;br/&gt; ඔබට තිබෙන්නේ කුමන දත්ත සැලසුමක්ද යන්න පිළිබඳ විශ්වාසයක් නොමැති නම්, බාගැනීම ස්වයංක්‍රියව ආරම්භ කිරීමට Wi-Fi සම්බන්ධයක් සොයා ගැනීම අප නිර්දේශ කරමු.&lt;br/&gt; &lt;br/&gt; ඉඟිය: ඔබට ඔබගේ ජංගම උපාංගයේ &lt;b&gt;සැකසීම්&lt;/b&gt; මෙනුව තුළ &lt;b&gt;භාෂාව සහ ආදානය&lt;/b&gt; වෙත යාම මගින් ශබ්දකෝෂ බාගැනීමට සහ ඉවත් කිරීමට හැක."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"දැන් බාගන්න (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi හරහා බාගන්න"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g> සඳහා ශබ්දකෝෂයක් ලබාගත හැක"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"සමාලෝචනය කිරීමට සහ බාගැනීමට ඔබන්න"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"බාගැනේ: <xliff:g id="LANGUAGE">%1$s</xliff:g> සඳහා යෝජනා ඉක්මනින් සුදානම් වනු ඇත."</string>
+ <string name="version_text" msgid="2715354215568469385">"අනුවාදය <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"එක් කරන්න"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"ශබ්ද කෝෂය වෙත එක් කරන්න"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"වාක්‍ය ඛණ්ඩය"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"තවත් විකල්ප"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"අඩු විකල්ප"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"හරි"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"වචනය:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"කෙටිමග:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"භාෂාව:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"වචනයක් ටයිප් කරන්න"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"විකල්පමය කෙටිමග"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"වචනය සංස්කරණය කරන්න"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"සංස්කරණය කරන්න"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"මකන්න"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"ඔබට පරිශීලක ශබ්ද කෝෂය තුළ වචන කිසිවක් නැත. එක් කරන්න (+) බොත්තම ස්පර්ශ කිරීම මගින් වචනයක් එක් කරන්න."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"සියලු භාෂාවන් සඳහා"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"තවත් භාෂා…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"මකන්න"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 730b7d813..d067265e3 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -66,7 +66,7 @@
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">10%p</fraction>
<fraction name="emoji_keyboard_row_height">33%p</fraction>
- <fraction name="emoji_keyboard_key_letter_size">95%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">85%p</fraction>
<integer name="emoji_keyboard_max_key_count">30</integer>
</resources>
diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml
index 2bcf2fa84..591355d3c 100644
--- a/java/res/values-sw600dp/dimens.xml
+++ b/java/res/values-sw600dp/dimens.xml
@@ -92,7 +92,7 @@
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">12.5%p</fraction>
<fraction name="emoji_keyboard_row_height">33%p</fraction>
- <fraction name="emoji_keyboard_key_letter_size">85%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">76%p</fraction>
<integer name="emoji_keyboard_max_key_count">24</integer>
</resources>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index 1e2e1c651..664630b4f 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -67,7 +67,7 @@
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">7.69%p</fraction>
<fraction name="emoji_keyboard_row_height">33%p</fraction>
- <fraction name="emoji_keyboard_key_letter_size">75%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">68%p</fraction>
<integer name="emoji_keyboard_max_key_count">39</integer>
</resources>
diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml
index f62a536d7..1fd933abf 100644
--- a/java/res/values-sw768dp/dimens.xml
+++ b/java/res/values-sw768dp/dimens.xml
@@ -92,7 +92,7 @@
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">10%p</fraction>
<fraction name="emoji_keyboard_row_height">33%p</fraction>
- <fraction name="emoji_keyboard_key_letter_size">85%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">76%p</fraction>
<integer name="emoji_keyboard_max_key_count">30</integer>
</resources>
diff --git a/java/res/values-zh-rHK/strings-appname.xml b/java/res/values-zh-rHK/strings-appname.xml
new file mode 100644
index 000000000..8761a98d0
--- /dev/null
+++ b/java/res/values-zh-rHK/strings-appname.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_name" msgid="5940510615957428904">"Android 鍵盤 (AOSP)"</string>
+ <string name="spell_checker_service_name" msgid="1254221805440242662">"Android 拼字檢查工具 (AOSP)"</string>
+ <string name="english_ime_settings" msgid="5760361067176802794">"Android 鍵盤設定 (AOSP)"</string>
+ <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android 拼字檢查工具設定 (AOSP)"</string>
+</resources>
diff --git a/java/res/values-zh-rHK/strings.xml b/java/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000..74be1e453
--- /dev/null
+++ b/java/res/values-zh-rHK/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"輸入選項"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"研究記錄指令"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查找聯絡人姓名"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼字檢查程式使用您的聯絡人名單中的各項記錄"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"按鍵時顯示彈出式視窗"</string>
+ <string name="general_category" msgid="1859088467017573195">"一般設定"</string>
+ <string name="correction_category" msgid="2236750915056607613">"文字更正"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"手勢輸入"</string>
+ <string name="misc_category" msgid="6894192814868233453">"其他選項"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"進階設定"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"專家選項"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"切換至其他輸入法"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"語言切換鍵包括其他輸入法"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"語言切換鍵"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"在啟用多種輸入語言時顯示"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"顯示滑動指示器"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"從 Shift 鍵或符號鍵開始滑動時顯示視覺提示"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"關閉彈出式鍵盤的延遲時間"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"不延遲"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"預設"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> 毫秒"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"系統預設"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人名稱"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用「聯絡人」的名稱提供建議與修正"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"按兩下空格鍵插入句號"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"只要輕按兩下空格鍵,即可插入句號並在後面加上一個空格"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"每句首個字詞大寫"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"個人字典"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"附加字典"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"主要字典"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"顯示更正建議"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"輸入時顯示建議字詞"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"永遠顯示"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"以垂直模式顯示"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"永遠隱藏"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"封鎖令人反感的字詞"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"不建議使用可能令人反感的字詞"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"自動更正"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"自動插入空白鍵和標點符號鍵盤,以修正拼字錯誤"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"關閉"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"普通模式"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"加強模式"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"極度加強模式"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"建議下一個字詞"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"根據前一個字詞提出建議"</string>
+ <string name="gesture_input" msgid="826951152254563827">"啟用手勢輸入"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"透過滑動手指寫出字母來輸入字詞"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"顯示手勢軌跡"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"動態浮動預覽"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"在啟用手勢輸入時顯示建議的字詞"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"開始"</string>
+ <string name="label_next_key" msgid="362972844525672568">"下一步"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"上一步"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"完成"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"發送"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"暫停"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"等候"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"插上耳機即可聽到系統朗讀密碼鍵。"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"目前文字為 %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"未輸入文字"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"按鍵代碼 %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift 鍵"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift 鍵已開啟 (輕按即可停用)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"大寫鎖定已開啟 (輕按即可停用)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"刪除"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"符號"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"字母"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"數字"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"設定"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab 鍵"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"空白鍵"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"語音輸入"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"笑臉"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Return 鍵"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"搜尋"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"點"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"切換語言"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"下一步"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"上一步"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 鍵已啟用"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"大寫鎖定已啟用"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 鍵已停用"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"符號模式"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"字母模式"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"撥號模式"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"符號撥號模式"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"鍵盤已隱藏"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"目前顯示的是<xliff:g id="MODE">%s</xliff:g>鍵盤"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"日期"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"日期和時間"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"電郵"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"短訊"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"數字"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"電話"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"文字"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"時間"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"網址"</string>
+ <string name="voice_input" msgid="3583258583521397548">"語音輸入鍵"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"於主鍵盤"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"符號鍵盤上"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"關閉"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"主鍵盤上的麥克風"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"符號鍵盤上的麥克風"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"語音輸入已停用"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"設定輸入法"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"輸入語言"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"傳送意見"</string>
+ <string name="select_language" msgid="3693815588777926848">"輸入語言"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"再次輕觸即可儲存"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"可使用字典"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"啟用用戶意見反映"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"自動傳送使用統計資料和當機報告,協助改良這個輸入法編輯器"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"英文 (英國)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"英文 (美國)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"西班牙文 (美國)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"英文 (英國) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"英文 (美國) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"西班牙文 (美國) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (傳統)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"無語言 (字母)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"字母 (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"字母 (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"字母 (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"字母 (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"自訂輸入樣式"</string>
+ <string name="add_style" msgid="6163126614514489951">"新增樣式"</string>
+ <string name="add" msgid="8299699805688017798">"新增"</string>
+ <string name="remove" msgid="4486081658752944606">"移除"</string>
+ <string name="save" msgid="7646738597196767214">"儲存"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"語言"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"配置"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"您必須先啟用自訂輸入樣式,才能開始使用。您要立即啟用嗎?"</string>
+ <string name="enable" msgid="5031294444630523247">"啟用"</string>
+ <string name="not_now" msgid="6172462888202790482">"暫時不要"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"已存在相同的輸入樣式:<xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"可用性研究模式"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"長按鍵延遲"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"按鍵震動時間"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"按鍵音量"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"讀取外部字典檔案"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"「下載」資料夾中沒有任何字典檔案"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"選取要安裝的字典檔案"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"準備好要為<xliff:g id="LOCALE_NAME">%s</xliff:g>版本安裝這個檔案嗎?"</string>
+ <string name="error" msgid="8940763624668513648">"發生錯誤"</string>
+ <string name="button_default" msgid="3988017840431881491">"預設"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"歡迎使用「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"配備觸控輸入功能"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"開始"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"下一步"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"設定「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"啟用「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"請在語言與輸入設定中勾選「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」,授權這個應用程式在您的裝置上執行。"</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"您已在 [語言與輸入設定] 中啟用「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」。這個步驟已完成,可繼續下一個步驟了!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"在設定中啟用"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"切換至「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"接著,請選取「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」作為目前使用的文字輸入方法。"</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"切換輸入方法"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"恭喜,一切就緒!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"現在,您可以在所有最愛的應用程式中使用「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」輸入文字。"</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"設定其他語言"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"完成"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"顯示應用程式圖示"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"在啟動器中顯示應用程式圖示"</string>
+ <string name="app_name" msgid="6320102637491234792">"字典供應商"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"字典供應商"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"字典服務"</string>
+ <string name="download_description" msgid="6014835283119198591">"字典更新資訊"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"附加字典"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"可使用字典"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"字典設定"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"用戶字典"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"用戶字典"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"可使用字典"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"目前下載中"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"已安裝"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"已安裝,但已停用"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"連線至字典服務時發生問題"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"沒有可用的字典"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"重新整理"</string>
+ <string name="last_update" msgid="730467549913588780">"上次更新日期"</string>
+ <string name="message_updating" msgid="4457761393932375219">"正在查看更新"</string>
+ <string name="message_loading" msgid="8689096636874758814">"正在載入..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"主要字典"</string>
+ <string name="cancel" msgid="6830980399865683324">"取消"</string>
+ <string name="install_dict" msgid="180852772562189365">"安裝"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"取消"</string>
+ <string name="delete_dict" msgid="756853268088330054">"刪除"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"您的流動裝置所選取的語言現有字典可供使用。&lt;br/&gt;建議您&lt;b&gt;下載&lt;/b&gt;<xliff:g id="LANGUAGE">%1$s</xliff:g>字典,讓您輸入時更方便。&lt;br/&gt;&lt;br/&gt;經由 3G 網絡下載需時一兩分鐘。如果您未使用&lt;b&gt;無限上網計劃&lt;/b&gt;,可能須另外付費。&lt;br/&gt;如果您不確定自己使用哪種上網計劃,建議您在連接 Wi-Fi 網絡後才開始自動下載。&lt;br/&gt;&lt;br/&gt;提示:您可以前往流動裝置的 [設定] &lt;b&gt;&lt;/b&gt;選單,透過其中的 [語言和輸入] &lt;b&gt;&lt;/b&gt;下載和移除字典。"</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"立即下載 (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"經由 Wi-Fi 下載"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"可使用<xliff:g id="LANGUAGE">%1$s</xliff:g>字典"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"按下即可查看並下載"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"下載中:很快就能提供<xliff:g id="LANGUAGE">%1$s</xliff:g>字詞建議。"</string>
+ <string name="version_text" msgid="2715354215568469385">"版本 <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"新增"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"加入字典"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"詞組"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"更多選項"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"較少選項"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"確定"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"字詞:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"快速鍵:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"語言:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"輸入字詞"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"自選快速鍵"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"編輯字詞"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"編輯"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"刪除"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"您的用戶字典中沒有任何字詞。輕觸 [新增] (+) 按鈕即可新增字詞。"</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"所有語言"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"更多語言..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"刪除"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 4e3b2f567..2d626dbcf 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -118,7 +118,7 @@
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">14.2857%p</fraction>
<fraction name="emoji_keyboard_row_height">33%p</fraction>
- <fraction name="emoji_keyboard_key_letter_size">90%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">81%p</fraction>
<integer name="emoji_keyboard_max_key_count">21</integer>
<dimen name="emoji_category_page_id_height">3dp</dimen>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 69da1e862..06f4b4789 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -174,6 +174,11 @@
<!-- Spoken description when there is no text entered -->
<string name="spoken_no_text_entered">No text entered</string>
+ <!-- Spoken description to let the user know what auto-correction will be performed when a key is pressed. -->
+ <string name="spoken_auto_correct"><xliff:g id="key" example="Space">%1$s</xliff:g> corrects <xliff:g id="original">%2$s</xliff:g> to <xliff:g id="corrected">%3$s</xliff:g></string>
+ <!-- Spoken description used during obscured (e.g. password) entry to let the user know that auto-correction will be performed when a key is pressed. -->
+ <string name="spoken_auto_correct_obscured"><xliff:g id="key" example="Space">%1$s</xliff:g> has auto-correction</string>
+
<!-- Spoken description for unknown keyboard keys. -->
<string name="spoken_description_unknown">Key code %d</string>
<!-- Spoken description for the "Shift" keyboard key when "Shift" is off. -->
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 7639432aa..c628c5b09 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -35,6 +35,8 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -285,9 +287,15 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
private String getKeyDescription(final Key key) {
final EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo();
final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo);
- final String keyDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
+ final SettingsValues currentSettings = Settings.getInstance().getCurrent();
+ final String keyCodeDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
mKeyboardView.getContext(), mKeyboardView.getKeyboard(), key, shouldObscure);
- return keyDescription;
+ if (currentSettings.isWordSeparator(key.getCode())) {
+ return mAccessibilityUtils.getAutoCorrectionDescription(
+ keyCodeDescription, shouldObscure);
+ } else {
+ return keyCodeDescription;
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index 8929dc7e9..10fb9fef4 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -23,6 +23,7 @@ import android.os.Build;
import android.os.SystemClock;
import android.provider.Settings;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
+import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -34,6 +35,7 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.SettingsSecureCompatUtils;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.utils.InputTypeUtils;
public final class AccessibilityUtils {
@@ -48,6 +50,12 @@ public final class AccessibilityUtils {
private AccessibilityManager mAccessibilityManager;
private AudioManager mAudioManager;
+ /** The most recent auto-correction. */
+ private String mAutoCorrectionWord;
+
+ /** The most recent typed word for auto-correction. */
+ private String mTypedWord;
+
/*
* Setting this constant to {@code false} will disable all keyboard
* accessibility code, regardless of whether Accessibility is turned on in
@@ -142,6 +150,51 @@ public final class AccessibilityUtils {
}
/**
+ * Sets the current auto-correction word and typed word. These may be used
+ * to provide the user with a spoken description of what auto-correction
+ * will occur when a key is typed.
+ *
+ * @param suggestedWords the list of suggested auto-correction words
+ * @param typedWord the currently typed word
+ */
+ public void setAutoCorrection(final SuggestedWords suggestedWords, final String typedWord) {
+ if (suggestedWords != null && suggestedWords.mWillAutoCorrect) {
+ mAutoCorrectionWord = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
+ mTypedWord = typedWord;
+ } else {
+ mAutoCorrectionWord = null;
+ mTypedWord = null;
+ }
+ }
+
+ /**
+ * Obtains a description for an auto-correction key, taking into account the
+ * currently typed word and auto-correction.
+ *
+ * @param keyCodeDescription spoken description of the key that will insert
+ * an auto-correction
+ * @param shouldObscure whether the key should be obscured
+ * @return a description including a description of the auto-correction, if
+ * needed
+ */
+ public String getAutoCorrectionDescription(
+ final String keyCodeDescription, final boolean shouldObscure) {
+ if (!TextUtils.isEmpty(mAutoCorrectionWord)) {
+ if (!TextUtils.equals(mAutoCorrectionWord, mTypedWord)) {
+ if (shouldObscure) {
+ // This should never happen, but just in case...
+ return mContext.getString(R.string.spoken_auto_correct_obscured,
+ keyCodeDescription);
+ }
+ return mContext.getString(R.string.spoken_auto_correct, keyCodeDescription,
+ mTypedWord, mAutoCorrectionWord);
+ }
+ }
+
+ return keyCodeDescription;
+ }
+
+ /**
* Sends the specified text to the {@link AccessibilityManager} to be
* spoken.
*
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
index 4e61edac2..eb48d01f6 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
@@ -153,7 +153,9 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
mCategoryNameToIdMap.put(sCategoryName[i], i);
}
addShownCategoryId(CATEGORY_ID_RECENTS);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2
+ || android.os.Build.VERSION.CODENAME.equalsIgnoreCase("KeyLimePie")
+ || android.os.Build.VERSION.CODENAME.equalsIgnoreCase("KitKat")) {
addShownCategoryId(CATEGORY_ID_PEOPLE);
addShownCategoryId(CATEGORY_ID_OBJECTS);
addShownCategoryId(CATEGORY_ID_NATURE);
@@ -716,12 +718,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
@Override
public void run() {
+ int repeatCount = 1;
int timeCount = 0;
while (timeCount < MAX_REPEAT_COUNT_TIME && !mAborted) {
if (timeCount > mKeyRepeatStartTimeout) {
- pressDelete();
+ pressDelete(repeatCount);
}
timeCount += mKeyRepeatInterval;
+ ++repeatCount;
try {
Thread.sleep(mKeyRepeatInterval);
} catch (InterruptedException e) {
@@ -734,9 +738,9 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
}
}
- public void pressDelete() {
+ public void pressDelete(int repeatCount) {
mKeyboardActionListener.onPressKey(
- Constants.CODE_DELETE, 0 /* repeatCount */, true /* isSinglePointer */);
+ Constants.CODE_DELETE, repeatCount, true /* isSinglePointer */);
mKeyboardActionListener.onCodeInput(
Constants.CODE_DELETE, NOT_A_COORDINATE, NOT_A_COORDINATE);
mKeyboardActionListener.onReleaseKey(
@@ -752,7 +756,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
v.setBackgroundColor(mDeleteKeyPressedBackgroundColor);
- pressDelete();
+ pressDelete(0 /* repeatCount */);
startRepeat();
return true;
case MotionEvent.ACTION_UP:
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index cc1ffd183..74edd87cf 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -315,7 +315,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
public boolean isShowingEmojiKeyboard() {
- return mEmojiKeyboardView.getVisibility() == View.VISIBLE;
+ return mEmojiKeyboardView != null && mEmojiKeyboardView.getVisibility() == View.VISIBLE;
}
public boolean isShowingMoreKeysPanel() {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index d4d0d8718..ee4ac950c 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -346,6 +346,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// true if this pointer is in a sliding key input from a modifier key,
// so that further modifier keys should be ignored.
boolean mIsInSlidingKeyInputFromModifier;
+ // if not a NOT_A_CODE, the key of this code is repeating
+ private int mCurrentRepeatingKeyCode = Constants.NOT_A_CODE;
// true if a sliding key input is allowed.
private boolean mIsAllowedSlidingKeyInput;
@@ -937,9 +939,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (!sShouldHandleGesture) {
return;
}
- // A gesture should start only from a non-modifier key.
+ // A gesture should start only from a non-modifier key. Note that the gesture detection is
+ // disabled when the key is repeating.
mIsDetectingGesture = (mKeyboard != null) && mKeyboard.mId.isAlphabetKeyboard()
- && key != null && !key.isModifier() && !key.isRepeatable();
+ && key != null && !key.isModifier();
if (mIsDetectingGesture) {
if (getActivePointerTrackerCount() == 1) {
sGestureFirstDownTime = eventTime;
@@ -1247,6 +1250,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mIsDetectingGesture = false;
final Key currentKey = mCurrentKey;
mCurrentKey = null;
+ final int currentRepeatingKeyCode = mCurrentRepeatingKeyCode;
+ mCurrentRepeatingKeyCode = Constants.NOT_A_CODE;
// Release the last pressed key.
setReleasedKeyGraphics(currentKey);
@@ -1272,8 +1277,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (mIsTrackingForActionDisabled) {
return;
}
- if (currentKey != null && currentKey.isRepeatable() && !isInSlidingKeyInput) {
- // Repeatable key has been registered in {@link #onDownEventInternal(int,int,long)}.
+ if (currentKey != null && currentKey.isRepeatable()
+ && (currentKey.getCode() == currentRepeatingKeyCode) && !isInSlidingKeyInput) {
return;
}
detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime);
@@ -1412,7 +1417,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (!key.isRepeatable()) return;
// Don't start key repeat when we are in sliding input mode.
if (mIsInSlidingKeyInput) return;
- detectAndSendKey(key, key.getX(), key.getY(), SystemClock.uptimeMillis());
final int startRepeatCount = 1;
mTimerProxy.startKeyRepeatTimer(this, startRepeatCount, sParams.mKeyRepeatStartTimeout);
}
@@ -1420,8 +1424,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public void onKeyRepeat(final int code, final int repeatCount) {
final Key key = getKey();
if (key == null || key.getCode() != code) {
+ mCurrentRepeatingKeyCode = Constants.NOT_A_CODE;
return;
}
+ mCurrentRepeatingKeyCode = code;
+ mIsDetectingGesture = false;
final int nextRepeatCount = repeatCount + 1;
mTimerProxy.startKeyRepeatTimer(this, nextRepeatCount, sParams.mKeyRepeatInterval);
callListenerOnPressAndCheckKeyboardLayoutChange(key, repeatCount);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index b3491d807..9f9fdaa6f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -585,7 +585,7 @@ public final class KeyboardState {
}
}
- private static boolean isSpaceCharacter(final int c) {
+ private static boolean isSpaceOrEnter(final int c) {
return c == Constants.CODE_SPACE || c == Constants.CODE_ENTER;
}
@@ -614,7 +614,12 @@ public final class KeyboardState {
}
break;
case SWITCH_STATE_SYMBOL_BEGIN:
- if (!isSpaceCharacter(code) && (Constants.isLetterCode(code)
+ if (mIsEmojiMode) {
+ // When in the Emoji keyboard, we don't want to switch back to the main layout even
+ // after the user hits an emoji letter followed by an enter or a space.
+ break;
+ }
+ if (!isSpaceOrEnter(code) && (Constants.isLetterCode(code)
|| code == Constants.CODE_OUTPUT_TEXT)) {
mSwitchState = SWITCH_STATE_SYMBOL;
}
@@ -622,7 +627,7 @@ public final class KeyboardState {
case SWITCH_STATE_SYMBOL:
// Switch back to alpha keyboard mode if user types one or more non-space/enter
// characters followed by a space/enter.
- if (isSpaceCharacter(code)) {
+ if (isSpaceOrEnter(code)) {
toggleAlphabetAndSymbols();
mPrevSymbolsKeyboardWasShifted = false;
}
diff --git a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
index 845a9b987..4a0ce3735 100644
--- a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
@@ -25,6 +25,7 @@ import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
import java.io.File;
import java.io.IOException;
+import java.util.Map;
// TODO: Quit extending Dictionary after implementing dynamic binary dictionary.
abstract public class AbstractDictionaryWriter extends Dictionary {
@@ -50,16 +51,16 @@ abstract public class AbstractDictionaryWriter extends Dictionary {
abstract public void removeBigramWords(final String word0, final String word1);
- abstract protected void writeDictionary(final DictEncoder dictEncoder)
- throws IOException, UnsupportedFormatException;
+ abstract protected void writeDictionary(final DictEncoder dictEncoder,
+ final Map<String, String> attributeMap) throws IOException, UnsupportedFormatException;
- public void write(final String fileName) {
+ public void write(final String fileName, final Map<String, String> attributeMap) {
final String tempFileName = fileName + ".temp";
final File file = new File(mContext.getFilesDir(), fileName);
final File tempFile = new File(mContext.getFilesDir(), tempFileName);
try {
final DictEncoder dictEncoder = new Ver3DictEncoder(tempFile);
- writeDictionary(dictEncoder);
+ writeDictionary(dictEncoder, attributeMap);
tempFile.renameTo(file);
} catch (IOException e) {
Log.e(TAG, "IO exception while writing file", e);
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 61ccfcfad..29c6c0451 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -31,10 +31,12 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
+import java.util.Map;
/**
* Implements a static, compacted, binary dictionary of standard words.
*/
+// TODO: All methods which should be locked need to have a suffix "Locked".
public final class BinaryDictionary extends Dictionary {
private static final String TAG = BinaryDictionary.class.getSimpleName();
@@ -46,6 +48,11 @@ public final class BinaryDictionary extends Dictionary {
// TODO: Remove this heuristic.
private static final int SPACE_COUNT_FOR_AUTO_COMMIT = 3;
+ @UsedForTesting
+ public static final String UNIGRAM_COUNT_QUERY = "UNIGRAM_COUNT";
+ @UsedForTesting
+ public static final String BIGRAM_COUNT_QUERY = "BIGRAM_COUNT";
+
private long mNativeDict;
private final Locale mLocale;
private final long mDictSize;
@@ -103,10 +110,12 @@ public final class BinaryDictionary extends Dictionary {
JniUtils.loadNativeLibrary();
}
+ private static native boolean createEmptyDictFileNative(String filePath, long dictVersion,
+ String[] attributeKeyStringArray, String[] attributeValueStringArray);
private static native long openNative(String sourceDir, long dictOffset, long dictSize,
boolean isUpdatable);
private static native void flushNative(long dict, String filePath);
- private static native boolean needsToRunGCNative(long dict);
+ private static native boolean needsToRunGCNative(long dict, boolean mindsBlockByGC);
private static native void flushWithGCNative(long dict, String filePath);
private static native void closeNative(long dict);
private static native int getProbabilityNative(long dict, int[] word);
@@ -125,6 +134,21 @@ public final class BinaryDictionary extends Dictionary {
private static native void removeBigramWordsNative(long dict, int[] word0, int[] word1);
private static native int calculateProbabilityNative(long dict, int unigramProbability,
int bigramProbability);
+ private static native String getPropertyNative(long dict, String query);
+
+ @UsedForTesting
+ public static boolean createEmptyDictFile(final String filePath, final long dictVersion,
+ final Map<String, String> attributeMap) {
+ final String[] keyArray = new String[attributeMap.size()];
+ final String[] valueArray = new String[attributeMap.size()];
+ int index = 0;
+ for (final String key : attributeMap.keySet()) {
+ keyArray[index] = key;
+ valueArray[index] = attributeMap.get(key);
+ index++;
+ }
+ return createEmptyDictFileNative(filePath, dictVersion, keyArray, valueArray);
+ }
// TODO: Move native dict into session
private final void loadDictionary(final String path, final long startOffset,
@@ -246,7 +270,7 @@ public final class BinaryDictionary extends Dictionary {
}
private void runGCIfRequired() {
- if (needsToRunGCNative(mNativeDict)) {
+ if (needsToRunGC(true /* mindsBlockByGC */)) {
flushWithGC();
}
}
@@ -283,27 +307,34 @@ public final class BinaryDictionary extends Dictionary {
removeBigramWordsNative(mNativeDict, codePoints0, codePoints1);
}
- public void flush() {
- if (!isValidDictionary()) return;
- flushNative(mNativeDict, mDictFilePath);
- closeNative(mNativeDict);
+ private void reopen() {
+ close();
final File dictFile = new File(mDictFilePath);
mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
dictFile.length(), true /* isUpdatable */);
}
+ public void flush() {
+ if (!isValidDictionary()) return;
+ flushNative(mNativeDict, mDictFilePath);
+ reopen();
+ }
+
public void flushWithGC() {
if (!isValidDictionary()) return;
flushWithGCNative(mNativeDict, mDictFilePath);
- closeNative(mNativeDict);
- final File dictFile = new File(mDictFilePath);
- mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
- dictFile.length(), true /* isUpdatable */);
+ reopen();
}
- public boolean needsToRunGC() {
+ /**
+ * Checks whether GC is needed to run or not.
+ * @param mindsBlockByGC Whether to mind operations blocked by GC. We don't need to care about
+ * the blocking in some situations such as in idle time or just before closing.
+ * @return whether GC is needed to run or not.
+ */
+ public boolean needsToRunGC(final boolean mindsBlockByGC) {
if (!isValidDictionary()) return false;
- return needsToRunGCNative(mNativeDict);
+ return needsToRunGCNative(mNativeDict, mindsBlockByGC);
}
@UsedForTesting
@@ -312,6 +343,12 @@ public final class BinaryDictionary extends Dictionary {
return calculateProbabilityNative(mNativeDict, unigramProbability, bigramProbability);
}
+ @UsedForTesting
+ public String getPropertyForTests(String query) {
+ if (!isValidDictionary()) return "";
+ return getPropertyNative(mNativeDict, query);
+ }
+
@Override
public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
// TODO: actually use the confidence rather than use this completely broken heuristic
@@ -338,21 +375,23 @@ public final class BinaryDictionary extends Dictionary {
traverseSession.close();
}
}
+ mDicTraverseSessions.clear();
}
- closeInternal();
+ closeInternalLocked();
}
- private synchronized void closeInternal() {
+ private synchronized void closeInternalLocked() {
if (mNativeDict != 0) {
closeNative(mNativeDict);
mNativeDict = 0;
}
}
+ // TODO: Manage BinaryDictionary instances without using WeakReference or something.
@Override
protected void finalize() throws Throwable {
try {
- closeInternal();
+ closeInternalLocked();
} finally {
super.finalize();
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 3721132c5..828e54f14 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -51,7 +51,7 @@ public final class DictionaryFactory {
if (null == locale) {
Log.e(TAG, "No locale defined for dictionary");
return new DictionaryCollection(Dictionary.TYPE_MAIN,
- createBinaryDictionary(context, locale));
+ createReadOnlyBinaryDictionary(context, locale));
}
final LinkedList<Dictionary> dictList = CollectionUtils.newLinkedList();
@@ -59,11 +59,11 @@ public final class DictionaryFactory {
BinaryDictionaryGetter.getDictionaryFiles(locale, context);
if (null != assetFileList) {
for (final AssetFileAddress f : assetFileList) {
- final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename,
- f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN,
- false /* isUpdatable */);
- if (binaryDictionary.isValidDictionary()) {
- dictList.add(binaryDictionary);
+ final ReadOnlyBinaryDictionary readOnlyBinaryDictionary =
+ new ReadOnlyBinaryDictionary(f.mFilename, f.mOffset, f.mLength,
+ useFullEditDistance, locale, Dictionary.TYPE_MAIN);
+ if (readOnlyBinaryDictionary.isValidDictionary()) {
+ dictList.add(readOnlyBinaryDictionary);
}
}
}
@@ -89,12 +89,12 @@ public final class DictionaryFactory {
}
/**
- * Initializes a dictionary from a raw resource file
+ * Initializes a read-only binary dictionary from a raw resource file
* @param context application context for reading resources
* @param locale the locale to use for the resource
- * @return an initialized instance of BinaryDictionary
+ * @return an initialized instance of ReadOnlyBinaryDictionary
*/
- protected static BinaryDictionary createBinaryDictionary(final Context context,
+ protected static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context,
final Locale locale) {
AssetFileDescriptor afd = null;
try {
@@ -113,9 +113,8 @@ public final class DictionaryFactory {
Log.e(TAG, "sourceDir is not a file: " + sourceDir);
return null;
}
- return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(),
- false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN,
- false /* isUpdatable */);
+ return new ReadOnlyBinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(),
+ false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN);
} catch (android.content.res.Resources.NotFoundException e) {
Log.e(TAG, "Could not find the resource");
return null;
@@ -142,10 +141,10 @@ public final class DictionaryFactory {
final DictionaryCollection dictionaryCollection =
new DictionaryCollection(Dictionary.TYPE_MAIN);
for (final AssetFileAddress address : dictionaryList) {
- final BinaryDictionary binaryDictionary = new BinaryDictionary(address.mFilename,
- address.mOffset, address.mLength, useFullEditDistance, locale,
- Dictionary.TYPE_MAIN, false /* isUpdatable */);
- dictionaryCollection.addDictionary(binaryDictionary);
+ final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(
+ address.mFilename, address.mOffset, address.mLength, useFullEditDistance,
+ locale, Dictionary.TYPE_MAIN);
+ dictionaryCollection.addDictionary(readOnlyBinaryDictionary);
}
return dictionaryCollection;
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryWriter.java b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
index 5a453dde5..84abfa66d 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
@@ -31,6 +31,7 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
/**
* An in memory dictionary for memorizing entries and writing a binary dictionary.
@@ -84,8 +85,11 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
}
@Override
- protected void writeDictionary(final DictEncoder dictEncoder)
- throws IOException, UnsupportedFormatException {
+ protected void writeDictionary(final DictEncoder dictEncoder,
+ final Map<String, String> attributeMap) throws IOException, UnsupportedFormatException {
+ for (final Map.Entry<String, String> entry : attributeMap.entrySet()) {
+ mFusionDictionary.addOptionAttribute(entry.getKey(), entry.getValue());
+ }
dictEncoder.writeDictionary(mFusionDictionary, FORMAT_OPTIONS);
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 183f12ad9..2d1ca51e2 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -22,12 +22,7 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
-import com.android.inputmethod.latin.makedict.DictEncoder;
import com.android.inputmethod.latin.makedict.FormatSpec;
-import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
-import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
import com.android.inputmethod.latin.personalization.DynamicPersonalizationDictionaryWriter;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
@@ -35,9 +30,9 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor;
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -69,8 +64,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
protected static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
- private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
- new FormatSpec.FormatOptions(3 /* version */, true /* supportsDynamicUpdate */);
+ private static final int DICTIONARY_FORMAT_VERSION = 3;
+
+ private static final String SUPPORTS_DYNAMIC_UPDATE =
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE;
/**
* A static map of update controllers, each of which records the time of accesses to a single
@@ -235,6 +232,14 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
});
}
+ protected Map<String, String> getHeaderAttributeMap() {
+ HashMap<String, String> attributeMap = new HashMap<String, String>();
+ attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
+ SUPPORTS_DYNAMIC_UPDATE);
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mFilename);
+ return attributeMap;
+ }
+
protected void clear() {
getExecutor(mFilename).execute(new Runnable() {
@Override
@@ -242,17 +247,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE && mDictionaryWriter == null) {
mBinaryDictionary.close();
final File file = new File(mContext.getFilesDir(), mFilename);
- final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>(),
- false, false));
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- try {
- dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
- } catch (IOException e) {
- Log.e(TAG, "Exception in creating new dictionary file.", e);
- } catch (UnsupportedFormatException e) {
- Log.e(TAG, "Exception in creating new dictionary file.", e);
- }
+ BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
+ DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap());
} else {
mDictionaryWriter.clear();
}
@@ -501,31 +497,22 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (needsToReloadBeforeWriting()) {
mDictionaryWriter.clear();
loadDictionaryAsync();
- mDictionaryWriter.write(mFilename);
+ mDictionaryWriter.write(mFilename, getHeaderAttributeMap());
} else {
if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
if (mBinaryDictionary == null || !mBinaryDictionary.isValidDictionary()) {
final File file = new File(mContext.getFilesDir(), mFilename);
- final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>(),
- false, false));
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- try {
- dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
- } catch (IOException e) {
- Log.e(TAG, "Exception in creating new dictionary file.", e);
- } catch (UnsupportedFormatException e) {
- Log.e(TAG, "Exception in creating new dictionary file.", e);
- }
+ BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
+ DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap());
} else {
- if (mBinaryDictionary.needsToRunGC()) {
+ if (mBinaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
mBinaryDictionary.flushWithGC();
} else {
mBinaryDictionary.flush();
}
}
} else {
- mDictionaryWriter.write(mFilename);
+ mDictionaryWriter.write(mFilename, getHeaderAttributeMap());
}
}
}
@@ -674,47 +661,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
}
- /**
- * Dynamically adds a word unigram to the dictionary for testing with blocking-lock.
- */
- @UsedForTesting
- protected void addWordDynamicallyForTests(final String word, final String shortcutTarget,
- final int frequency, final boolean isNotAWord) {
- getExecutor(mFilename).executePrioritized(new Runnable() {
- @Override
- public void run() {
- addWordDynamically(word, shortcutTarget, frequency, isNotAWord);
- }
- });
- }
-
- /**
- * Dynamically adds a word bigram in the dictionary for testing with blocking-lock.
- */
- @UsedForTesting
- protected void addBigramDynamicallyForTests(final String word0, final String word1,
- final int frequency, final boolean isValid) {
- getExecutor(mFilename).executePrioritized(new Runnable() {
- @Override
- public void run() {
- addBigramDynamically(word0, word1, frequency, isValid);
- }
- });
- }
-
- /**
- * Dynamically remove a word bigram in the dictionary for testing with blocking-lock.
- */
- @UsedForTesting
- protected void removeBigramDynamicallyForTests(final String word0, final String word1) {
- getExecutor(mFilename).executePrioritized(new Runnable() {
- @Override
- public void run() {
- removeBigramDynamically(word0, word1);
- }
- });
- }
-
// TODO: Implement native binary methods once the dynamic dictionary implementation is done.
@UsedForTesting
public boolean isInDictionaryForTests(final String word) {
@@ -727,7 +673,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
holder.set(mBinaryDictionary.isValidWord(word));
} else {
holder.set(((DynamicPersonalizationDictionaryWriter) mDictionaryWriter)
- .isInDictionaryForTests(word));
+ .isInBigramListForTests(word));
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index 21b103e5a..8caf6f17f 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -103,6 +103,10 @@ public final class InputAttributes {
}
}
+ public boolean isTypeNull() {
+ return InputType.TYPE_NULL == mInputType;
+ }
+
public boolean isSameInputType(final EditorInfo editorInfo) {
return editorInfo.inputType == mInputType;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 270dc4c06..96e16de0d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -81,7 +81,7 @@ import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.PersonalizationPredictionDictionary;
-import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
+import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsActivity;
import com.android.inputmethod.latin.settings.SettingsValues;
@@ -179,7 +179,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mIsMainDictionaryAvailable;
private UserBinaryDictionary mUserDictionary;
- private UserHistoryPredictionDictionary mUserHistoryPredictionDictionary;
+ private UserHistoryDictionary mUserHistoryDictionary;
private PersonalizationPredictionDictionary mPersonalizationPredictionDictionary;
private PersonalizationDictionary mPersonalizationDictionary;
private boolean mIsUserDictionaryAvailable;
@@ -623,9 +623,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- mUserHistoryPredictionDictionary = PersonalizationHelper
- .getUserHistoryPredictionDictionary(this, localeStr, prefs);
- newSuggest.setUserHistoryPredictionDictionary(mUserHistoryPredictionDictionary);
+ mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary(
+ this, localeStr, prefs);
+ newSuggest.setUserHistoryDictionary(mUserHistoryDictionary);
mPersonalizationDictionary = PersonalizationHelper
.getPersonalizationDictionary(this, localeStr, prefs);
newSuggest.setPersonalizationDictionary(mPersonalizationDictionary);
@@ -1521,7 +1521,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeState.switchSubtype(token, mRichImm);
}
- private void sendDownUpKeyEventForBackwardCompatibility(final int code) {
+ private void sendDownUpKeyEvent(final int code) {
final long eventTime = SystemClock.uptimeMillis();
mConnection.sendKeyEvent(new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, code, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
@@ -1538,7 +1538,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (code >= '0' && code <= '9') {
- sendDownUpKeyEventForBackwardCompatibility(code - '0' + KeyEvent.KEYCODE_0);
+ sendDownUpKeyEvent(code - '0' + KeyEvent.KEYCODE_0);
return;
}
@@ -1547,7 +1547,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// a hardware keyboard event on pressing enter or delete. This is bad for many
// reasons (there are race conditions with commits) but some applications are
// relying on this behavior so we continue to support it for older apps.
- sendDownUpKeyEventForBackwardCompatibility(KeyEvent.KEYCODE_ENTER);
+ sendDownUpKeyEvent(KeyEvent.KEYCODE_ENTER);
} else {
final String text = new String(new int[] { code }, 0, 1);
mConnection.commitText(text, text.length());
@@ -2104,12 +2104,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
final int lengthToDelete = Character.isSupplementaryCodePoint(
mConnection.getCodePointBeforeCursor()) ? 2 : 1;
- if (mAppWorkAroundsUtils.isBeforeJellyBean()) {
- // Backward compatibility mode. Before Jelly bean, the keyboard would simulate
- // a hardware keyboard event on pressing enter or delete. This is bad for many
- // reasons (there are race conditions with commits) but some applications are
- // relying on this behavior so we continue to support it for older apps.
- sendDownUpKeyEventForBackwardCompatibility(KeyEvent.KEYCODE_DEL);
+ if (mAppWorkAroundsUtils.isBeforeJellyBean() ||
+ currentSettings.mInputAttributes.isTypeNull()) {
+ // There are two possible reasons to send a key event: either the field has
+ // type TYPE_NULL, in which case the keyboard should send events, or we are
+ // running in backward compatibility mode. Before Jelly bean, the keyboard
+ // would simulate a hardware keyboard event on pressing enter or delete. This
+ // is bad for many reasons (there are race conditions with commits) but some
+ // applications are relying on this behavior so we continue to support it for
+ // older apps, so we retain this behavior if the app has target SDK < JellyBean.
+ sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
} else {
mConnection.deleteSurroundingText(lengthToDelete, 0);
}
@@ -2553,6 +2557,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
final String typedWord) {
if (suggestedWords.isEmpty()) {
+ // No auto-correction is available, clear the cached values.
+ AccessibilityUtils.getInstance().setAutoCorrection(null, null);
clearSuggestionStrip();
return;
}
@@ -2561,6 +2567,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setSuggestedWords(suggestedWords, isAutoCorrection);
setAutoCorrectionIndicator(isAutoCorrection);
setSuggestionStripShown(isSuggestionsStripVisible());
+ // An auto-correction is available, cache it in accessibility code so
+ // we can be speak it if the user touches a key that will insert it.
+ AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, typedWord);
}
private void showSuggestionStrip(final SuggestedWords suggestedWords) {
@@ -2746,9 +2755,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SettingsValues currentSettings = mSettings.getCurrent();
if (!currentSettings.mCorrectionEnabled) return null;
- final UserHistoryPredictionDictionary userHistoryPredictionDictionary =
- mUserHistoryPredictionDictionary;
- if (userHistoryPredictionDictionary == null) return null;
+ final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary;
+ if (userHistoryDictionary == null) return null;
final String prevWord = mConnection.getNthPreviousWord(currentSettings.mWordSeparators, 2);
final String secondWord;
@@ -2762,8 +2770,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int maxFreq = AutoCorrectionUtils.getMaxFrequency(
suggest.getUnigramDictionaries(), suggestion);
if (maxFreq == 0) return null;
- userHistoryPredictionDictionary
- .addToPersonalizationPredictionDictionary(prevWord, secondWord, maxFreq > 0);
+ userHistoryDictionary.addToDictionary(prevWord, secondWord, maxFreq > 0);
return prevWord;
}
@@ -2949,7 +2956,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mConnection.deleteSurroundingText(deleteLength, 0);
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
- mUserHistoryPredictionDictionary.cancelAddingUserHistory(previousWord, committedWord);
+ mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
}
final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
if (mSettings.getCurrent().mCurrentLanguageHasSpaces) {
diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
new file mode 100644
index 000000000..68505ce38
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * This class provides binary dictionary reading operations with locking. An instance of this class
+ * can be used by multiple threads. Note that different session IDs must be used when multiple
+ * threads get suggestions using this class.
+ */
+public final class ReadOnlyBinaryDictionary extends Dictionary {
+ /**
+ * A lock for accessing binary dictionary. Only closing binary dictionary is the operation
+ * that change the state of dictionary.
+ */
+ private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
+
+ private final BinaryDictionary mBinaryDictionary;
+
+ public ReadOnlyBinaryDictionary(final String filename, final long offset, final long length,
+ final boolean useFullEditDistance, final Locale locale, final String dictType) {
+ super(dictType);
+ mBinaryDictionary = new BinaryDictionary(filename, offset, length, useFullEditDistance,
+ locale, dictType, false /* isUpdatable */);
+ }
+
+ public boolean isValidDictionary() {
+ return mBinaryDictionary.isValidDictionary();
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, 0 /* sessionId */);
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId) {
+ if (mLock.readLock().tryLock()) {
+ try {
+ return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions);
+ } finally {
+ mLock.readLock().unlock();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ if (mLock.readLock().tryLock()) {
+ try {
+ return mBinaryDictionary.isValidWord(word);
+ } finally {
+ mLock.readLock().unlock();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
+ if (mLock.readLock().tryLock()) {
+ try {
+ return mBinaryDictionary.shouldAutoCommit(candidate);
+ } finally {
+ mLock.readLock().unlock();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int getFrequency(final String word) {
+ if (mLock.readLock().tryLock()) {
+ try {
+ return mBinaryDictionary.getFrequency(word);
+ } finally {
+ mLock.readLock().unlock();
+ }
+ }
+ return NOT_A_PROBABILITY;
+ }
+
+ @Override
+ public void close() {
+ mLock.writeLock().lock();
+ try {
+ mBinaryDictionary.close();
+ } finally {
+ mLock.writeLock().unlock();
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 925381b50..8580a6e54 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -30,6 +30,7 @@ import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.DebugLogUtils;
+import com.android.inputmethod.latin.utils.SpannableStringUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.latin.utils.TextRange;
import com.android.inputmethod.research.ResearchLogger;
@@ -610,8 +611,9 @@ public final class RichInputConnection {
// We don't use TextUtils#concat because it copies all spans without respect to their
// nature. If the text includes a PARAGRAPH span and it has been split, then
// TextUtils#concat will crash when it tries to concat both sides of it.
- return new TextRange(StringUtils.concatWithNonParagraphSuggestionSpansOnly(before, after),
- startIndexInBefore, before.length() + endIndexInAfter, before.length());
+ return new TextRange(
+ SpannableStringUtils.concatWithNonParagraphSuggestionSpansOnly(before, after),
+ startIndexInBefore, before.length() + endIndexInAfter, before.length());
}
public boolean isCursorTouchingWord(final SettingsValues settingsValues) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 6c18c948f..9fd1f53a2 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -26,7 +26,7 @@ import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationPredictionDictionary;
-import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
+import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.BoundedTreeSet;
@@ -190,10 +190,8 @@ public final class Suggest {
addOrReplaceDictionaryInternal(Dictionary.TYPE_CONTACTS, contactsDictionary);
}
- public void setUserHistoryPredictionDictionary(
- final UserHistoryPredictionDictionary userHistoryPredictionDictionary) {
- addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY,
- userHistoryPredictionDictionary);
+ public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) {
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY, userHistoryDictionary);
}
public void setPersonalizationPredictionDictionary(
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 4dba8e5cf..af61f2979 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -225,6 +225,26 @@ public class BinaryDictEncoderUtils {
return position;
}
+ static void writeUIntToStream(final OutputStream stream, final int value, final int size)
+ throws IOException {
+ switch(size) {
+ case 4:
+ stream.write((value >> 24) & 0xFF);
+ /* fall through */
+ case 3:
+ stream.write((value >> 16) & 0xFF);
+ /* fall through */
+ case 2:
+ stream.write((value >> 8) & 0xFF);
+ /* fall through */
+ case 1:
+ stream.write(value & 0xFF);
+ break;
+ default:
+ /* nop */
+ }
+ }
+
// End utility methods
// This method is responsible for finding a nice ordering of the nodes that favors run-time
@@ -365,12 +385,14 @@ public class BinaryDictEncoderUtils {
nodeSize + size, ptNode.mChildren));
}
nodeSize += getShortcutListSize(ptNode.mShortcutTargets);
- if (null != ptNode.mBigrams) {
- for (WeightedString bigram : ptNode.mBigrams) {
- final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray,
- nodeSize + size + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE,
- FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord));
- nodeSize += getByteSize(offset) + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
+ if (formatOptions.mVersion < FormatSpec.FIRST_VERSION_WITH_TERMINAL_ID) {
+ if (null != ptNode.mBigrams) {
+ for (WeightedString bigram : ptNode.mBigrams) {
+ final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray,
+ nodeSize + size + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE,
+ FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord));
+ nodeSize += getByteSize(offset) + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
+ }
}
}
ptNode.mCachedSize = nodeSize;
@@ -882,8 +904,9 @@ public class BinaryDictEncoderUtils {
* @param destination the stream to write the file header to.
* @param dict the dictionary to write.
* @param formatOptions file format options.
+ * @return the size of the header.
*/
- /* package */ static void writeDictionaryHeader(final OutputStream destination,
+ /* package */ static int writeDictionaryHeader(final OutputStream destination,
final FusionDictionary dict, final FormatOptions formatOptions)
throws IOException, UnsupportedFormatException {
final int version = formatOptions.mVersion;
@@ -932,5 +955,6 @@ public class BinaryDictEncoderUtils {
destination.write(bytes);
headerBuffer.close();
+ return size;
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java
index bf3d19101..411e265b3 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java
@@ -77,7 +77,7 @@ public final class DynamicBinaryDictIOUtils {
* @param newParentAddress the absolute address of the parent.
* @param formatOptions file format options.
*/
- public static void updateParentAddress(final DictBuffer dictBuffer,
+ private static void updateParentAddress(final DictBuffer dictBuffer,
final int ptNodeOriginAddress, final int newParentAddress,
final FormatOptions formatOptions) {
final int originalPosition = dictBuffer.position();
@@ -109,7 +109,7 @@ public final class DynamicBinaryDictIOUtils {
* @param newParentAddress the address to be written.
* @param formatOptions file format options.
*/
- public static void updateParentAddresses(final DictBuffer dictBuffer,
+ private static void updateParentAddresses(final DictBuffer dictBuffer,
final int ptNodeOriginAddress, final int newParentAddress,
final FormatOptions formatOptions) {
final int originalPosition = dictBuffer.position();
@@ -136,7 +136,7 @@ public final class DynamicBinaryDictIOUtils {
* @param newChildrenAddress the absolute address of the child.
* @param formatOptions file format options.
*/
- public static void updateChildrenAddress(final DictBuffer dictBuffer,
+ private static void updateChildrenAddress(final DictBuffer dictBuffer,
final int ptNodeOriginAddress, final int newChildrenAddress,
final FormatOptions formatOptions) {
final int originalPosition = dictBuffer.position();
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 51b89a02a..9481a8c14 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -263,7 +263,14 @@ public final class FormatSpec {
// These values are used only by version 4 or later.
static final String TRIE_FILE_EXTENSION = ".trie";
static final String FREQ_FILE_EXTENSION = ".freq";
+ // tat = Terminal Address Table
+ static final String TERMINAL_ADDRESS_TABLE_FILE_EXTENSION = ".tat";
+ static final String BIGRAM_FILE_EXTENSION = ".bigram";
+ static final String BIGRAM_LOOKUP_TABLE_FILE_EXTENSION = ".bigram_lookup";
+ static final String BIGRAM_ADDRESS_TABLE_FILE_EXTENSION = ".bigram_index";
static final int FREQUENCY_AND_FLAGS_SIZE = 2;
+ static final int TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE = 3;
+ static final int BIGRAM_ADDRESS_TABLE_BLOCK_SIZE = 4;
static final int NO_CHILDREN_ADDRESS = Integer.MIN_VALUE;
static final int NO_PARENT_ADDRESS = 0;
@@ -322,9 +329,15 @@ public final class FormatSpec {
public final int mHeaderSize;
public final DictionaryOptions mDictionaryOptions;
public final FormatOptions mFormatOptions;
- private static final String DICTIONARY_VERSION_ATTRIBUTE = "version";
- private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
- private static final String DICTIONARY_ID_ATTRIBUTE = "dictionary";
+ // Note that these are corresponding definitions in native code in latinime::HeaderPolicy
+ // and latinime::HeaderReadWriteUtils.
+ public static final String SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE = "SUPPORTS_DYNAMIC_UPDATE";
+ public static final String USES_FORGETTING_CURVE_ATTRIBUTE = "USES_FORGETTING_CURVE";
+ public static final String ATTRIBUTE_VALUE_TRUE = "1";
+
+ public static final String DICTIONARY_VERSION_ATTRIBUTE = "version";
+ public static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
+ public static final String DICTIONARY_ID_ATTRIBUTE = "dictionary";
private static final String DICTIONARY_DESCRIPTION_ATTRIBUTE = "description";
public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
final FormatOptions formatOptions) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/SparseTable.java b/java/src/com/android/inputmethod/latin/makedict/SparseTable.java
new file mode 100644
index 000000000..96d057a44
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/SparseTable.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * SparseTable is an extensible map from integer to integer.
+ * This holds one value for every mBlockSize keys, so it uses 1/mBlockSize'th of the full index
+ * memory.
+ */
+@UsedForTesting
+public class SparseTable {
+
+ /**
+ * mLookupTable is indexed by terminal ID, containing exactly one entry for every mBlockSize
+ * terminals.
+ * It contains at index i = j / mBlockSize the index in mContentsTable where the values for
+ * terminals with IDs j to j + mBlockSize - 1 are stored as an mBlockSize-sized integer array.
+ */
+ private final ArrayList<Integer> mLookupTable;
+ private final ArrayList<Integer> mContentTable;
+
+ private final int mBlockSize;
+ public static final int NOT_EXIST = -1;
+
+ @UsedForTesting
+ public SparseTable(final int initialCapacity, final int blockSize) {
+ mBlockSize = blockSize;
+ final int lookupTableSize = initialCapacity / mBlockSize
+ + (initialCapacity % mBlockSize > 0 ? 1 : 0);
+ mLookupTable = new ArrayList<Integer>(Collections.nCopies(lookupTableSize, NOT_EXIST));
+ mContentTable = new ArrayList<Integer>();
+ }
+
+ @UsedForTesting
+ public SparseTable(final int[] lookupTable, final int[] contentTable, final int blockSize) {
+ mBlockSize = blockSize;
+ mLookupTable = new ArrayList<Integer>(lookupTable.length);
+ for (int i = 0; i < lookupTable.length; ++i) {
+ mLookupTable.add(lookupTable[i]);
+ }
+ mContentTable = new ArrayList<Integer>(contentTable.length);
+ for (int i = 0; i < contentTable.length; ++i) {
+ mContentTable.add(contentTable[i]);
+ }
+ }
+
+ /**
+ * Converts an byte array to an int array considering each set of 4 bytes is an int stored in
+ * big-endian.
+ * The length of byteArray must be a multiple of four.
+ * Otherwise, IndexOutOfBoundsException will be raised.
+ */
+ @UsedForTesting
+ private static void convertByteArrayToIntegerArray(final byte[] byteArray,
+ final ArrayList<Integer> integerArray) {
+ for (int i = 0; i < byteArray.length; i += 4) {
+ int value = 0;
+ for (int j = i; j < i + 4; ++j) {
+ value <<= 8;
+ value |= byteArray[j] & 0xFF;
+ }
+ integerArray.add(value);
+ }
+ }
+
+ @UsedForTesting
+ public SparseTable(final byte[] lookupTable, final byte[] contentTable, final int blockSize) {
+ mBlockSize = blockSize;
+ mLookupTable = new ArrayList<Integer>(lookupTable.length / 4);
+ mContentTable = new ArrayList<Integer>(contentTable.length / 4);
+ convertByteArrayToIntegerArray(lookupTable, mLookupTable);
+ convertByteArrayToIntegerArray(contentTable, mContentTable);
+ }
+
+ @UsedForTesting
+ public int get(final int index) {
+ if (index < 0 || index / mBlockSize >= mLookupTable.size()
+ || mLookupTable.get(index / mBlockSize) == NOT_EXIST) {
+ return NOT_EXIST;
+ }
+ return mContentTable.get(mLookupTable.get(index / mBlockSize) + (index % mBlockSize));
+ }
+
+ @UsedForTesting
+ public void set(final int index, final int value) {
+ if (mLookupTable.get(index / mBlockSize) == NOT_EXIST) {
+ mLookupTable.set(index / mBlockSize, mContentTable.size());
+ for (int i = 0; i < mBlockSize; ++i) {
+ mContentTable.add(NOT_EXIST);
+ }
+ }
+ mContentTable.set(mLookupTable.get(index / mBlockSize) + (index % mBlockSize), value);
+ }
+
+ public void remove(final int index) {
+ set(index, NOT_EXIST);
+ }
+
+ @UsedForTesting
+ public int size() {
+ return mLookupTable.size() * mBlockSize;
+ }
+
+ @UsedForTesting
+ /* package */ int getContentTableSize() {
+ return mContentTable.size();
+ }
+
+ @UsedForTesting
+ /* package */ int getLookupTableSize() {
+ return mLookupTable.size();
+ }
+
+ public boolean contains(final int index) {
+ return get(index) != NOT_EXIST;
+ }
+
+ @UsedForTesting
+ public void write(final OutputStream lookupOutStream, final OutputStream contentOutStream)
+ throws IOException {
+ for (final int index : mLookupTable) {
+ BinaryDictEncoderUtils.writeUIntToStream(lookupOutStream, index, 4);
+ }
+
+ for (final int index : mContentTable) {
+ BinaryDictEncoderUtils.writeUIntToStream(contentOutStream, index, 4);
+ }
+ }
+
+ @UsedForTesting
+ public void writeToFiles(final File lookupTableFile, final File contentFile)
+ throws IOException {
+ FileOutputStream lookupTableOutStream = null;
+ FileOutputStream contentOutStream = null;
+ try {
+ lookupTableOutStream = new FileOutputStream(lookupTableFile);
+ contentOutStream = new FileOutputStream(contentFile);
+ write(lookupTableOutStream, contentOutStream);
+ } finally {
+ if (lookupTableOutStream != null) {
+ lookupTableOutStream.close();
+ }
+ if (contentOutStream != null) {
+ contentOutStream.close();
+ }
+ }
+ }
+
+ private static byte[] readFileToByteArray(final File file) throws IOException {
+ final byte[] contents = new byte[(int) file.length()];
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(file);
+ inStream.read(contents);
+ } finally {
+ if (inStream != null) {
+ inStream.close();
+ }
+ }
+ return contents;
+ }
+
+ @UsedForTesting
+ public static SparseTable readFromFiles(final File lookupTableFile, final File contentFile,
+ final int blockSize) throws IOException {
+ final byte[] lookupTable = readFileToByteArray(lookupTableFile);
+ final byte[] content = readFileToByteArray(contentFile);
+ return new SparseTable(lookupTable, content, blockSize);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
index 36c5a2720..0aa431966 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -41,11 +41,16 @@ public class Ver4DictDecoder extends DictDecoder {
private static final int FILETYPE_TRIE = 1;
private static final int FILETYPE_FREQUENCY = 2;
+ private static final int FILETYPE_TERMINAL_ADDRESS_TABLE = 3;
+ private static final int FILETYPE_BIGRAM = 4;
private final File mDictDirectory;
private final DictionaryBufferFactory mBufferFactory;
private DictBuffer mDictBuffer;
private DictBuffer mFrequencyBuffer;
+ private DictBuffer mTerminalAddressTableBuffer;
+ private DictBuffer mBigramBuffer;
+ private SparseTable mBigramAddressTable;
@UsedForTesting
/* package */ Ver4DictDecoder(final File dictDirectory, final int factoryFlag) {
@@ -77,6 +82,12 @@ public class Ver4DictDecoder extends DictDecoder {
} else if (fileType == FILETYPE_FREQUENCY) {
return new File(mDictDirectory,
mDictDirectory.getName() + FormatSpec.FREQ_FILE_EXTENSION);
+ } else if (fileType == FILETYPE_TERMINAL_ADDRESS_TABLE) {
+ return new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
+ } else if (fileType == FILETYPE_BIGRAM) {
+ return new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.BIGRAM_FILE_EXTENSION);
} else {
throw new RuntimeException("Unsupported kind of file : " + fileType);
}
@@ -87,6 +98,10 @@ public class Ver4DictDecoder extends DictDecoder {
final String filename = mDictDirectory.getName();
mDictBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_TRIE));
mFrequencyBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_FREQUENCY));
+ mTerminalAddressTableBuffer = mBufferFactory.getDictionaryBuffer(
+ getFile(FILETYPE_TERMINAL_ADDRESS_TABLE));
+ mBigramBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_BIGRAM));
+ loadBigramAddressSparseTable();
}
@Override
@@ -111,6 +126,15 @@ public class Ver4DictDecoder extends DictDecoder {
return header;
}
+ private void loadBigramAddressSparseTable() throws IOException {
+ final File lookupIndexFile = new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.BIGRAM_LOOKUP_TABLE_FILE_EXTENSION);
+ final File contentFile = new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.BIGRAM_ADDRESS_TABLE_FILE_EXTENSION);
+ mBigramAddressTable = SparseTable.readFromFiles(lookupIndexFile, contentFile,
+ FormatSpec.BIGRAM_ADDRESS_TABLE_BLOCK_SIZE);
+ }
+
protected static class PtNodeReader extends DictDecoder.PtNodeReader {
protected static int readFrequency(final DictBuffer frequencyBuffer, final int terminalId) {
frequencyBuffer.position(terminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE + 1);
@@ -184,8 +208,21 @@ public class Ver4DictDecoder extends DictDecoder {
final ArrayList<PendingAttribute> bigrams;
if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
bigrams = new ArrayList<PendingAttribute>();
- addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams,
- addressPointer);
+ final int posOfBigrams = mBigramAddressTable.get(terminalId);
+ mBigramBuffer.position(posOfBigrams);
+ while (bigrams.size() < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ // If bigrams.size() reaches FormatSpec.MAX_BIGRAMS_IN_A_PTNODE,
+ // remaining bigram entries are ignored.
+ final int bigramFlags = mBigramBuffer.readUnsignedByte();
+ final int targetTerminalId = mBigramBuffer.readUnsignedInt24();
+ mTerminalAddressTableBuffer.position(
+ targetTerminalId * FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE);
+ final int targetAddress = mTerminalAddressTableBuffer.readUnsignedInt24();
+ bigrams.add(new PendingAttribute(
+ bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY,
+ targetAddress));
+ if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
+ }
if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
MakedictLog.d("too many bigrams in a node.");
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
index 75b75ae2e..4c25faf88 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
@@ -26,6 +26,7 @@ import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -41,10 +42,15 @@ import java.util.Iterator;
public class Ver4DictEncoder implements DictEncoder {
private final File mDictPlacedDir;
private byte[] mTrieBuf;
- private byte[] mFreqBuf;
private int mTriePos;
+ private int mHeaderSize;
+ private SparseTable mBigramAddressTable;
private OutputStream mTrieOutStream;
private OutputStream mFreqOutStream;
+ private OutputStream mTerminalAddressTableOutStream;
+ private OutputStream mBigramOutStream;
+ private File mDictDir;
+ private String mBaseFilename;
@UsedForTesting
public Ver4DictEncoder(final File dictPlacedDir) {
@@ -54,18 +60,25 @@ public class Ver4DictEncoder implements DictEncoder {
private void openStreams(final FormatOptions formatOptions, final DictionaryOptions dictOptions)
throws FileNotFoundException, IOException {
final FileHeader header = new FileHeader(0, dictOptions, formatOptions);
- final String filename = header.getId() + "." + header.getVersion();
- final File mDictDir = new File(mDictPlacedDir, filename);
- final File trieFile = new File(mDictDir, filename + FormatSpec.TRIE_FILE_EXTENSION);
- final File freqFile = new File(mDictDir, filename + FormatSpec.FREQ_FILE_EXTENSION);
+ mBaseFilename = header.getId() + "." + header.getVersion();
+ mDictDir = new File(mDictPlacedDir, mBaseFilename);
+ final File trieFile = new File(mDictDir, mBaseFilename + FormatSpec.TRIE_FILE_EXTENSION);
+ final File freqFile = new File(mDictDir, mBaseFilename + FormatSpec.FREQ_FILE_EXTENSION);
+ final File terminalAddressTableFile = new File(mDictDir,
+ mBaseFilename + FormatSpec.TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
+ final File bigramFile = new File(mDictDir,
+ mBaseFilename + FormatSpec.BIGRAM_FILE_EXTENSION);
if (!mDictDir.isDirectory()) {
if (mDictDir.exists()) mDictDir.delete();
mDictDir.mkdirs();
}
if (!trieFile.exists()) trieFile.createNewFile();
if (!freqFile.exists()) freqFile.createNewFile();
+ if (!terminalAddressTableFile.exists()) terminalAddressTableFile.createNewFile();
mTrieOutStream = new FileOutputStream(trieFile);
mFreqOutStream = new FileOutputStream(freqFile);
+ mTerminalAddressTableOutStream = new FileOutputStream(terminalAddressTableFile);
+ mBigramOutStream = new FileOutputStream(bigramFile);
}
private void close() throws IOException {
@@ -76,9 +89,17 @@ public class Ver4DictEncoder implements DictEncoder {
if (mFreqOutStream != null) {
mFreqOutStream.close();
}
+ if (mTerminalAddressTableOutStream != null) {
+ mTerminalAddressTableOutStream.close();
+ }
+ if (mBigramOutStream != null) {
+ mBigramOutStream.close();
+ }
} finally {
mTrieOutStream = null;
mFreqOutStream = null;
+ mTerminalAddressTableOutStream = null;
+ mBigramOutStream = null;
}
}
@@ -97,7 +118,8 @@ public class Ver4DictEncoder implements DictEncoder {
openStreams(formatOptions, dict.mOptions);
}
- BinaryDictEncoderUtils.writeDictionaryHeader(mTrieOutStream, dict, formatOptions);
+ mHeaderSize = BinaryDictEncoderUtils.writeDictionaryHeader(mTrieOutStream, dict,
+ formatOptions);
MakedictLog.i("Flattening the tree...");
ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray);
@@ -112,10 +134,15 @@ public class Ver4DictEncoder implements DictEncoder {
BinaryDictEncoderUtils.computeAddresses(dict, flatNodes, formatOptions);
if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes);
+ writeTerminalData(flatNodes, terminalCount);
+ mBigramAddressTable = new SparseTable(terminalCount,
+ FormatSpec.BIGRAM_ADDRESS_TABLE_BLOCK_SIZE);
+ writeBigrams(flatNodes, dict);
+ writeBigramAddressSparseTable();
+
final PtNodeArray lastNodeArray = flatNodes.get(flatNodes.size() - 1);
final int bufferSize = lastNodeArray.mCachedAddressAfterUpdate + lastNodeArray.mCachedSize;
mTrieBuf = new byte[bufferSize];
- mFreqBuf = new byte[terminalCount * FormatSpec.FREQUENCY_AND_FLAGS_SIZE];
MakedictLog.i("Writing file...");
for (PtNodeArray nodeArray : flatNodes) {
@@ -126,7 +153,6 @@ public class Ver4DictEncoder implements DictEncoder {
MakedictLog.i("has " + terminalCount + " terminals.");
}
mTrieOutStream.write(mTrieBuf);
- mFreqOutStream.write(mFreqBuf);
MakedictLog.i("Done");
close();
@@ -185,12 +211,6 @@ public class Ver4DictEncoder implements DictEncoder {
FormatSpec.PTNODE_TERMINAL_ID_SIZE);
}
- private void writeFrequency(final int frequency, final int terminalId) {
- final int freqPos = terminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE;
- BinaryDictEncoderUtils.writeUIntToBuffer(mFreqBuf, freqPos, frequency,
- FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
- }
-
private void writeChildrenPosition(PtNode ptNode, FormatOptions formatOptions) {
final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
if (formatOptions.mSupportsDynamicUpdate) {
@@ -226,24 +246,41 @@ public class Ver4DictEncoder implements DictEncoder {
shortcutByteSize, FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE);
}
- private void writeBigrams(ArrayList<WeightedString> bigrams, FusionDictionary dict) {
- if (bigrams == null) return;
-
- final Iterator<WeightedString> bigramIterator = bigrams.iterator();
- while (bigramIterator.hasNext()) {
- final WeightedString bigram = bigramIterator.next();
- final PtNode target =
- FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord);
- final int addressOfBigram = target.mCachedAddressAfterUpdate;
- final int unigramFrequencyForThisWord = target.mFrequency;
- final int offset = addressOfBigram
- - (mTriePos + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
- int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(),
- offset, bigram.mFrequency, unigramFrequencyForThisWord, bigram.mWord);
- mTrieBuf[mTriePos++] = (byte) bigramFlags;
- mTriePos += BinaryDictEncoderUtils.writeChildrenPosition(mTrieBuf,
- mTriePos, Math.abs(offset));
+ private void writeBigrams(final ArrayList<PtNodeArray> flatNodes, final FusionDictionary dict)
+ throws IOException {
+ final ByteArrayOutputStream bigramBuffer = new ByteArrayOutputStream();
+
+ for (final PtNodeArray nodeArray : flatNodes) {
+ for (final PtNode ptNode : nodeArray.mData) {
+ if (ptNode.mBigrams != null) {
+ final int startPos = bigramBuffer.size();
+ mBigramAddressTable.set(ptNode.mTerminalId, startPos);
+ final Iterator<WeightedString> bigramIterator = ptNode.mBigrams.iterator();
+ while (bigramIterator.hasNext()) {
+ final WeightedString bigram = bigramIterator.next();
+ final PtNode target =
+ FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord);
+ final int unigramFrequencyForThisWord = target.mFrequency;
+ final int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(
+ bigramIterator.hasNext(), 0, bigram.mFrequency,
+ unigramFrequencyForThisWord, bigram.mWord);
+ BinaryDictEncoderUtils.writeUIntToStream(bigramBuffer, bigramFlags,
+ FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
+ BinaryDictEncoderUtils.writeUIntToStream(bigramBuffer, target.mTerminalId,
+ FormatSpec.PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE);
+ }
+ }
+ }
}
+ bigramBuffer.writeTo(mBigramOutStream);
+ }
+
+ private void writeBigramAddressSparseTable() throws IOException {
+ final File lookupIndexFile =
+ new File(mDictDir, mBaseFilename + FormatSpec.BIGRAM_LOOKUP_TABLE_FILE_EXTENSION);
+ final File contentFile =
+ new File(mDictDir, mBaseFilename + FormatSpec.BIGRAM_ADDRESS_TABLE_FILE_EXTENSION);
+ mBigramAddressTable.writeToFiles(lookupIndexFile, contentFile);
}
@Override
@@ -260,10 +297,30 @@ public class Ver4DictEncoder implements DictEncoder {
writeCharacters(ptNode.mChars, ptNode.hasSeveralChars());
if (ptNode.isTerminal()) {
writeTerminalId(ptNode.mTerminalId);
- writeFrequency(ptNode.mFrequency, ptNode.mTerminalId);
}
writeChildrenPosition(ptNode, formatOptions);
writeShortcuts(ptNode.mShortcutTargets);
- writeBigrams(ptNode.mBigrams, dict);
+ }
+
+ private void writeTerminalData(final ArrayList<PtNodeArray> flatNodes,
+ final int terminalCount) throws IOException {
+ final byte[] freqBuf = new byte[terminalCount * FormatSpec.FREQUENCY_AND_FLAGS_SIZE];
+ final byte[] terminalAddressTableBuf =
+ new byte[terminalCount * FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE];
+ for (final PtNodeArray nodeArray : flatNodes) {
+ for (final PtNode ptNode : nodeArray.mData) {
+ if (ptNode.isTerminal()) {
+ BinaryDictEncoderUtils.writeUIntToBuffer(freqBuf,
+ ptNode.mTerminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE,
+ ptNode.mFrequency, FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
+ BinaryDictEncoderUtils.writeUIntToBuffer(terminalAddressTableBuf,
+ ptNode.mTerminalId * FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE,
+ ptNode.mCachedAddressAfterUpdate + mHeaderSize,
+ FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE);
+ }
+ }
+ }
+ mFreqOutStream.write(freqBuf);
+ mTerminalAddressTableOutStream.write(terminalAddressTableBuf);
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index 075d7e3c3..7cf4f0c88 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -22,6 +22,7 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.makedict.DictDecoder;
@@ -34,12 +35,15 @@ import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListe
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
/**
- * This class is a base class of a dictionary for the personalized prediction language model.
+ * This class is a base class of a dictionary that supports decaying for the personalized language
+ * model.
*/
-public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDictionary {
- private static final String TAG = DynamicPredictionDictionaryBase.class.getSimpleName();
+public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableBinaryDictionary {
+ private static final String TAG = DecayingExpandableBinaryDictionaryBase.class.getSimpleName();
public static final boolean DBG_SAVE_RESTORE = false;
private static final boolean DBG_STRESS_TEST = false;
private static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG;
@@ -47,6 +51,9 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
/** Any pair being typed or picked */
public static final int FREQUENCY_FOR_TYPED = 2;
+ public static final int FREQUENCY_FOR_WORDS_IN_DICTS = FREQUENCY_FOR_TYPED;
+ public static final int FREQUENCY_FOR_WORDS_NOT_IN_DICTS = Dictionary.NOT_A_PROBABILITY;
+
/** Locale for which this user history dictionary is storing words */
private final String mLocale;
@@ -60,8 +67,9 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
// Should always be false except when we use this class for test
@UsedForTesting boolean mIsTest = false;
- /* package */ DynamicPredictionDictionaryBase(final Context context, final String locale,
- final SharedPreferences sp, final String dictionaryType, final String fileName) {
+ /* package */ DecayingExpandableBinaryDictionaryBase(final Context context,
+ final String locale, final SharedPreferences sp, final String dictionaryType,
+ final String fileName) {
super(context, fileName, dictionaryType, true);
mLocale = locale;
mFileName = fileName;
@@ -84,6 +92,18 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
}
@Override
+ protected Map<String, String> getHeaderAttributeMap() {
+ HashMap<String, String> attributeMap = new HashMap<String, String>();
+ attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
+ attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_ATTRIBUTE,
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mFileName);
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale);
+ return attributeMap;
+ }
+
+ @Override
protected boolean hasContentChanged() {
return false;
}
@@ -103,27 +123,29 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
}
/**
- * Pair will be added to the personalization prediction dictionary.
+ * Pair will be added to the decaying dictionary.
*
* The first word may be null. That means we don't know the context, in other words,
* it's only a unigram. The first word may also be an empty string : this means start
* context, as in beginning of a sentence for example.
* The second word may not be null (a NullPointerException would be thrown).
*/
- public void addToPersonalizationPredictionDictionary(
- final String word0, final String word1, final boolean isValid) {
+ public void addToDictionary(final String word0, final String word1, final boolean isValid) {
if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
(word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
return;
}
- addWordDynamically(word1, null /* the "shortcut" parameter is null */, FREQUENCY_FOR_TYPED,
+ final int frequency = ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE ?
+ (isValid ? FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS) :
+ FREQUENCY_FOR_TYPED;
+ addWordDynamically(word1, null /* the "shortcut" parameter is null */, frequency,
false /* isNotAWord */);
// Do not insert a word as a bigram of itself
if (word1.equals(word0)) {
return;
}
if (null != word0) {
- addBigramDynamically(word0, word1, FREQUENCY_FOR_TYPED, isValid);
+ addBigramDynamically(word0, word1, frequency, isValid);
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
index 0af028a9e..039b25337 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
@@ -36,6 +36,7 @@ import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils.Forge
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Map;
// Currently this class is used to implement dynamic prodiction dictionary.
// TODO: Move to native code.
@@ -79,7 +80,7 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
public void addUnigramWord(final String word, final String shortcutTarget, final int frequency,
final boolean isNotAWord) {
if (mBigramList.size() > mMaxHistoryBigrams * 2) {
- // Too many entries: just stop adding new vocabrary and wait next refresh.
+ // Too many entries: just stop adding new vocabulary and wait next refresh.
return;
}
mExpandableDictionary.addWord(word, shortcutTarget, frequency);
@@ -90,7 +91,7 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
public void addBigramWords(final String word0, final String word1, final int frequency,
final boolean isValid, final long lastModifiedTime) {
if (mBigramList.size() > mMaxHistoryBigrams * 2) {
- // Too many entries: just stop adding new vocabrary and wait next refresh.
+ // Too many entries: just stop adding new vocabulary and wait next refresh.
return;
}
if (lastModifiedTime > 0) {
@@ -113,8 +114,8 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
}
@Override
- protected void writeDictionary(final DictEncoder dictEncoder)
- throws IOException, UnsupportedFormatException {
+ protected void writeDictionary(final DictEncoder dictEncoder,
+ final Map<String, String> attributeMap) throws IOException, UnsupportedFormatException {
UserHistoryDictIOUtils.writeDictionary(dictEncoder,
new FrequencyProvider(mBigramList, mExpandableDictionary, mMaxHistoryBigrams),
mBigramList, FORMAT_OPTIONS);
@@ -176,8 +177,8 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
}
@UsedForTesting
- public boolean isInDictionaryForTests(final String word) {
+ public boolean isInBigramListForTests(final String word) {
// TODO: Use native method to determine whether the word is in dictionary or not
- return mBigramList.containsKey(word);
+ return mBigramList.containsKey(word) || mBigramList.getBigrams(null).containsKey(word);
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java
index ab3de801c..a86f6e584 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java
@@ -46,7 +46,7 @@ public abstract class PersonalizationDictionaryUpdateSession {
// TODO: Use a dynamic binary dictionary instead
public WeakReference<PersonalizationDictionary> mDictionary;
- public WeakReference<DynamicPredictionDictionaryBase> mPredictionDictionary;
+ public WeakReference<DecayingExpandableBinaryDictionaryBase> mPredictionDictionary;
public final String mSystemLocale;
public PersonalizationDictionaryUpdateSession(String locale) {
mSystemLocale = locale;
@@ -60,15 +60,16 @@ public abstract class PersonalizationDictionaryUpdateSession {
mDictionary = new WeakReference<PersonalizationDictionary>(dictionary);
}
- public void setPredictionDictionary(DynamicPredictionDictionaryBase dictionary) {
- mPredictionDictionary = new WeakReference<DynamicPredictionDictionaryBase>(dictionary);
+ public void setPredictionDictionary(DecayingExpandableBinaryDictionaryBase dictionary) {
+ mPredictionDictionary =
+ new WeakReference<DecayingExpandableBinaryDictionaryBase>(dictionary);
}
protected PersonalizationDictionary getDictionary() {
return mDictionary == null ? null : mDictionary.get();
}
- protected DynamicPredictionDictionaryBase getPredictionDictionary() {
+ protected DecayingExpandableBinaryDictionaryBase getPredictionDictionary() {
return mPredictionDictionary == null ? null : mPredictionDictionary.get();
}
@@ -81,7 +82,7 @@ public abstract class PersonalizationDictionaryUpdateSession {
}
private void unsetPredictionDictionary() {
- final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ final DecayingExpandableBinaryDictionaryBase dictionary = getPredictionDictionary();
if (dictionary == null) {
return;
}
@@ -89,7 +90,7 @@ public abstract class PersonalizationDictionaryUpdateSession {
}
public void clearAndFlushPredictionDictionary(Context context) {
- final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ final DecayingExpandableBinaryDictionaryBase dictionary = getPredictionDictionary();
if (dictionary == null) {
return;
}
@@ -105,24 +106,23 @@ public abstract class PersonalizationDictionaryUpdateSession {
// TODO: Support multi locale to add bigram
public void addBigramToPersonalizationDictionary(String word0, String word1, boolean isValid,
int frequency) {
- final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ final DecayingExpandableBinaryDictionaryBase dictionary = getPredictionDictionary();
if (dictionary == null) {
return;
}
- dictionary.addToPersonalizationPredictionDictionary(word0, word1, isValid);
+ dictionary.addToDictionary(word0, word1, isValid);
}
// Bulk import
// TODO: Support multi locale to add bigram
public void addBigramsToPersonalizationDictionary(
final ArrayList<PersonalizationLanguageModelParam> lmParams) {
- final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ final DecayingExpandableBinaryDictionaryBase dictionary = getPredictionDictionary();
if (dictionary == null) {
return;
}
for (final PersonalizationLanguageModelParam lmParam : lmParams) {
- dictionary.addToPersonalizationPredictionDictionary(
- lmParam.mWord0, lmParam.mWord1, lmParam.mIsValid);
+ dictionary.addToDictionary(lmParam.mWord0, lmParam.mWord1, lmParam.mIsValid);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index 5f702ee3f..8c9484b12 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -30,7 +30,7 @@ public class PersonalizationHelper {
private static final String TAG = PersonalizationHelper.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final ConcurrentHashMap<String, SoftReference<UserHistoryPredictionDictionary>>
+ private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>>
sLangUserHistoryDictCache = CollectionUtils.newConcurrentHashMap();
private static final ConcurrentHashMap<String, SoftReference<PersonalizationDictionary>>
@@ -41,25 +41,23 @@ public class PersonalizationHelper {
sLangPersonalizationPredictionDictCache =
CollectionUtils.newConcurrentHashMap();
- public static UserHistoryPredictionDictionary getUserHistoryPredictionDictionary(
+ public static UserHistoryDictionary getUserHistoryDictionary(
final Context context, final String locale, final SharedPreferences sp) {
synchronized (sLangUserHistoryDictCache) {
if (sLangUserHistoryDictCache.containsKey(locale)) {
- final SoftReference<UserHistoryPredictionDictionary> ref =
+ final SoftReference<UserHistoryDictionary> ref =
sLangUserHistoryDictCache.get(locale);
- final UserHistoryPredictionDictionary dict = ref == null ? null : ref.get();
+ final UserHistoryDictionary dict = ref == null ? null : ref.get();
if (dict != null) {
if (DEBUG) {
- Log.w(TAG, "Use cached UserHistoryPredictionDictionary for " + locale);
+ Log.w(TAG, "Use cached UserHistoryDictionary for " + locale);
}
dict.reloadDictionaryIfRequired();
return dict;
}
}
- final UserHistoryPredictionDictionary dict =
- new UserHistoryPredictionDictionary(context, locale, sp);
- sLangUserHistoryDictCache.put(
- locale, new SoftReference<UserHistoryPredictionDictionary>(dict));
+ final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale, sp);
+ sLangUserHistoryDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict));
return dict;
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
index e80953c05..432954453 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
@@ -22,7 +22,7 @@ import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import android.content.Context;
import android.content.SharedPreferences;
-public class PersonalizationPredictionDictionary extends DynamicPredictionDictionaryBase {
+public class PersonalizationPredictionDictionary extends DecayingExpandableBinaryDictionaryBase {
private static final String NAME = PersonalizationPredictionDictionary.class.getSimpleName();
/* package */ PersonalizationPredictionDictionary(final Context context, final String locale,
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index b140c919b..a60226d7e 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -26,10 +26,10 @@ import android.content.SharedPreferences;
* Locally gathers stats about the words user types and various other signals like auto-correction
* cancellation or manual picks. This allows the keyboard to adapt to the typist over time.
*/
-public class UserHistoryPredictionDictionary extends DynamicPredictionDictionaryBase {
+public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase {
/* package for tests */ static final String NAME =
- UserHistoryPredictionDictionary.class.getSimpleName();
- /* package */ UserHistoryPredictionDictionary(final Context context, final String locale,
+ UserHistoryDictionary.class.getSimpleName();
+ /* package */ UserHistoryDictionary(final Context context, final String locale,
final SharedPreferences sp) {
super(context, locale, sp, Dictionary.TYPE_USER_HISTORY, getDictionaryFileName(locale));
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
index 4c1803bdf..55a90ee51 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
@@ -54,7 +54,7 @@ public final class UserHistoryDictionaryBigramList {
* Called when loaded from the SQL DB.
*/
public void addBigram(String word1, String word2, byte fcValue) {
- if (DynamicPredictionDictionaryBase.DBG_SAVE_RESTORE) {
+ if (DecayingExpandableBinaryDictionaryBase.DBG_SAVE_RESTORE) {
Log.d(TAG, "--- add bigram: " + word1 + ", " + word2 + ", " + fcValue);
}
final HashMap<String, Byte> map;
@@ -74,7 +74,7 @@ public final class UserHistoryDictionaryBigramList {
* Called when inserted to the SQL DB.
*/
public void updateBigram(String word1, String word2, byte fcValue) {
- if (DynamicPredictionDictionaryBase.DBG_SAVE_RESTORE) {
+ if (DecayingExpandableBinaryDictionaryBase.DBG_SAVE_RESTORE) {
Log.d(TAG, "--- update bigram: " + word1 + ", " + word2 + ", " + fcValue);
}
final HashMap<String, Byte> map;
diff --git a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
index 5dc0b5893..201a70d42 100644
--- a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
+++ b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
@@ -16,8 +16,11 @@
package com.android.inputmethod.latin.utils;
-import java.util.ArrayDeque;
import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
/**
* An object that executes submitted tasks using a thread.
@@ -27,19 +30,20 @@ public class PrioritizedSerialExecutor {
private final Object mLock = new Object();
- // The default value of capacities of task queues.
- private static final int TASK_QUEUE_CAPACITY = 1000;
private final Queue<Runnable> mTasks;
private final Queue<Runnable> mPrioritizedTasks;
private boolean mIsShutdown;
+ private final ThreadPoolExecutor mThreadPoolExecutor;
// The task which is running now.
private Runnable mActive;
public PrioritizedSerialExecutor() {
- mTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY);
- mPrioritizedTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY);
+ mTasks = new ConcurrentLinkedQueue<Runnable>();
+ mPrioritizedTasks = new ConcurrentLinkedQueue<Runnable>();
mIsShutdown = false;
+ mThreadPoolExecutor = new ThreadPoolExecutor(1 /* corePoolSize */, 1 /* maximumPoolSize */,
+ 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
}
/**
@@ -59,7 +63,16 @@ public class PrioritizedSerialExecutor {
public void execute(final Runnable r) {
synchronized(mLock) {
if (!mIsShutdown) {
- mTasks.offer(r);
+ mTasks.offer(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
if (mActive == null) {
scheduleNext();
}
@@ -74,45 +87,36 @@ public class PrioritizedSerialExecutor {
public void executePrioritized(final Runnable r) {
synchronized(mLock) {
if (!mIsShutdown) {
- mPrioritizedTasks.offer(r);
- if (mActive == null) {
+ mPrioritizedTasks.offer(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
+ if (mActive == null) {
scheduleNext();
}
}
}
}
- private boolean fetchNextTasks() {
- synchronized(mLock) {
- mActive = mPrioritizedTasks.poll();
- if (mActive == null) {
- mActive = mTasks.poll();
- }
- return mActive != null;
+ private boolean fetchNextTasksLocked() {
+ mActive = mPrioritizedTasks.poll();
+ if (mActive == null) {
+ mActive = mTasks.poll();
}
+ return mActive != null;
}
private void scheduleNext() {
synchronized(mLock) {
- if (!fetchNextTasks()) {
- return;
+ if (fetchNextTasksLocked()) {
+ mThreadPoolExecutor.execute(mActive);
}
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- do {
- synchronized(mLock) {
- if (mActive != null) {
- mActive.run();
- }
- }
- } while (fetchNextTasks());
- } finally {
- scheduleNext();
- }
- }
- }).start();
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SpannableStringUtils.java b/java/src/com/android/inputmethod/latin/utils/SpannableStringUtils.java
new file mode 100644
index 000000000..b51fd9377
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/SpannableStringUtils.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.SpannedString;
+import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
+
+public final class SpannableStringUtils {
+ /**
+ * Copies the spans from the region <code>start...end</code> in
+ * <code>source</code> to the region
+ * <code>destoff...destoff+end-start</code> in <code>dest</code>.
+ * Spans in <code>source</code> that begin before <code>start</code>
+ * or end after <code>end</code> but overlap this range are trimmed
+ * as if they began at <code>start</code> or ended at <code>end</code>.
+ * Only SuggestionSpans that don't have the SPAN_PARAGRAPH span are copied.
+ *
+ * This code is almost entirely taken from {@link TextUtils#copySpansFrom}, except for the
+ * kind of span that is copied.
+ *
+ * @throws IndexOutOfBoundsException if any of the copied spans
+ * are out of range in <code>dest</code>.
+ */
+ public static void copyNonParagraphSuggestionSpansFrom(Spanned source, int start, int end,
+ Spannable dest, int destoff) {
+ Object[] spans = source.getSpans(start, end, SuggestionSpan.class);
+
+ for (int i = 0; i < spans.length; i++) {
+ int fl = source.getSpanFlags(spans[i]);
+ if (0 != (fl & Spannable.SPAN_PARAGRAPH)) continue;
+
+ int st = source.getSpanStart(spans[i]);
+ int en = source.getSpanEnd(spans[i]);
+
+ if (st < start)
+ st = start;
+ if (en > end)
+ en = end;
+
+ dest.setSpan(spans[i], st - start + destoff, en - start + destoff,
+ fl);
+ }
+ }
+
+ /**
+ * Returns a CharSequence concatenating the specified CharSequences, retaining their
+ * SuggestionSpans that don't have the PARAGRAPH flag, but not other spans.
+ *
+ * This code is almost entirely taken from {@link TextUtils#concat(CharSequence...)}, except
+ * it calls copyNonParagraphSuggestionSpansFrom instead of {@link TextUtils#copySpansFrom}.
+ */
+ public static CharSequence concatWithNonParagraphSuggestionSpansOnly(CharSequence... text) {
+ if (text.length == 0) {
+ return "";
+ }
+
+ if (text.length == 1) {
+ return text[0];
+ }
+
+ boolean spanned = false;
+ for (int i = 0; i < text.length; i++) {
+ if (text[i] instanceof Spanned) {
+ spanned = true;
+ break;
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < text.length; i++) {
+ sb.append(text[i]);
+ }
+
+ if (!spanned) {
+ return sb.toString();
+ }
+
+ SpannableString ss = new SpannableString(sb);
+ int off = 0;
+ for (int i = 0; i < text.length; i++) {
+ int len = text[i].length();
+
+ if (text[i] instanceof Spanned) {
+ copyNonParagraphSuggestionSpansFrom((Spanned) text[i], 0, len, ss, off);
+ }
+
+ off += len;
+ }
+
+ return new SpannedString(ss);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index 327780ad0..121aecf0f 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -20,12 +20,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.settings.SettingsValues;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.SpannedString;
import android.text.TextUtils;
-import android.text.style.SuggestionSpan;
import android.util.JsonReader;
import android.util.JsonWriter;
import android.util.Log;
@@ -467,88 +462,4 @@ public final class StringUtils {
}
return "";
}
-
- /**
- * Copies the spans from the region <code>start...end</code> in
- * <code>source</code> to the region
- * <code>destoff...destoff+end-start</code> in <code>dest</code>.
- * Spans in <code>source</code> that begin before <code>start</code>
- * or end after <code>end</code> but overlap this range are trimmed
- * as if they began at <code>start</code> or ended at <code>end</code>.
- * Only SuggestionSpans that don't have the SPAN_PARAGRAPH span are copied.
- *
- * This code is almost entirely taken from {@link TextUtils#copySpansFrom}, except for the
- * kind of span that is copied.
- *
- * @throws IndexOutOfBoundsException if any of the copied spans
- * are out of range in <code>dest</code>.
- */
- public static void copyNonParagraphSuggestionSpansFrom(Spanned source, int start, int end,
- Spannable dest, int destoff) {
- Object[] spans = source.getSpans(start, end, SuggestionSpan.class);
-
- for (int i = 0; i < spans.length; i++) {
- int fl = source.getSpanFlags(spans[i]);
- if (0 != (fl & Spannable.SPAN_PARAGRAPH)) continue;
-
- int st = source.getSpanStart(spans[i]);
- int en = source.getSpanEnd(spans[i]);
-
- if (st < start)
- st = start;
- if (en > end)
- en = end;
-
- dest.setSpan(spans[i], st - start + destoff, en - start + destoff,
- fl);
- }
- }
-
- /**
- * Returns a CharSequence concatenating the specified CharSequences, retaining their
- * SuggestionSpans that don't have the PARAGRAPH flag, but not other spans.
- *
- * This code is almost entirely taken from {@link TextUtils#concat(CharSequence...)}, except
- * it calls copyNonParagraphSuggestionSpansFrom instead of {@link TextUtils#copySpansFrom}.
- */
- public static CharSequence concatWithNonParagraphSuggestionSpansOnly(CharSequence... text) {
- if (text.length == 0) {
- return "";
- }
-
- if (text.length == 1) {
- return text[0];
- }
-
- boolean spanned = false;
- for (int i = 0; i < text.length; i++) {
- if (text[i] instanceof Spanned) {
- spanned = true;
- break;
- }
- }
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < text.length; i++) {
- sb.append(text[i]);
- }
-
- if (!spanned) {
- return sb.toString();
- }
-
- SpannableString ss = new SpannableString(sb);
- int off = 0;
- for (int i = 0; i < text.length; i++) {
- int len = text[i].length();
-
- if (text[i] instanceof Spanned) {
- copyNonParagraphSuggestionSpansFrom((Spanned) text[i], 0, len, ss, off);
- }
-
- off += len;
- }
-
- return new SpannedString(ss);
- }
}
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index c2070327e..36afea54b 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -85,6 +85,8 @@ LATIN_IME_CORE_SRC_FILES := \
$(addprefix suggest/policyimpl/dictionary/utils/, \
buffer_with_extendable_buffer.cpp \
byte_array_utils.cpp \
+ decaying_utils.cpp \
+ dict_file_writing_utils.cpp \
format_utils.cpp) \
suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp \
$(addprefix suggest/policyimpl/typing/, \
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 7f47493b2..c5ef264fc 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -26,12 +26,55 @@
#include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/suggest_options.h"
#include "suggest/policyimpl/dictionary/dictionary_structure_with_buffer_policy_factory.h"
+#include "suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h"
#include "utils/autocorrection_threshold_utils.h"
namespace latinime {
class ProximityInfo;
+// TODO: Move to makedict.
+static jboolean latinime_BinaryDictionary_createEmptyDictFile(JNIEnv *env, jclass clazz,
+ jstring filePath, jlong dictVersion, jobjectArray attributeKeyStringArray,
+ jobjectArray attributeValueStringArray) {
+ const jsize filePathUtf8Length = env->GetStringUTFLength(filePath);
+ char filePathChars[filePathUtf8Length + 1];
+ env->GetStringUTFRegion(filePath, 0, env->GetStringLength(filePath), filePathChars);
+ filePathChars[filePathUtf8Length] = '\0';
+
+ const int keyCount = env->GetArrayLength(attributeKeyStringArray);
+ const int valueCount = env->GetArrayLength(attributeValueStringArray);
+ if (keyCount != valueCount) {
+ return false;
+ }
+
+ HeaderReadWriteUtils::AttributeMap attributeMap;
+ for (int i = 0; i < keyCount; i++) {
+ jstring keyString = static_cast<jstring>(
+ env->GetObjectArrayElement(attributeKeyStringArray, i));
+ const jsize keyUtf8Length = env->GetStringUTFLength(keyString);
+ char keyChars[keyUtf8Length + 1];
+ env->GetStringUTFRegion(keyString, 0, env->GetStringLength(keyString), keyChars);
+ keyChars[keyUtf8Length] = '\0';
+ HeaderReadWriteUtils::AttributeMap::key_type key;
+ HeaderReadWriteUtils::insertCharactersIntoVector(keyChars, &key);
+
+ jstring valueString = static_cast<jstring>(
+ env->GetObjectArrayElement(attributeValueStringArray, i));
+ const jsize valueUtf8Length = env->GetStringUTFLength(valueString);
+ char valueChars[valueUtf8Length + 1];
+ env->GetStringUTFRegion(valueString, 0, env->GetStringLength(valueString), valueChars);
+ valueChars[valueUtf8Length] = '\0';
+ HeaderReadWriteUtils::AttributeMap::mapped_type value;
+ HeaderReadWriteUtils::insertCharactersIntoVector(valueChars, &value);
+
+ attributeMap[key] = value;
+ }
+
+ return DictFileWritingUtils::createEmptyDictFile(filePathChars, static_cast<int>(dictVersion),
+ &attributeMap);
+}
+
static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring sourceDir,
jlong dictOffset, jlong dictSize, jboolean isUpdatable) {
PROF_OPEN;
@@ -70,10 +113,10 @@ static void latinime_BinaryDictionary_flush(JNIEnv *env, jclass clazz, jlong dic
}
static bool latinime_BinaryDictionary_needsToRunGC(JNIEnv *env, jclass clazz,
- jlong dict) {
+ jlong dict, jboolean mindsBlockByGC) {
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) return false;
- return dictionary->needsToRunGC();
+ return dictionary->needsToRunGC(mindsBlockByGC == JNI_TRUE);
}
static void latinime_BinaryDictionary_flushWithGC(JNIEnv *env, jclass clazz, jlong dict,
@@ -280,8 +323,31 @@ static int latinime_BinaryDictionary_calculateProbabilityNative(JNIEnv *env, jcl
bigramProbability);
}
+static jstring latinime_BinaryDictionary_getProperty(JNIEnv *env, jclass clazz, jlong dict,
+ jstring query) {
+ Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
+ if (!dictionary) {
+ return env->NewStringUTF("");
+ }
+ const jsize queryUtf8Length = env->GetStringUTFLength(query);
+ char queryChars[queryUtf8Length + 1];
+ env->GetStringUTFRegion(query, 0, env->GetStringLength(query), queryChars);
+ queryChars[queryUtf8Length] = '\0';
+ static const int GET_PROPERTY_RESULT_LENGTH = 100;
+ char resultChars[GET_PROPERTY_RESULT_LENGTH];
+ resultChars[0] = '\0';
+ dictionary->getDictionaryStructurePolicy()->getProperty(queryChars, resultChars,
+ GET_PROPERTY_RESULT_LENGTH);
+ return env->NewStringUTF(resultChars);
+}
+
static const JNINativeMethod sMethods[] = {
{
+ const_cast<char *>("createEmptyDictFileNative"),
+ const_cast<char *>("(Ljava/lang/String;J[Ljava/lang/String;[Ljava/lang/String;)Z"),
+ reinterpret_cast<void *>(latinime_BinaryDictionary_createEmptyDictFile)
+ },
+ {
const_cast<char *>("openNative"),
const_cast<char *>("(Ljava/lang/String;JJZ)J"),
reinterpret_cast<void *>(latinime_BinaryDictionary_open)
@@ -298,7 +364,7 @@ static const JNINativeMethod sMethods[] = {
},
{
const_cast<char *>("needsToRunGCNative"),
- const_cast<char *>("(J)Z"),
+ const_cast<char *>("(JZ)Z"),
reinterpret_cast<void *>(latinime_BinaryDictionary_needsToRunGC)
},
{
@@ -350,6 +416,11 @@ static const JNINativeMethod sMethods[] = {
const_cast<char *>("calculateProbabilityNative"),
const_cast<char *>("(JII)I"),
reinterpret_cast<void *>(latinime_BinaryDictionary_calculateProbabilityNative)
+ },
+ {
+ const_cast<char *>("getPropertyNative"),
+ const_cast<char *>("(JLjava/lang/String;)Ljava/lang/String;"),
+ reinterpret_cast<void *>(latinime_BinaryDictionary_getProperty)
}
};
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 89dfa39b3..c2aa8ba0e 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -375,7 +375,7 @@ typedef enum {
CT_TERMINAL,
CT_TERMINAL_INSERTION,
// Create new word with space omission
- CT_NEW_WORD_SPACE_OMITTION,
+ CT_NEW_WORD_SPACE_OMISSION,
// Create new word with space substitution
CT_NEW_WORD_SPACE_SUBSTITUTION,
} CorrectionType;
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h
index 41ef9d2b2..9099e8285 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node.h
@@ -38,10 +38,10 @@
INTS_TO_CHARS(mDicNodeState.mDicNodeStatePrevWord.mPrevWord, \
mDicNodeState.mDicNodeStatePrevWord.getPrevWordLength(), prevWordCharBuf, \
NELEMS(prevWordCharBuf)); \
- AKLOGI("#%8s, %5f, %5f, %5f, %5f, %s, %s, %d,,", header, \
+ AKLOGI("#%8s, %5f, %5f, %5f, %5f, %s, %s, %d, %5f,", header, \
getSpatialDistanceForScoring(), getLanguageDistanceForScoring(), \
getNormalizedCompoundDistance(), getRawLength(), prevWordCharBuf, charBuf, \
- getInputIndex(0)); \
+ getInputIndex(0), getNormalizedCompoundDistanceAfterFirstWord()); \
} while (0)
#else
#define LOGI_SHOW_ADD_COST_PROP
@@ -434,6 +434,13 @@ class DicNode {
return mDicNodeState.mDicNodeStateScoring.getLanguageDistance();
}
+ // For space-aware gestures, we store the normalized distance at the char index
+ // that ends the first word of the suggestion. We call this the distance after
+ // first word.
+ float getNormalizedCompoundDistanceAfterFirstWord() const {
+ return mDicNodeState.mDicNodeStateScoring.getNormalizedCompoundDistanceAfterFirstWord();
+ }
+
float getLanguageDistanceRatePerWordForScoring() const {
const float langDist = getLanguageDistanceForScoring();
const float totalWordCount =
@@ -565,6 +572,12 @@ class DicNode {
inputSize, getTotalInputIndex(), errorType);
}
+ // Saves the current normalized compound distance for space-aware gestures.
+ // See getNormalizedCompoundDistanceAfterFirstWord for details.
+ AK_FORCE_INLINE void saveNormalizedCompoundDistanceAfterFirstWordIfNoneYet() {
+ mDicNodeState.mDicNodeStateScoring.saveNormalizedCompoundDistanceAfterFirstWordIfNoneYet();
+ }
+
// Caveat: Must not be called outside Weighting
// This restriction is guaranteed by "friend"
AK_FORCE_INLINE void forwardInputIndex(const int pointerId, const int count,
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
index 4c884225a..3c85d0e9d 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
@@ -31,7 +31,8 @@ class DicNodeStateScoring {
mDigraphIndex(DigraphUtils::NOT_A_DIGRAPH_INDEX),
mEditCorrectionCount(0), mProximityCorrectionCount(0),
mNormalizedCompoundDistance(0.0f), mSpatialDistance(0.0f), mLanguageDistance(0.0f),
- mRawLength(0.0f), mExactMatch(true) {
+ mRawLength(0.0f), mExactMatch(true),
+ mNormalizedCompoundDistanceAfterFirstWord(MAX_VALUE_FOR_WEIGHTING) {
}
virtual ~DicNodeStateScoring() {}
@@ -45,6 +46,7 @@ class DicNodeStateScoring {
mRawLength = 0.0f;
mDoubleLetterLevel = NOT_A_DOUBLE_LETTER;
mDigraphIndex = DigraphUtils::NOT_A_DIGRAPH_INDEX;
+ mNormalizedCompoundDistanceAfterFirstWord = MAX_VALUE_FOR_WEIGHTING;
mExactMatch = true;
}
@@ -58,6 +60,8 @@ class DicNodeStateScoring {
mDoubleLetterLevel = scoring->mDoubleLetterLevel;
mDigraphIndex = scoring->mDigraphIndex;
mExactMatch = scoring->mExactMatch;
+ mNormalizedCompoundDistanceAfterFirstWord =
+ scoring->mNormalizedCompoundDistanceAfterFirstWord;
}
void addCost(const float spatialCost, const float languageCost, const bool doNormalization,
@@ -86,6 +90,17 @@ class DicNodeStateScoring {
}
}
+ // Saves the current normalized distance for space-aware gestures.
+ // See getNormalizedCompoundDistanceAfterFirstWord for details.
+ void saveNormalizedCompoundDistanceAfterFirstWordIfNoneYet() {
+ // We get called here after each word. We only want to store the distance after
+ // the first word, so if we already have a distance we skip saving -- hence "IfNoneYet"
+ // in the method name.
+ if (mNormalizedCompoundDistanceAfterFirstWord >= MAX_VALUE_FOR_WEIGHTING) {
+ mNormalizedCompoundDistanceAfterFirstWord = getNormalizedCompoundDistance();
+ }
+ }
+
void addRawLength(const float rawLength) {
mRawLength += rawLength;
}
@@ -102,6 +117,13 @@ class DicNodeStateScoring {
return mNormalizedCompoundDistance;
}
+ // For space-aware gestures, we store the normalized distance at the char index
+ // that ends the first word of the suggestion. We call this the distance after
+ // first word.
+ float getNormalizedCompoundDistanceAfterFirstWord() const {
+ return mNormalizedCompoundDistanceAfterFirstWord;
+ }
+
float getSpatialDistance() const {
return mSpatialDistance;
}
@@ -178,6 +200,7 @@ class DicNodeStateScoring {
float mLanguageDistance;
float mRawLength;
bool mExactMatch;
+ float mNormalizedCompoundDistanceAfterFirstWord;
AK_FORCE_INLINE void addDistance(float spatialDistance, float languageDistance,
bool doNormalization, int inputSize, int totalInputIndex) {
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index ec1b63a12..b1d01ed86 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -33,6 +33,8 @@
namespace latinime {
+const int Dictionary::HEADER_ATTRIBUTE_BUFFER_SIZE = 32;
+
Dictionary::Dictionary(JNIEnv *env,
DictionaryStructureWithBufferPolicy *const dictionaryStructureWithBufferPolicy)
: mDictionaryStructureWithBufferPolicy(dictionaryStructureWithBufferPolicy),
@@ -121,32 +123,37 @@ void Dictionary::flushWithGC(const char *const filePath) {
mDictionaryStructureWithBufferPolicy->flushWithGC(filePath);
}
-bool Dictionary::needsToRunGC() {
- return mDictionaryStructureWithBufferPolicy->needsToRunGC();
+bool Dictionary::needsToRunGC(const bool mindsBlockByGC) {
+ return mDictionaryStructureWithBufferPolicy->needsToRunGC(mindsBlockByGC);
+}
+
+void Dictionary::getProperty(const char *const query, char *const outResult,
+ const int maxResultLength) const {
+ return mDictionaryStructureWithBufferPolicy->getProperty(query, outResult, maxResultLength);
}
void Dictionary::logDictionaryInfo(JNIEnv *const env) const {
- const int BUFFER_SIZE = 16;
- int dictionaryIdCodePointBuffer[BUFFER_SIZE];
- int versionStringCodePointBuffer[BUFFER_SIZE];
- int dateStringCodePointBuffer[BUFFER_SIZE];
+ int dictionaryIdCodePointBuffer[HEADER_ATTRIBUTE_BUFFER_SIZE];
+ int versionStringCodePointBuffer[HEADER_ATTRIBUTE_BUFFER_SIZE];
+ int dateStringCodePointBuffer[HEADER_ATTRIBUTE_BUFFER_SIZE];
const DictionaryHeaderStructurePolicy *const headerPolicy =
getDictionaryStructurePolicy()->getHeaderStructurePolicy();
headerPolicy->readHeaderValueOrQuestionMark("dictionary", dictionaryIdCodePointBuffer,
- BUFFER_SIZE);
+ HEADER_ATTRIBUTE_BUFFER_SIZE);
headerPolicy->readHeaderValueOrQuestionMark("version", versionStringCodePointBuffer,
- BUFFER_SIZE);
- headerPolicy->readHeaderValueOrQuestionMark("date", dateStringCodePointBuffer, BUFFER_SIZE);
-
- char dictionaryIdCharBuffer[BUFFER_SIZE];
- char versionStringCharBuffer[BUFFER_SIZE];
- char dateStringCharBuffer[BUFFER_SIZE];
- intArrayToCharArray(dictionaryIdCodePointBuffer, BUFFER_SIZE,
- dictionaryIdCharBuffer, BUFFER_SIZE);
- intArrayToCharArray(versionStringCodePointBuffer, BUFFER_SIZE,
- versionStringCharBuffer, BUFFER_SIZE);
- intArrayToCharArray(dateStringCodePointBuffer, BUFFER_SIZE,
- dateStringCharBuffer, BUFFER_SIZE);
+ HEADER_ATTRIBUTE_BUFFER_SIZE);
+ headerPolicy->readHeaderValueOrQuestionMark("date", dateStringCodePointBuffer,
+ HEADER_ATTRIBUTE_BUFFER_SIZE);
+
+ char dictionaryIdCharBuffer[HEADER_ATTRIBUTE_BUFFER_SIZE];
+ char versionStringCharBuffer[HEADER_ATTRIBUTE_BUFFER_SIZE];
+ char dateStringCharBuffer[HEADER_ATTRIBUTE_BUFFER_SIZE];
+ intArrayToCharArray(dictionaryIdCodePointBuffer, HEADER_ATTRIBUTE_BUFFER_SIZE,
+ dictionaryIdCharBuffer, HEADER_ATTRIBUTE_BUFFER_SIZE);
+ intArrayToCharArray(versionStringCodePointBuffer, HEADER_ATTRIBUTE_BUFFER_SIZE,
+ versionStringCharBuffer, HEADER_ATTRIBUTE_BUFFER_SIZE);
+ intArrayToCharArray(dateStringCodePointBuffer, HEADER_ATTRIBUTE_BUFFER_SIZE,
+ dateStringCharBuffer, HEADER_ATTRIBUTE_BUFFER_SIZE);
LogUtils::logToJava(env,
"Dictionary info: dictionary = %s ; version = %s ; date = %s",
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h
index 974447468..d8a0f3e58 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/dictionary.h
@@ -81,7 +81,10 @@ class Dictionary {
void flushWithGC(const char *const filePath);
- bool needsToRunGC();
+ bool needsToRunGC(const bool mindsBlockByGC);
+
+ void getProperty(const char *const query, char *const outResult,
+ const int maxResultLength) const;
const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const {
return mDictionaryStructureWithBufferPolicy;
@@ -92,6 +95,8 @@ class Dictionary {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary);
+ static const int HEADER_ATTRIBUTE_BUFFER_SIZE;
+
DictionaryStructureWithBufferPolicy *const mDictionaryStructureWithBufferPolicy;
const BigramDictionary *const mBigramDictionary;
const SuggestInterface *const mGestureSuggest;
diff --git a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
index b95488ebd..c7ffef0d5 100644
--- a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
+++ b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
@@ -78,7 +78,10 @@ class DictionaryStructureWithBufferPolicy {
virtual void flushWithGC(const char *const filePath) = 0;
- virtual bool needsToRunGC() const = 0;
+ virtual bool needsToRunGC(const bool mindsBlockByGC) const = 0;
+
+ virtual void getProperty(const char *const query, char *const outResult,
+ const int maxResultLength) const = 0;
protected:
DictionaryStructureWithBufferPolicy() {}
diff --git a/native/jni/src/suggest/core/policy/weighting.cpp b/native/jni/src/suggest/core/policy/weighting.cpp
index f9b777df2..0c4016893 100644
--- a/native/jni/src/suggest/core/policy/weighting.cpp
+++ b/native/jni/src/suggest/core/policy/weighting.cpp
@@ -38,7 +38,7 @@ static inline void profile(const CorrectionType correctionType, DicNode *const n
case CT_SUBSTITUTION:
PROF_SUBSTITUTION(node->mProfiler);
return;
- case CT_NEW_WORD_SPACE_OMITTION:
+ case CT_NEW_WORD_SPACE_OMISSION:
PROF_NEW_WORD(node->mProfiler);
return;
case CT_MATCH:
@@ -93,6 +93,11 @@ static inline void profile(const CorrectionType correctionType, DicNode *const n
}
dicNode->addCost(spatialCost, languageCost, weighting->needsToNormalizeCompoundDistance(),
inputSize, errorType);
+ if (CT_NEW_WORD_SPACE_OMISSION == correctionType) {
+ // When we are on a terminal, we save the current distance for evaluating
+ // when to auto-commit partial suggestions.
+ dicNode->saveNormalizedCompoundDistanceAfterFirstWordIfNoneYet();
+ }
}
/* static */ float Weighting::getSpatialCost(const Weighting *const weighting,
@@ -108,7 +113,7 @@ static inline void profile(const CorrectionType correctionType, DicNode *const n
case CT_SUBSTITUTION:
// only used for typing
return weighting->getSubstitutionCost();
- case CT_NEW_WORD_SPACE_OMITTION:
+ case CT_NEW_WORD_SPACE_OMISSION:
return weighting->getNewWordSpatialCost(traverseSession, dicNode, inputStateG);
case CT_MATCH:
return weighting->getMatchedCost(traverseSession, dicNode, inputStateG);
@@ -138,7 +143,7 @@ static inline void profile(const CorrectionType correctionType, DicNode *const n
return 0.0f;
case CT_SUBSTITUTION:
return 0.0f;
- case CT_NEW_WORD_SPACE_OMITTION:
+ case CT_NEW_WORD_SPACE_OMISSION:
return weighting->getNewWordBigramLanguageCost(
traverseSession, parentDicNode, multiBigramMap);
case CT_MATCH:
@@ -173,7 +178,7 @@ static inline void profile(const CorrectionType correctionType, DicNode *const n
return 0; /* 0 because CT_MATCH will be called */
case CT_SUBSTITUTION:
return 0; /* 0 because CT_MATCH will be called */
- case CT_NEW_WORD_SPACE_OMITTION:
+ case CT_NEW_WORD_SPACE_OMISSION:
return 0;
case CT_MATCH:
return 1;
diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp
index b1340e12f..e20bc497a 100644
--- a/native/jni/src/suggest/core/suggest.cpp
+++ b/native/jni/src/suggest/core/suggest.cpp
@@ -574,7 +574,7 @@ void Suggest::createNextWordDicNode(DicTraverseSession *traverseSession, DicNode
DicNodeUtils::initAsRootWithPreviousWord(
traverseSession->getDictionaryStructurePolicy(), dicNode, &newDicNode);
const CorrectionType correctionType = spaceSubstitution ?
- CT_NEW_WORD_SPACE_SUBSTITUTION : CT_NEW_WORD_SPACE_OMITTION;
+ CT_NEW_WORD_SPACE_SUBSTITUTION : CT_NEW_WORD_SPACE_OMISSION;
Weighting::addCostAndForwardInputIndex(WEIGHTING, correctionType, traverseSession, dicNode,
&newDicNode, traverseSession->getMultiBigramMap());
if (newDicNode.getCompoundDistance() < static_cast<float>(MAX_VALUE_FOR_WEIGHTING)) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp
index bc2f5ee58..67a085de3 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp
@@ -17,10 +17,10 @@
#include "suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h"
#include "suggest/core/policy/dictionary_shortcuts_structure_policy.h"
-#include "suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h"
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h"
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h"
#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
+#include "suggest/policyimpl/dictionary/utils/decaying_utils.h"
namespace latinime {
@@ -41,9 +41,14 @@ void DynamicBigramListPolicy::getNextBigram(int *const outBigramPos, int *const
if (usesAdditionalBuffer && originalBigramPos != NOT_A_DICT_POS) {
originalBigramPos += mBuffer->getOriginalBufferSize();
}
- *outBigramPos = followBigramLinkAndGetCurrentBigramPtNodePos(originalBigramPos);
*outProbability = BigramListReadWriteUtils::getProbabilityFromFlags(bigramFlags);
*outHasNext = BigramListReadWriteUtils::hasNext(bigramFlags);
+ if (mIsDecayingDict && !DecayingUtils::isValidBigram(*outProbability)) {
+ // This bigram is too weak to output.
+ *outBigramPos = NOT_A_DICT_POS;
+ } else {
+ *outBigramPos = followBigramLinkAndGetCurrentBigramPtNodePos(originalBigramPos);
+ }
if (usesAdditionalBuffer) {
*bigramEntryPos += mBuffer->getOriginalBufferSize();
}
@@ -119,7 +124,7 @@ bool DynamicBigramListPolicy::copyAllBigrams(BufferWithExtendableBuffer *const b
// Finding useless bigram entries and remove them. Bigram entry is useless when the target PtNode
// has been deleted or is not a valid terminal.
bool DynamicBigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(
- int *const bigramListPos) {
+ int *const bigramListPos, int *const outValidBigramEntryCount) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*bigramListPos);
if (usesAdditionalBuffer) {
*bigramListPos -= mBuffer->getOriginalBufferSize();
@@ -153,14 +158,22 @@ bool DynamicBigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(
const int bigramTargetNodePos =
followBigramLinkAndGetCurrentBigramPtNodePos(originalBigramPos);
nodeReader.fetchNodeInfoInBufferFromPtNodePos(bigramTargetNodePos);
- // TODO: Update probability for supporting probability decaying.
if (nodeReader.isDeleted() || !nodeReader.isTerminal()
|| bigramTargetNodePos == NOT_A_DICT_POS) {
// The target is no longer valid terminal. Invalidate the current bigram entry.
if (!BigramListReadWriteUtils::writeBigramEntry(mBuffer, bigramFlags,
- NOT_A_DICT_POS /* targetOffset */, &bigramEntryPos)) {
+ NOT_A_DICT_POS /* targetPtNodePos */, &bigramEntryPos)) {
return false;
}
+ continue;
+ }
+ bool isRemoved = false;
+ if (!updateProbabilityForDecay(bigramFlags, bigramTargetNodePos, &bigramEntryPos,
+ &isRemoved)) {
+ return false;
+ }
+ if (!isRemoved) {
+ (*outValidBigramEntryCount) += 1;
}
} while(BigramListReadWriteUtils::hasNext(bigramFlags));
return true;
@@ -169,7 +182,7 @@ bool DynamicBigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(
// Updates bigram target PtNode positions in the list after the placing step in GC.
bool DynamicBigramListPolicy::updateAllBigramTargetPtNodePositions(int *const bigramListPos,
const DynamicPatriciaTrieWritingHelper::PtNodePositionRelocationMap *const
- ptNodePositionRelocationMap) {
+ ptNodePositionRelocationMap, int *const outBigramEntryCount) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*bigramListPos);
if (usesAdditionalBuffer) {
*bigramListPos -= mBuffer->getOriginalBufferSize();
@@ -211,11 +224,12 @@ bool DynamicBigramListPolicy::updateAllBigramTargetPtNodePositions(int *const bi
return false;
}
} while(BigramListReadWriteUtils::hasNext(bigramFlags));
+ (*outBigramEntryCount) = bigramEntryCount;
return true;
}
bool DynamicBigramListPolicy::addNewBigramEntryToBigramList(const int bigramTargetPos,
- const int probability, int *const bigramListPos) {
+ const int probability, int *const bigramListPos, bool *const outAddedNewBigram) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*bigramListPos);
if (usesAdditionalBuffer) {
*bigramListPos -= mBuffer->getOriginalBufferSize();
@@ -243,8 +257,15 @@ bool DynamicBigramListPolicy::addNewBigramEntryToBigramList(const int bigramTarg
}
if (followBigramLinkAndGetCurrentBigramPtNodePos(originalBigramPos) == bigramTargetPos) {
// Update this bigram entry.
+ *outAddedNewBigram = false;
+ const int originalProbability = BigramListReadWriteUtils::getProbabilityFromFlags(
+ bigramFlags);
+ const int probabilityToWrite = mIsDecayingDict ?
+ DecayingUtils::getUpdatedBigramProbabilityDelta(
+ originalProbability, probability) : probability;
const BigramListReadWriteUtils::BigramFlags updatedFlags =
- BigramListReadWriteUtils::setProbabilityInFlags(bigramFlags, probability);
+ BigramListReadWriteUtils::setProbabilityInFlags(bigramFlags,
+ probabilityToWrite);
return BigramListReadWriteUtils::writeBigramEntry(mBuffer, updatedFlags,
originalBigramPos, &entryPos);
}
@@ -254,12 +275,14 @@ bool DynamicBigramListPolicy::addNewBigramEntryToBigramList(const int bigramTarg
// The current last entry is found.
// First, update the flags of the last entry.
if (!BigramListReadWriteUtils::setHasNextFlag(mBuffer, true /* hasNext */, entryPos)) {
+ *outAddedNewBigram = false;
return false;
}
if (usesAdditionalBuffer) {
*bigramListPos += mBuffer->getOriginalBufferSize();
}
// Then, add a new entry after the last entry.
+ *outAddedNewBigram = true;
return writeNewBigramEntry(bigramTargetPos, probability, bigramListPos);
} while(BigramListReadWriteUtils::hasNext(bigramFlags));
// We return directly from the while loop.
@@ -270,8 +293,11 @@ bool DynamicBigramListPolicy::addNewBigramEntryToBigramList(const int bigramTarg
bool DynamicBigramListPolicy::writeNewBigramEntry(const int bigramTargetPos, const int probability,
int *const writingPos) {
// hasNext is false because we are adding a new bigram entry at the end of the bigram list.
+ const int probabilityToWrite = mIsDecayingDict ?
+ DecayingUtils::getUpdatedBigramProbabilityDelta(NOT_A_PROBABILITY, probability) :
+ probability;
return BigramListReadWriteUtils::createAndWriteBigramEntry(mBuffer, bigramTargetPos,
- probability, false /* hasNext */, writingPos);
+ probabilityToWrite, false /* hasNext */, writingPos);
}
bool DynamicBigramListPolicy::removeBigram(const int bigramListPos, const int bigramTargetPos) {
@@ -325,7 +351,7 @@ int DynamicBigramListPolicy::followBigramLinkAndGetCurrentBigramPtNodePos(
nodeReader.fetchNodeInfoInBufferFromPtNodePos(currentPos);
bigramLinkCount++;
if (bigramLinkCount > CONTINUING_BIGRAM_LINK_COUNT_LIMIT) {
- AKLOGE("Bigram link is invalid. start position: %d", bigramPos);
+ AKLOGE("Bigram link is invalid. start position: %d", originalBigramPos);
ASSERT(false);
return NOT_A_DICT_POS;
}
@@ -333,4 +359,33 @@ int DynamicBigramListPolicy::followBigramLinkAndGetCurrentBigramPtNodePos(
return currentPos;
}
+bool DynamicBigramListPolicy::updateProbabilityForDecay(
+ BigramListReadWriteUtils::BigramFlags bigramFlags, const int targetPtNodePos,
+ int *const bigramEntryPos, bool *const outRemoved) const {
+ *outRemoved = false;
+ if (mIsDecayingDict) {
+ // Update bigram probability for decaying.
+ const int newProbability = DecayingUtils::getBigramProbabilityDeltaToSave(
+ BigramListReadWriteUtils::getProbabilityFromFlags(bigramFlags));
+ if (DecayingUtils::isValidBigram(newProbability)) {
+ // Write new probability.
+ const BigramListReadWriteUtils::BigramFlags updatedBigramFlags =
+ BigramListReadWriteUtils::setProbabilityInFlags(
+ bigramFlags, newProbability);
+ if (!BigramListReadWriteUtils::writeBigramEntry(mBuffer, updatedBigramFlags,
+ targetPtNodePos, bigramEntryPos)) {
+ return false;
+ }
+ } else {
+ // Remove current bigram entry.
+ *outRemoved = true;
+ if (!BigramListReadWriteUtils::writeBigramEntry(mBuffer, bigramFlags,
+ NOT_A_DICT_POS /* targetPtNodePos */, bigramEntryPos)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h
index 8ea318a41..b358b4ed5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h
@@ -21,6 +21,7 @@
#include "defines.h"
#include "suggest/core/policy/dictionary_bigrams_structure_policy.h"
+#include "suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h"
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h"
namespace latinime {
@@ -34,8 +35,9 @@ class DictionaryShortcutsStructurePolicy;
class DynamicBigramListPolicy : public DictionaryBigramsStructurePolicy {
public:
DynamicBigramListPolicy(BufferWithExtendableBuffer *const buffer,
- const DictionaryShortcutsStructurePolicy *const shortcutPolicy)
- : mBuffer(buffer), mShortcutPolicy(shortcutPolicy) {}
+ const DictionaryShortcutsStructurePolicy *const shortcutPolicy,
+ const bool isDecayingDict)
+ : mBuffer(buffer), mShortcutPolicy(shortcutPolicy), mIsDecayingDict(isDecayingDict) {}
~DynamicBigramListPolicy() {}
@@ -50,19 +52,20 @@ class DynamicBigramListPolicy : public DictionaryBigramsStructurePolicy {
bool copyAllBigrams(BufferWithExtendableBuffer *const bufferToWrite, int *const fromPos,
int *const toPos, int *const outBigramsCount) const;
- bool updateAllBigramEntriesAndDeleteUselessEntries(int *const bigramListPos);
+ bool updateAllBigramEntriesAndDeleteUselessEntries(int *const bigramListPos,
+ int *const outBigramEntryCount);
bool updateAllBigramTargetPtNodePositions(int *const bigramListPos,
const DynamicPatriciaTrieWritingHelper::PtNodePositionRelocationMap *const
- ptNodePositionRelocationMap);
+ ptNodePositionRelocationMap, int *const outValidBigramEntryCount);
bool addNewBigramEntryToBigramList(const int bigramTargetPos, const int probability,
- int *const bigramListPos);
+ int *const bigramListPos, bool *const outAddedNewBigram);
bool writeNewBigramEntry(const int bigramTargetPos, const int probability,
int *const writingPos);
- // Return if targetBigramPos is found or not.
+ // Return whether or not targetBigramPos is found.
bool removeBigram(const int bigramListPos, const int bigramTargetPos);
private:
@@ -73,9 +76,13 @@ class DynamicBigramListPolicy : public DictionaryBigramsStructurePolicy {
BufferWithExtendableBuffer *const mBuffer;
const DictionaryShortcutsStructurePolicy *const mShortcutPolicy;
+ const bool mIsDecayingDict;
// Follow bigram link and return the position of bigram target PtNode that is currently valid.
int followBigramLinkAndGetCurrentBigramPtNodePos(const int originalBigramPos) const;
+
+ bool updateProbabilityForDecay(BigramListReadWriteUtils::BigramFlags bigramFlags,
+ const int targetPtNodePos, int *const bigramEntryPos, bool *const outRemoved) const;
};
} // namespace latinime
#endif // LATINIME_DYNAMIC_BIGRAM_LIST_POLICY_H
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.cpp
index c60e45819..081163a4d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.cpp
@@ -16,6 +16,8 @@
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h"
+#include "suggest/policyimpl/dictionary/utils/decaying_utils.h"
+
namespace latinime {
bool DynamicPatriciaTrieGcEventListeners
@@ -25,6 +27,19 @@ bool DynamicPatriciaTrieGcEventListeners
// PtNode is useless when the PtNode is not a terminal and doesn't have any not useless
// children.
bool isUselessPtNode = !node->isTerminal();
+ if (node->isTerminal() && mIsDecayingDict) {
+ const int newProbability =
+ DecayingUtils::getUnigramProbabilityToSave(node->getProbability());
+ int writingPos = node->getProbabilityFieldPos();
+ // Update probability.
+ if (!DynamicPatriciaTrieWritingUtils::writeProbabilityAndAdvancePosition(
+ mBuffer, newProbability, &writingPos)) {
+ return false;
+ }
+ if (!DecayingUtils::isValidUnigram(newProbability)) {
+ isUselessPtNode = false;
+ }
+ }
if (mChildrenValue > 0) {
isUselessPtNode = false;
} else if (node->isTerminal()) {
@@ -41,7 +56,27 @@ bool DynamicPatriciaTrieGcEventListeners
return false;
}
} else {
- valueStack.back() += 1;
+ mValueStack.back() += 1;
+ if (node->isTerminal()) {
+ mValidUnigramCount += 1;
+ }
+ }
+ return true;
+}
+
+bool DynamicPatriciaTrieGcEventListeners::TraversePolicyToUpdateBigramProbability
+ ::onVisitingPtNode(const DynamicPatriciaTrieNodeReader *const node,
+ const int *const nodeCodePoints) {
+ if (!node->isDeleted()) {
+ int pos = node->getBigramsPos();
+ if (pos != NOT_A_DICT_POS) {
+ int bigramEntryCount = 0;
+ if (!mBigramPolicy->updateAllBigramEntriesAndDeleteUselessEntries(&pos,
+ &bigramEntryCount)) {
+ return false;
+ }
+ mValidBigramEntryCount += bigramEntryCount;
+ }
}
return true;
}
@@ -137,10 +172,15 @@ bool DynamicPatriciaTrieGcEventListeners::TraversePolicyToUpdateAllPositionField
// Updates bigram target PtNode positions in the bigram list.
int bigramsPos = node->getBigramsPos();
if (bigramsPos != NOT_A_DICT_POS) {
+ int bigramEntryCount;
if (!mBigramPolicy->updateAllBigramTargetPtNodePositions(&bigramsPos,
- &mDictPositionRelocationMap->mPtNodePositionRelocationMap)) {
+ &mDictPositionRelocationMap->mPtNodePositionRelocationMap, &bigramEntryCount)) {
return false;
}
+ mBigramCount += bigramEntryCount;
+ }
+ if (node->isTerminal()) {
+ mUnigramCount++;
}
return true;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h
index 4256f22fb..463715af5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h
@@ -39,23 +39,23 @@ class DynamicPatriciaTrieGcEventListeners {
public:
TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted(
DynamicPatriciaTrieWritingHelper *const writingHelper,
- BufferWithExtendableBuffer *const buffer)
- : mWritingHelper(writingHelper), mBuffer(buffer), valueStack(),
- mChildrenValue(0) {}
+ BufferWithExtendableBuffer *const buffer, const bool isDecayingDict)
+ : mWritingHelper(writingHelper), mBuffer(buffer), mIsDecayingDict(isDecayingDict),
+ mValueStack(), mChildrenValue(0), mValidUnigramCount(0) {}
~TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted() {};
bool onAscend() {
- if (valueStack.empty()) {
+ if (mValueStack.empty()) {
return false;
}
- mChildrenValue = valueStack.back();
- valueStack.pop_back();
+ mChildrenValue = mValueStack.back();
+ mValueStack.pop_back();
return true;
}
bool onDescend(const int ptNodeArrayPos) {
- valueStack.push_back(0);
+ mValueStack.push_back(0);
return true;
}
@@ -64,14 +64,20 @@ class DynamicPatriciaTrieGcEventListeners {
bool onVisitingPtNode(const DynamicPatriciaTrieNodeReader *const node,
const int *const nodeCodePoints);
+ int getValidUnigramCount() const {
+ return mValidUnigramCount;
+ }
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(
TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted);
DynamicPatriciaTrieWritingHelper *const mWritingHelper;
BufferWithExtendableBuffer *const mBuffer;
- std::vector<int> valueStack;
+ const int mIsDecayingDict;
+ std::vector<int> mValueStack;
int mChildrenValue;
+ int mValidUnigramCount;
};
// Updates all bigram entries that are held by valid PtNodes. This removes useless bigram
@@ -80,7 +86,7 @@ class DynamicPatriciaTrieGcEventListeners {
: public DynamicPatriciaTrieReadingHelper::TraversingEventListener {
public:
TraversePolicyToUpdateBigramProbability(DynamicBigramListPolicy *const bigramPolicy)
- : mBigramPolicy(bigramPolicy) {}
+ : mBigramPolicy(bigramPolicy), mValidBigramEntryCount(0) {}
bool onAscend() { return true; }
@@ -89,22 +95,17 @@ class DynamicPatriciaTrieGcEventListeners {
bool onReadingPtNodeArrayTail() { return true; }
bool onVisitingPtNode(const DynamicPatriciaTrieNodeReader *const node,
- const int *const nodeCodePoints) {
- if (!node->isDeleted()) {
- int pos = node->getBigramsPos();
- if (pos != NOT_A_DICT_POS) {
- if (!mBigramPolicy->updateAllBigramEntriesAndDeleteUselessEntries(&pos)) {
- return false;
- }
- }
- }
- return true;
+ const int *const nodeCodePoints);
+
+ int getValidBigramEntryCount() const {
+ return mValidBigramEntryCount;
}
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TraversePolicyToUpdateBigramProbability);
DynamicBigramListPolicy *const mBigramPolicy;
+ int mValidBigramEntryCount;
};
class TraversePolicyToPlaceAndWriteValidPtNodesToBuffer
@@ -150,7 +151,8 @@ class DynamicPatriciaTrieGcEventListeners {
dictPositionRelocationMap)
: mWritingHelper(writingHelper), mBigramPolicy(bigramPolicy),
mBufferToWrite(bufferToWrite),
- mDictPositionRelocationMap(dictPositionRelocationMap) {};
+ mDictPositionRelocationMap(dictPositionRelocationMap), mUnigramCount(0),
+ mBigramCount(0) {};
bool onAscend() { return true; }
@@ -161,6 +163,14 @@ class DynamicPatriciaTrieGcEventListeners {
bool onVisitingPtNode(const DynamicPatriciaTrieNodeReader *const node,
const int *const nodeCodePoints);
+ int getUnigramCount() const {
+ return mUnigramCount;
+ }
+
+ int getBigramCount() const {
+ return mBigramCount;
+ }
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TraversePolicyToUpdateAllPositionFields);
@@ -169,6 +179,8 @@ class DynamicPatriciaTrieGcEventListeners {
BufferWithExtendableBuffer *const mBufferToWrite;
const DynamicPatriciaTrieWritingHelper::DictPositionRelocationMap *const
mDictPositionRelocationMap;
+ int mUnigramCount;
+ int mBigramCount;
};
private:
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
index 456352c17..2fa3111d3 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
@@ -26,7 +26,8 @@ namespace latinime {
void DynamicPatriciaTrieNodeReader::fetchPtNodeInfoFromBufferAndProcessMovedPtNode(
const int ptNodePos, const int maxCodePointCount, int *const outCodePoints) {
if (ptNodePos < 0 || ptNodePos >= mBuffer->getTailPosition()) {
- AKLOGE("Fetching PtNode info form invalid dictionary position: %d, dictionary size: %d",
+ // Reading invalid position because of bug or broken dictionary.
+ AKLOGE("Fetching PtNode info from invalid dictionary position: %d, dictionary size: %d",
ptNodePos, mBuffer->getTailPosition());
ASSERT(false);
invalidatePtNodeInfo();
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
index 42397c19e..0d8c92768 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
@@ -16,6 +16,10 @@
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h"
+#include <cstdio>
+#include <cstring>
+#include <ctime>
+
#include "defines.h"
#include "suggest/core/dicnode/dic_node.h"
#include "suggest/core/dicnode/dic_node_vector.h"
@@ -24,10 +28,18 @@
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h"
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h"
#include "suggest/policyimpl/dictionary/patricia_trie_reading_utils.h"
+#include "suggest/policyimpl/dictionary/utils/decaying_utils.h"
#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
namespace latinime {
+const char *const DynamicPatriciaTriePolicy::UNIGRAM_COUNT_QUERY = "UNIGRAM_COUNT";
+const char *const DynamicPatriciaTriePolicy::BIGRAM_COUNT_QUERY = "BIGRAM_COUNT";
+const int DynamicPatriciaTriePolicy::MAX_DICT_EXTENDED_REGION_SIZE = 1024 * 1024;
+const int DynamicPatriciaTriePolicy::MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS =
+ DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE - 1024;
+const int DynamicPatriciaTriePolicy::MIN_SECONDS_TO_REQUIRE_GC_WHEN_WRITING = 2 * 60 * 60;
+
void DynamicPatriciaTriePolicy::createAndGetAllChildNodes(const DicNode *const dicNode,
DicNodeVector *const childDicNodes) const {
if (!dicNode->hasChildren()) {
@@ -137,14 +149,17 @@ int DynamicPatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const in
int DynamicPatriciaTriePolicy::getProbability(const int unigramProbability,
const int bigramProbability) const {
- // TODO: check mHeaderPolicy.usesForgettingCurve();
- if (unigramProbability == NOT_A_PROBABILITY) {
- return NOT_A_PROBABILITY;
- } else if (bigramProbability == NOT_A_PROBABILITY) {
- return ProbabilityUtils::backoff(unigramProbability);
+ if (mHeaderPolicy.isDecayingDict()) {
+ return DecayingUtils::getProbability(unigramProbability, bigramProbability);
} else {
- return ProbabilityUtils::computeProbabilityForBigram(unigramProbability,
- bigramProbability);
+ if (unigramProbability == NOT_A_PROBABILITY) {
+ return NOT_A_PROBABILITY;
+ } else if (bigramProbability == NOT_A_PROBABILITY) {
+ return ProbabilityUtils::backoff(unigramProbability);
+ } else {
+ return ProbabilityUtils::computeProbabilityForBigram(unigramProbability,
+ bigramProbability);
+ }
}
}
@@ -193,12 +208,26 @@ bool DynamicPatriciaTriePolicy::addUnigramWord(const int *const word, const int
AKLOGI("Warning: addUnigramWord() is called for non-updatable dictionary.");
return false;
}
+ if (mBufferWithExtendableBuffer.getTailPosition()
+ >= MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS) {
+ AKLOGE("The dictionary is too large to dynamically update.");
+ return false;
+ }
DynamicPatriciaTrieReadingHelper readingHelper(&mBufferWithExtendableBuffer,
getBigramsStructurePolicy(), getShortcutsStructurePolicy());
readingHelper.initWithPtNodeArrayPos(getRootPosition());
DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer,
- &mBigramListPolicy, &mShortcutListPolicy);
- return writingHelper.addUnigramWord(&readingHelper, word, length, probability);
+ &mBigramListPolicy, &mShortcutListPolicy, mHeaderPolicy.isDecayingDict());
+ bool addedNewUnigram = false;
+ if (writingHelper.addUnigramWord(&readingHelper, word, length, probability,
+ &addedNewUnigram)) {
+ if (addedNewUnigram) {
+ mUnigramCount++;
+ }
+ return true;
+ } else {
+ return false;
+ }
}
bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int length0,
@@ -207,6 +236,11 @@ bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int
AKLOGI("Warning: addBigramWords() is called for non-updatable dictionary.");
return false;
}
+ if (mBufferWithExtendableBuffer.getTailPosition()
+ >= MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS) {
+ AKLOGE("The dictionary is too large to dynamically update.");
+ return false;
+ }
const int word0Pos = getTerminalNodePositionOfWord(word0, length0,
false /* forceLowerCaseSearch */);
if (word0Pos == NOT_A_DICT_POS) {
@@ -218,8 +252,16 @@ bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int
return false;
}
DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer,
- &mBigramListPolicy, &mShortcutListPolicy);
- return writingHelper.addBigramWords(word0Pos, word1Pos, probability);
+ &mBigramListPolicy, &mShortcutListPolicy, mHeaderPolicy.isDecayingDict());
+ bool addedNewBigram = false;
+ if (writingHelper.addBigramWords(word0Pos, word1Pos, probability, &addedNewBigram)) {
+ if (addedNewBigram) {
+ mBigramCount++;
+ }
+ return true;
+ } else {
+ return false;
+ }
}
bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const int length0,
@@ -228,6 +270,11 @@ bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const
AKLOGI("Warning: removeBigramWords() is called for non-updatable dictionary.");
return false;
}
+ if (mBufferWithExtendableBuffer.getTailPosition()
+ >= MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS) {
+ AKLOGE("The dictionary is too large to dynamically update.");
+ return false;
+ }
const int word0Pos = getTerminalNodePositionOfWord(word0, length0,
false /* forceLowerCaseSearch */);
if (word0Pos == NOT_A_DICT_POS) {
@@ -239,8 +286,13 @@ bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const
return false;
}
DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer,
- &mBigramListPolicy, &mShortcutListPolicy);
- return writingHelper.removeBigramWords(word0Pos, word1Pos);
+ &mBigramListPolicy, &mShortcutListPolicy, mHeaderPolicy.isDecayingDict());
+ if (writingHelper.removeBigramWords(word0Pos, word1Pos)) {
+ mBigramCount--;
+ return true;
+ } else {
+ return false;
+ }
}
void DynamicPatriciaTriePolicy::flush(const char *const filePath) {
@@ -249,8 +301,8 @@ void DynamicPatriciaTriePolicy::flush(const char *const filePath) {
return;
}
DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer,
- &mBigramListPolicy, &mShortcutListPolicy);
- writingHelper.writeToDictFile(filePath, &mHeaderPolicy);
+ &mBigramListPolicy, &mShortcutListPolicy, mHeaderPolicy.isDecayingDict());
+ writingHelper.writeToDictFile(filePath, &mHeaderPolicy, mUnigramCount, mBigramCount);
}
void DynamicPatriciaTriePolicy::flushWithGC(const char *const filePath) {
@@ -259,17 +311,51 @@ void DynamicPatriciaTriePolicy::flushWithGC(const char *const filePath) {
return;
}
DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer,
- &mBigramListPolicy, &mShortcutListPolicy);
+ &mBigramListPolicy, &mShortcutListPolicy, mHeaderPolicy.isDecayingDict());
writingHelper.writeToDictFileWithGC(getRootPosition(), filePath, &mHeaderPolicy);
}
-bool DynamicPatriciaTriePolicy::needsToRunGC() const {
+bool DynamicPatriciaTriePolicy::needsToRunGC(const bool mindsBlockByGC) const {
if (!mBuffer->isUpdatable()) {
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
return false;
}
- // TODO: Implement more properly.
- return mBufferWithExtendableBuffer.isNearSizeLimit();
+ if (mBufferWithExtendableBuffer.isNearSizeLimit()) {
+ // Additional buffer size is near the limit.
+ return true;
+ } else if (mHeaderPolicy.getExtendedRegionSize()
+ + mBufferWithExtendableBuffer.getUsedAdditionalBufferSize()
+ > MAX_DICT_EXTENDED_REGION_SIZE) {
+ // Total extended region size exceeds the limit.
+ return true;
+ } else if (mBufferWithExtendableBuffer.getTailPosition()
+ >= MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS
+ && mBufferWithExtendableBuffer.getUsedAdditionalBufferSize() > 0) {
+ // Needs to reduce dictionary size.
+ return true;
+ } else if (mHeaderPolicy.isDecayingDict()) {
+ if (mUnigramCount >= DecayingUtils::MAX_UNIGRAM_COUNT) {
+ // Unigram count exceeds the limit.
+ return true;
+ } else if (mBigramCount >= DecayingUtils::MAX_BIGRAM_COUNT) {
+ // Bigram count exceeds the limit.
+ return true;
+ } else if (mindsBlockByGC && mHeaderPolicy.getLastUpdatedTime()
+ + MIN_SECONDS_TO_REQUIRE_GC_WHEN_WRITING < time(0)) {
+ // Time to update probabilities for decaying.
+ return true;
+ }
+ }
+ return false;
+}
+
+void DynamicPatriciaTriePolicy::getProperty(const char *const query, char *const outResult,
+ const int maxResultLength) const {
+ if (strncmp(query, UNIGRAM_COUNT_QUERY, maxResultLength) == 0) {
+ snprintf(outResult, maxResultLength, "%d", mUnigramCount);
+ } else if (strncmp(query, BIGRAM_COUNT_QUERY, maxResultLength) == 0) {
+ snprintf(outResult, maxResultLength, "%d", mBigramCount);
+ }
}
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h
index 06d8095d8..d3150c6fc 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h
@@ -37,7 +37,10 @@ class DynamicPatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
mBufferWithExtendableBuffer(mBuffer->getBuffer() + mHeaderPolicy.getSize(),
mBuffer->getBufferSize() - mHeaderPolicy.getSize()),
mShortcutListPolicy(&mBufferWithExtendableBuffer),
- mBigramListPolicy(&mBufferWithExtendableBuffer, &mShortcutListPolicy) {}
+ mBigramListPolicy(&mBufferWithExtendableBuffer, &mShortcutListPolicy,
+ mHeaderPolicy.isDecayingDict()),
+ mUnigramCount(mHeaderPolicy.getUnigramCount()),
+ mBigramCount(mHeaderPolicy.getBigramCount()) {}
~DynamicPatriciaTriePolicy() {
delete mBuffer;
@@ -89,16 +92,27 @@ class DynamicPatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
void flushWithGC(const char *const filePath);
- bool needsToRunGC() const;
+ bool needsToRunGC(const bool mindsBlockByGC) const;
+
+ void getProperty(const char *const query, char *const outResult,
+ const int maxResultLength) const;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicPatriciaTriePolicy);
+ static const char*const UNIGRAM_COUNT_QUERY;
+ static const char*const BIGRAM_COUNT_QUERY;
+ static const int MAX_DICT_EXTENDED_REGION_SIZE;
+ static const int MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS;
+ static const int MIN_SECONDS_TO_REQUIRE_GC_WHEN_WRITING;
+
const MmappedBuffer *const mBuffer;
const HeaderPolicy mHeaderPolicy;
BufferWithExtendableBuffer mBufferWithExtendableBuffer;
DynamicShortcutListPolicy mShortcutListPolicy;
DynamicBigramListPolicy mBigramListPolicy;
+ int mUnigramCount;
+ int mBigramCount;
};
} // namespace latinime
#endif // LATINIME_DYNAMIC_PATRICIA_TRIE_POLICY_H
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.cpp
index f4a2ef389..601ee663b 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.cpp
@@ -155,6 +155,15 @@ bool DynamicPatriciaTrieReadingHelper::traverseAllPtNodesInPtNodeArrayLevelPreor
// Read node array size and process empty node arrays. Nodes and arrays are counted up in this
// method to avoid an infinite loop.
void DynamicPatriciaTrieReadingHelper::nextPtNodeArray() {
+ if (mReadingState.mPos < 0 || mReadingState.mPos >= mBuffer->getTailPosition()) {
+ // Reading invalid position because of a bug or a broken dictionary.
+ AKLOGE("Reading PtNode array info from invalid dictionary position: %d, dict size: %d",
+ mReadingState.mPos, mBuffer->getTailPosition());
+ ASSERT(false);
+ mIsError = true;
+ mReadingState.mPos = NOT_A_DICT_POS;
+ return;
+ }
mReadingState.mPosOfLastPtNodeArrayHead = mReadingState.mPos;
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(mReadingState.mPos);
const uint8_t *const dictBuf = mBuffer->getBuffer(usesAdditionalBuffer);
@@ -191,6 +200,15 @@ void DynamicPatriciaTrieReadingHelper::nextPtNodeArray() {
// Follow the forward link and read the next node array if exists.
void DynamicPatriciaTrieReadingHelper::followForwardLink() {
+ if (mReadingState.mPos < 0 || mReadingState.mPos >= mBuffer->getTailPosition()) {
+ // Reading invalid position because of bug or broken dictionary.
+ AKLOGE("Reading forward link from invalid dictionary position: %d, dict size: %d",
+ mReadingState.mPos, mBuffer->getTailPosition());
+ ASSERT(false);
+ mIsError = true;
+ mReadingState.mPos = NOT_A_DICT_POS;
+ return;
+ }
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(mReadingState.mPos);
const uint8_t *const dictBuf = mBuffer->getBuffer(usesAdditionalBuffer);
if (usesAdditionalBuffer) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h
index b033eee05..512a4d818 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h
@@ -240,6 +240,7 @@ class DynamicPatriciaTrieReadingHelper {
static const int MAX_NODE_ARRAY_COUNT_TO_AVOID_INFINITE_LOOP;
static const size_t MAX_READING_STATE_STACK_SIZE;
+ // TODO: Introduce error code to track what caused the error.
bool mIsError;
ReadingState mReadingState;
const BufferWithExtendableBuffer *const mBuffer;
@@ -263,7 +264,7 @@ class DynamicPatriciaTrieReadingHelper {
AK_FORCE_INLINE void pushReadingStateToStack() {
if (mReadingStateStack.size() > MAX_READING_STATE_STACK_SIZE) {
- AKLOGI("Reading state stack overflow. Max size: %d", MAX_READING_STATE_STACK_SIZE);
+ AKLOGI("Reading state stack overflow. Max size: %zd", MAX_READING_STATE_STACK_SIZE);
ASSERT(false);
mIsError = true;
mReadingState.mPos = NOT_A_DICT_POS;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
index a51ae5e1d..28124d251 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
@@ -16,9 +16,6 @@
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h"
-#include <cstdio>
-#include <cstring>
-
#include "suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.h"
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_gc_event_listeners.h"
#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h"
@@ -28,19 +25,20 @@
#include "suggest/policyimpl/dictionary/header/header_policy.h"
#include "suggest/policyimpl/dictionary/patricia_trie_reading_utils.h"
#include "suggest/policyimpl/dictionary/shortcut/dynamic_shortcut_list_policy.h"
+#include "suggest/policyimpl/dictionary/utils/decaying_utils.h"
+#include "suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h"
#include "utils/hash_map_compat.h"
namespace latinime {
const int DynamicPatriciaTrieWritingHelper::CHILDREN_POSITION_FIELD_SIZE = 3;
-const char *const DynamicPatriciaTrieWritingHelper::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE =
- ".tmp";
// TODO: Make MAX_DICTIONARY_SIZE 8MB.
const size_t DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE = 2 * 1024 * 1024;
bool DynamicPatriciaTrieWritingHelper::addUnigramWord(
DynamicPatriciaTrieReadingHelper *const readingHelper,
- const int *const wordCodePoints, const int codePointCount, const int probability) {
+ const int *const wordCodePoints, const int codePointCount, const int probability,
+ bool *const outAddedNewUnigram) {
int parentPos = NOT_A_DICT_POS;
while (!readingHelper->isEnd()) {
const int matchedCodePointCount = readingHelper->getPrevTotalCodePointCount();
@@ -58,8 +56,11 @@ bool DynamicPatriciaTrieWritingHelper::addUnigramWord(
const int nextIndex = matchedCodePointCount + j;
if (nextIndex >= codePointCount || !readingHelper->isMatchedCodePoint(j,
wordCodePoints[matchedCodePointCount + j])) {
+ *outAddedNewUnigram = true;
return reallocatePtNodeAndAddNewPtNodes(nodeReader,
- readingHelper->getMergedNodeCodePoints(), j, probability,
+ readingHelper->getMergedNodeCodePoints(), j,
+ getUpdatedProbability(NOT_A_PROBABILITY /* originalProbability */,
+ probability),
wordCodePoints + matchedCodePointCount,
codePointCount - matchedCodePointCount);
}
@@ -67,10 +68,12 @@ bool DynamicPatriciaTrieWritingHelper::addUnigramWord(
// All characters are matched.
if (codePointCount == readingHelper->getTotalCodePointCount()) {
return setPtNodeProbability(nodeReader, probability,
- readingHelper->getMergedNodeCodePoints());
+ readingHelper->getMergedNodeCodePoints(), outAddedNewUnigram);
}
if (!nodeReader->hasChildren()) {
- return createChildrenPtNodeArrayAndAChildPtNode(nodeReader, probability,
+ *outAddedNewUnigram = true;
+ return createChildrenPtNodeArrayAndAChildPtNode(nodeReader,
+ getUpdatedProbability(NOT_A_PROBABILITY /* originalProbability */, probability),
wordCodePoints + readingHelper->getTotalCodePointCount(),
codePointCount - readingHelper->getTotalCodePointCount());
}
@@ -83,14 +86,15 @@ bool DynamicPatriciaTrieWritingHelper::addUnigramWord(
return false;
}
int pos = readingHelper->getPosOfLastForwardLinkField();
+ *outAddedNewUnigram = true;
return createAndInsertNodeIntoPtNodeArray(parentPos,
wordCodePoints + readingHelper->getPrevTotalCodePointCount(),
codePointCount - readingHelper->getPrevTotalCodePointCount(),
- probability, &pos);
+ getUpdatedProbability(NOT_A_PROBABILITY /* originalProbability */, probability), &pos);
}
bool DynamicPatriciaTrieWritingHelper::addBigramWords(const int word0Pos, const int word1Pos,
- const int probability) {
+ const int probability, bool *const outAddedNewBigram) {
int mMergedNodeCodePoints[MAX_WORD_LENGTH];
DynamicPatriciaTrieNodeReader nodeReader(mBuffer, mBigramPolicy, mShortcutPolicy);
nodeReader.fetchNodeInfoInBufferFromPtNodePosAndGetNodeCodePoints(word0Pos, MAX_WORD_LENGTH,
@@ -111,9 +115,11 @@ bool DynamicPatriciaTrieWritingHelper::addBigramWords(const int word0Pos, const
if (nodeReader.getBigramsPos() != NOT_A_DICT_POS) {
// Insert a new bigram entry into the existing bigram list.
int bigramListPos = nodeReader.getBigramsPos();
- return mBigramPolicy->addNewBigramEntryToBigramList(word1Pos, probability, &bigramListPos);
+ return mBigramPolicy->addNewBigramEntryToBigramList(word1Pos, probability, &bigramListPos,
+ outAddedNewBigram);
} else {
// The PtNode doesn't have a bigram list.
+ *outAddedNewBigram = true;
// First, Write a bigram entry at the tail position of the PtNode.
if (!mBigramPolicy->writeNewBigramEntry(word1Pos, probability, &writingPos)) {
return false;
@@ -142,26 +148,32 @@ bool DynamicPatriciaTrieWritingHelper::removeBigramWords(const int word0Pos, con
}
void DynamicPatriciaTrieWritingHelper::writeToDictFile(const char *const fileName,
- const HeaderPolicy *const headerPolicy) {
+ const HeaderPolicy *const headerPolicy, const int unigramCount, const int bigramCount) {
BufferWithExtendableBuffer headerBuffer(0 /* originalBuffer */, 0 /* originalBufferSize */);
- if (!headerPolicy->writeHeaderToBuffer(&headerBuffer, false /* updatesLastUpdatedTime */)) {
+ const int extendedRegionSize = headerPolicy->getExtendedRegionSize() +
+ mBuffer->getUsedAdditionalBufferSize();
+ if (!headerPolicy->writeHeaderToBuffer(&headerBuffer, false /* updatesLastUpdatedTime */,
+ unigramCount, bigramCount, extendedRegionSize)) {
return;
}
- flushAllToFile(fileName, &headerBuffer, mBuffer);
+ DictFileWritingUtils::flushAllHeaderAndBodyToFile(fileName, &headerBuffer, mBuffer);
}
void DynamicPatriciaTrieWritingHelper::writeToDictFileWithGC(const int rootPtNodeArrayPos,
const char *const fileName, const HeaderPolicy *const headerPolicy) {
- BufferWithExtendableBuffer headerBuffer(0 /* originalBuffer */, 0 /* originalBufferSize */);
- if (!headerPolicy->writeHeaderToBuffer(&headerBuffer, true /* updatesLastUpdatedTime */)) {
- return;
- }
BufferWithExtendableBuffer newDictBuffer(0 /* originalBuffer */, 0 /* originalBufferSize */,
MAX_DICTIONARY_SIZE);
- if (!runGC(rootPtNodeArrayPos, &newDictBuffer)) {
+ int unigramCount = 0;
+ int bigramCount = 0;
+ if (!runGC(rootPtNodeArrayPos, &newDictBuffer, &unigramCount, &bigramCount)) {
+ return;
+ }
+ BufferWithExtendableBuffer headerBuffer(0 /* originalBuffer */, 0 /* originalBufferSize */);
+ if (!headerPolicy->writeHeaderToBuffer(&headerBuffer, true /* updatesLastUpdatedTime */,
+ unigramCount, bigramCount, 0 /* extendedRegionSize */)) {
return;
}
- flushAllToFile(fileName, &headerBuffer, &newDictBuffer);
+ DictFileWritingUtils::flushAllHeaderAndBodyToFile(fileName, &headerBuffer, &newDictBuffer);
}
bool DynamicPatriciaTrieWritingHelper::markNodeAsDeleted(
@@ -339,23 +351,28 @@ bool DynamicPatriciaTrieWritingHelper::createAndInsertNodeIntoPtNodeArray(const
bool DynamicPatriciaTrieWritingHelper::setPtNodeProbability(
const DynamicPatriciaTrieNodeReader *const originalPtNode, const int probability,
- const int *const codePoints) {
+ const int *const codePoints, bool *const outAddedNewUnigram) {
if (originalPtNode->isTerminal()) {
// Overwrites the probability.
+ *outAddedNewUnigram = false;
+ const int probabilityToWrite = getUpdatedProbability(originalPtNode->getProbability(),
+ probability);
int probabilityFieldPos = originalPtNode->getProbabilityFieldPos();
if (!DynamicPatriciaTrieWritingUtils::writeProbabilityAndAdvancePosition(mBuffer,
- probability, &probabilityFieldPos)) {
+ probabilityToWrite, &probabilityFieldPos)) {
return false;
}
} else {
// Make the node terminal and write the probability.
+ *outAddedNewUnigram = true;
int movedPos = mBuffer->getTailPosition();
if (!markNodeAsMovedAndSetPosition(originalPtNode, movedPos, movedPos)) {
return false;
}
if (!writePtNodeToBufferByCopyingPtNodeInfo(mBuffer, originalPtNode,
originalPtNode->getParentPos(), codePoints, originalPtNode->getCodePointCount(),
- probability, &movedPos)) {
+ getUpdatedProbability(NOT_A_PROBABILITY /* originalProbability */, probability),
+ &movedPos)) {
return false;
}
}
@@ -463,72 +480,23 @@ bool DynamicPatriciaTrieWritingHelper::reallocatePtNodeAndAddNewPtNodes(
return true;
}
-// TODO: Create a struct which contains header, body and etc... and use here as an argument.
-void DynamicPatriciaTrieWritingHelper::flushAllToFile(const char *const fileName,
- BufferWithExtendableBuffer *const dictHeader,
- BufferWithExtendableBuffer *const dictBody) const {
- const int tmpFileNameBufSize = strlen(fileName)
- + strlen(TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE) + 1 /* terminator */;
- // Name of a temporary file used for writing that is a connected string of original name and
- // TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE.
- char tmpFileName[tmpFileNameBufSize];
- snprintf(tmpFileName, tmpFileNameBufSize, "%s%s", fileName,
- TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE);
- FILE *const file = fopen(tmpFileName, "wb");
- if (!file) {
- AKLOGI("Dictionary file %s cannnot be opened.", tmpFileName);
- ASSERT(false);
- return;
- }
- // Write the dictionary header.
- if (!writeBufferToFilePointer(file, dictHeader)) {
- remove(tmpFileName);
- AKLOGI("Dictionary header cannnot be written. size: %d", dictHeader->getTailPosition());
- ASSERT(false);
- return;
- }
- // Write the dictionary body.
- if (!writeBufferToFilePointer(file, dictBody)) {
- remove(tmpFileName);
- AKLOGI("Dictionary body cannnot be written. size: %d", dictBody->getTailPosition());
- ASSERT(false);
- return;
- }
- fclose(file);
- rename(tmpFileName, fileName);
-}
-
-// This closes file pointer when an error is caused and returns whether the writing was succeeded
-// or not.
-bool DynamicPatriciaTrieWritingHelper::writeBufferToFilePointer(FILE *const file,
- const BufferWithExtendableBuffer *const buffer) const {
- const int originalBufSize = buffer->getOriginalBufferSize();
- if (originalBufSize > 0 && fwrite(buffer->getBuffer(false /* usesAdditionalBuffer */),
- originalBufSize, 1, file) < 1) {
- fclose(file);
- return false;
- }
- const int additionalBufSize = buffer->getTailPosition() - buffer->getOriginalBufferSize();
- if (additionalBufSize > 0 && fwrite(buffer->getBuffer(true /* usesAdditionalBuffer */),
- additionalBufSize, 1, file) < 1) {
- fclose(file);
- return false;
- }
- return true;
-}
-
bool DynamicPatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
- BufferWithExtendableBuffer *const bufferToWrite) {
+ BufferWithExtendableBuffer *const bufferToWrite, int *const outUnigramCount,
+ int *const outBigramCount) {
DynamicPatriciaTrieReadingHelper readingHelper(mBuffer, mBigramPolicy, mShortcutPolicy);
readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos);
DynamicPatriciaTrieGcEventListeners
::TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted
traversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted(
- this, mBuffer);
+ this, mBuffer, mIsDecayingDict);
if (!readingHelper.traverseAllPtNodesInPostorderDepthFirstManner(
&traversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted)) {
return false;
}
+ if (mIsDecayingDict && traversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted
+ .getValidUnigramCount() > DecayingUtils::MAX_UNIGRAM_COUNT_AFTER_GC) {
+ // TODO: Remove more unigrams.
+ }
readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos);
DynamicPatriciaTrieGcEventListeners::TraversePolicyToUpdateBigramProbability
@@ -538,6 +506,11 @@ bool DynamicPatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
return false;
}
+ if (mIsDecayingDict && traversePolicyToUpdateBigramProbability.getValidBigramEntryCount()
+ > DecayingUtils::MAX_BIGRAM_COUNT_AFTER_GC) {
+ // TODO: Remove more bigrams.
+ }
+
// Mapping from positions in mBuffer to positions in bufferToWrite.
DictPositionRelocationMap dictPositionRelocationMap;
readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos);
@@ -551,7 +524,8 @@ bool DynamicPatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
// Create policy instance for the GCed dictionary.
DynamicShortcutListPolicy newDictShortcutPolicy(bufferToWrite);
- DynamicBigramListPolicy newDictBigramPolicy(bufferToWrite, &newDictShortcutPolicy);
+ DynamicBigramListPolicy newDictBigramPolicy(bufferToWrite, &newDictShortcutPolicy,
+ mIsDecayingDict);
// Create reading helper for the GCed dictionary.
DynamicPatriciaTrieReadingHelper newDictReadingHelper(bufferToWrite, &newDictBigramPolicy,
&newDictShortcutPolicy);
@@ -563,7 +537,18 @@ bool DynamicPatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
&traversePolicyToUpdateAllPositionFields)) {
return false;
}
+ *outUnigramCount = traversePolicyToUpdateAllPositionFields.getUnigramCount();
+ *outBigramCount = traversePolicyToUpdateAllPositionFields.getBigramCount();
return true;
}
+int DynamicPatriciaTrieWritingHelper::getUpdatedProbability(const int originalProbability,
+ const int newProbability) {
+ if (mIsDecayingDict) {
+ return DecayingUtils::getUpdatedUnigramProbability(originalProbability, newProbability);
+ } else {
+ return newProbability;
+ }
+}
+
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h
index 028fa6075..ecee2cdbf 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h
@@ -17,7 +17,6 @@
#ifndef LATINIME_DYNAMIC_PATRICIA_TRIE_WRITING_HELPER_H
#define LATINIME_DYNAMIC_PATRICIA_TRIE_WRITING_HELPER_H
-#include <cstdio>
#include <stdint.h>
#include "defines.h"
@@ -48,24 +47,30 @@ class DynamicPatriciaTrieWritingHelper {
DISALLOW_COPY_AND_ASSIGN(DictPositionRelocationMap);
};
+ static const size_t MAX_DICTIONARY_SIZE;
+
DynamicPatriciaTrieWritingHelper(BufferWithExtendableBuffer *const buffer,
DynamicBigramListPolicy *const bigramPolicy,
- DynamicShortcutListPolicy *const shortcutPolicy)
- : mBuffer(buffer), mBigramPolicy(bigramPolicy), mShortcutPolicy(shortcutPolicy) {}
+ DynamicShortcutListPolicy *const shortcutPolicy, const bool isDecayingDict)
+ : mBuffer(buffer), mBigramPolicy(bigramPolicy), mShortcutPolicy(shortcutPolicy),
+ mIsDecayingDict(isDecayingDict) {}
~DynamicPatriciaTrieWritingHelper() {}
// Add a word to the dictionary. If the word already exists, update the probability.
bool addUnigramWord(DynamicPatriciaTrieReadingHelper *const readingHelper,
- const int *const wordCodePoints, const int codePointCount, const int probability);
+ const int *const wordCodePoints, const int codePointCount, const int probability,
+ bool *const outAddedNewUnigram);
// Add a bigram relation from word0Pos to word1Pos.
- bool addBigramWords(const int word0Pos, const int word1Pos, const int probability);
+ bool addBigramWords(const int word0Pos, const int word1Pos, const int probability,
+ bool *const outAddedNewBigram);
// Remove a bigram relation from word0Pos to word1Pos.
bool removeBigramWords(const int word0Pos, const int word1Pos);
- void writeToDictFile(const char *const fileName, const HeaderPolicy *const headerPolicy);
+ void writeToDictFile(const char *const fileName, const HeaderPolicy *const headerPolicy,
+ const int unigramCount, const int bigramCount);
void writeToDictFileWithGC(const int rootPtNodeArrayPos, const char *const fileName,
const HeaderPolicy *const headerPolicy);
@@ -85,12 +90,11 @@ class DynamicPatriciaTrieWritingHelper {
DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicPatriciaTrieWritingHelper);
static const int CHILDREN_POSITION_FIELD_SIZE;
- static const char *const TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE;
- static const size_t MAX_DICTIONARY_SIZE;
BufferWithExtendableBuffer *const mBuffer;
DynamicBigramListPolicy *const mBigramPolicy;
DynamicShortcutListPolicy *const mShortcutPolicy;
+ const bool mIsDecayingDict;
bool markNodeAsMovedAndSetPosition(const DynamicPatriciaTrieNodeReader *const nodeToUpdate,
const int movedPos, const int bigramLinkedNodePos);
@@ -109,7 +113,7 @@ class DynamicPatriciaTrieWritingHelper {
const int nodeCodePointCount, const int probability, int *const forwardLinkFieldPos);
bool setPtNodeProbability(const DynamicPatriciaTrieNodeReader *const originalNode,
- const int probability, const int *const codePoints);
+ const int probability, const int *const codePoints, bool *const outAddedNewUnigram);
bool createChildrenPtNodeArrayAndAChildPtNode(
const DynamicPatriciaTrieNodeReader *const parentNode, const int probability,
@@ -124,14 +128,10 @@ class DynamicPatriciaTrieWritingHelper {
const int probabilityOfNewPtNode, const int *const newNodeCodePoints,
const int newNodeCodePointCount);
- void flushAllToFile(const char *const fileName,
- BufferWithExtendableBuffer *const dictHeader,
- BufferWithExtendableBuffer *const dictBody) const;
-
- bool writeBufferToFilePointer(FILE *const file,
- const BufferWithExtendableBuffer *const buffer) const;
+ bool runGC(const int rootPtNodeArrayPos, BufferWithExtendableBuffer *const bufferToWrite,
+ int *const outUnigramCount, int *const outBigramCount);
- bool runGC(const int rootPtNodeArrayPos, BufferWithExtendableBuffer *const bufferToWrite);
+ int getUpdatedProbability(const int originalProbability, const int newProbability);
};
} // namespace latinime
#endif /* LATINIME_DYNAMIC_PATRICIA_TRIE_WRITING_HELPER_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp
index 5a3983776..30ff10cd6 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp
@@ -36,6 +36,16 @@ const int DynamicPatriciaTrieWritingUtils::DICT_OFFSET_NEGATIVE_FLAG = 0x800000;
const int DynamicPatriciaTrieWritingUtils::PROBABILITY_FIELD_SIZE = 1;
const int DynamicPatriciaTrieWritingUtils::NODE_FLAG_FIELD_SIZE = 1;
+/* static */ bool DynamicPatriciaTrieWritingUtils::writeEmptyDictionary(
+ BufferWithExtendableBuffer *const buffer, const int rootPos) {
+ int writingPos = rootPos;
+ if (!writePtNodeArraySizeAndAdvancePosition(buffer, 0 /* arraySize */, &writingPos)) {
+ return false;
+ }
+ return writeForwardLinkPositionAndAdvancePosition(buffer, NOT_A_DICT_POS /* forwardLinkPos */,
+ &writingPos);
+}
+
/* static */ bool DynamicPatriciaTrieWritingUtils::writeForwardLinkPositionAndAdvancePosition(
BufferWithExtendableBuffer *const buffer, const int forwardLinkPos,
int *const forwardLinkFieldPos) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h
index a37e9fb3d..af76bc6b5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h
@@ -30,6 +30,8 @@ class DynamicPatriciaTrieWritingUtils {
public:
static const int NODE_FLAG_FIELD_SIZE;
+ static bool writeEmptyDictionary(BufferWithExtendableBuffer *const buffer, const int rootPos);
+
static bool writeForwardLinkPositionAndAdvancePosition(
BufferWithExtendableBuffer *const buffer, const int forwardLinkPos,
int *const forwardLinkFieldPos);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
index 47ace23a1..9ce9994dd 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
@@ -16,16 +16,17 @@
#include "suggest/policyimpl/dictionary/header/header_policy.h"
-#include <cstddef>
-#include <cstdio>
-#include <ctime>
-
namespace latinime {
+// Note that these are corresponding definitions in Java side in FormatSpec.FileHeader.
const char *const HeaderPolicy::MULTIPLE_WORDS_DEMOTION_RATE_KEY = "MULTIPLE_WORDS_DEMOTION_RATE";
-const char *const HeaderPolicy::USES_FORGETTING_CURVE_KEY = "USES_FORGETTING_CURVE";
+// TODO: Change attribute string to "IS_DECAYING_DICT".
+const char *const HeaderPolicy::IS_DECAYING_DICT_KEY = "USES_FORGETTING_CURVE";
const char *const HeaderPolicy::LAST_UPDATED_TIME_KEY = "date";
-const float HeaderPolicy::DEFAULT_MULTIPLE_WORD_COST_MULTIPLIER = 1.0f;
+const char *const HeaderPolicy::UNIGRAM_COUNT_KEY = "UNIGRAM_COUNT";
+const char *const HeaderPolicy::BIGRAM_COUNT_KEY = "BIGRAM_COUNT";
+const char *const HeaderPolicy::EXTENDED_REGION_SIZE_KEY = "EXTENDED_REGION_SIZE";
+const int HeaderPolicy::DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE = 100;
const float HeaderPolicy::MULTIPLE_WORD_COST_MULTIPLIER_SCALE = 100.0f;
// Used for logging. Question mark is used to indicate that the key is not found.
@@ -37,7 +38,7 @@ void HeaderPolicy::readHeaderValueOrQuestionMark(const char *const key, int *out
return;
}
std::vector<int> keyCodePointVector;
- insertCharactersIntoVector(key, &keyCodePointVector);
+ HeaderReadWriteUtils::insertCharactersIntoVector(key, &keyCodePointVector);
HeaderReadWriteUtils::AttributeMap::const_iterator it = mAttributeMap.find(keyCodePointVector);
if (it == mAttributeMap.end()) {
// The key was not found.
@@ -53,51 +54,17 @@ void HeaderPolicy::readHeaderValueOrQuestionMark(const char *const key, int *out
}
float HeaderPolicy::readMultipleWordCostMultiplier() const {
- int attributeValue = 0;
- if (getAttributeValueAsInt(MULTIPLE_WORDS_DEMOTION_RATE_KEY, &attributeValue)) {
- if (attributeValue <= 0) {
- return static_cast<float>(MAX_VALUE_FOR_WEIGHTING);
- }
- return MULTIPLE_WORD_COST_MULTIPLIER_SCALE / static_cast<float>(attributeValue);
- } else {
- return DEFAULT_MULTIPLE_WORD_COST_MULTIPLIER;
- }
-}
-
-bool HeaderPolicy::readUsesForgettingCurveFlag() const {
- int attributeValue = 0;
- if (getAttributeValueAsInt(USES_FORGETTING_CURVE_KEY, &attributeValue)) {
- return attributeValue != 0;
- } else {
- return false;
- }
-}
-
-// Returns S_INT_MIN when the key is not found or the value is invalid.
-int HeaderPolicy::readLastUpdatedTime() const {
- int attributeValue = 0;
- if (getAttributeValueAsInt(LAST_UPDATED_TIME_KEY, &attributeValue)) {
- return attributeValue;
- } else {
- return S_INT_MIN;
- }
-}
-
-// Returns whether the key is found or not and stores the found value into outValue.
-bool HeaderPolicy::getAttributeValueAsInt(const char *const key, int *const outValue) const {
- std::vector<int> keyVector;
- insertCharactersIntoVector(key, &keyVector);
- HeaderReadWriteUtils::AttributeMap::const_iterator it = mAttributeMap.find(keyVector);
- if (it == mAttributeMap.end()) {
- // The key was not found.
- return false;
+ const int demotionRate = HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
+ MULTIPLE_WORDS_DEMOTION_RATE_KEY, DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE);
+ if (demotionRate <= 0) {
+ return static_cast<float>(MAX_VALUE_FOR_WEIGHTING);
}
- *outValue = parseIntAttributeValue(&(it->second));
- return true;
+ return MULTIPLE_WORD_COST_MULTIPLIER_SCALE / static_cast<float>(demotionRate);
}
bool HeaderPolicy::writeHeaderToBuffer(BufferWithExtendableBuffer *const bufferToWrite,
- const bool updatesLastUpdatedTime) const {
+ const bool updatesLastUpdatedTime, const int unigramCount, const int bigramCount,
+ const int extendedRegionSize) const {
int writingPos = 0;
if (!HeaderReadWriteUtils::writeDictionaryVersion(bufferToWrite, mDictFormatVersion,
&writingPos)) {
@@ -113,26 +80,19 @@ bool HeaderPolicy::writeHeaderToBuffer(BufferWithExtendableBuffer *const bufferT
&writingPos)) {
return false;
}
+ HeaderReadWriteUtils::AttributeMap attributeMapTowrite(mAttributeMap);
+ HeaderReadWriteUtils::setIntAttribute(&attributeMapTowrite, UNIGRAM_COUNT_KEY, unigramCount);
+ HeaderReadWriteUtils::setIntAttribute(&attributeMapTowrite, BIGRAM_COUNT_KEY, bigramCount);
+ HeaderReadWriteUtils::setIntAttribute(&attributeMapTowrite, EXTENDED_REGION_SIZE_KEY,
+ extendedRegionSize);
if (updatesLastUpdatedTime) {
// Set current time as a last updated time.
- HeaderReadWriteUtils::AttributeMap attributeMapTowrite(mAttributeMap);
- std::vector<int> updatedTimekey;
- insertCharactersIntoVector(LAST_UPDATED_TIME_KEY, &updatedTimekey);
- const time_t currentTime = time(NULL);
- std::vector<int> updatedTimeValue;
- char charBuf[LARGEST_INT_DIGIT_COUNT + 1];
- snprintf(charBuf, LARGEST_INT_DIGIT_COUNT + 1, "%ld", currentTime);
- insertCharactersIntoVector(charBuf, &updatedTimeValue);
- attributeMapTowrite[updatedTimekey] = updatedTimeValue;
- if (!HeaderReadWriteUtils::writeHeaderAttributes(bufferToWrite, &attributeMapTowrite,
- &writingPos)) {
- return false;
- }
- } else {
- if (!HeaderReadWriteUtils::writeHeaderAttributes(bufferToWrite, &mAttributeMap,
- &writingPos)) {
- return false;
- }
+ HeaderReadWriteUtils::setIntAttribute(&attributeMapTowrite, LAST_UPDATED_TIME_KEY,
+ time(0));
+ }
+ if (!HeaderReadWriteUtils::writeHeaderAttributes(bufferToWrite, &attributeMapTowrite,
+ &writingPos)) {
+ return false;
}
// Writes an actual header size.
if (!HeaderReadWriteUtils::writeDictionaryHeaderSize(bufferToWrite, writingPos,
@@ -149,30 +109,4 @@ bool HeaderPolicy::writeHeaderToBuffer(BufferWithExtendableBuffer *const bufferT
return attributeMap;
}
-/* static */ int HeaderPolicy::parseIntAttributeValue(
- const std::vector<int> *const attributeValue) {
- int value = 0;
- bool isNegative = false;
- for (size_t i = 0; i < attributeValue->size(); ++i) {
- if (i == 0 && attributeValue->at(i) == '-') {
- isNegative = true;
- } else {
- if (!isdigit(attributeValue->at(i))) {
- // If not a number, return S_INT_MIN
- return S_INT_MIN;
- }
- value *= 10;
- value += attributeValue->at(i) - '0';
- }
- }
- return isNegative ? -value : value;
-}
-
-/* static */ void HeaderPolicy::insertCharactersIntoVector(const char *const characters,
- std::vector<int> *const vector) {
- for (int i = 0; characters[i]; ++i) {
- vector->push_back(characters[i]);
- }
-}
-
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
index 6b396f3f2..4261667fa 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
@@ -17,7 +17,7 @@
#ifndef LATINIME_HEADER_POLICY_H
#define LATINIME_HEADER_POLICY_H
-#include <cctype>
+#include <ctime>
#include <stdint.h>
#include "defines.h"
@@ -29,15 +29,36 @@ namespace latinime {
class HeaderPolicy : public DictionaryHeaderStructurePolicy {
public:
- explicit HeaderPolicy(const uint8_t *const dictBuf, const int dictSize)
- : mDictBuf(dictBuf),
- mDictFormatVersion(FormatUtils::detectFormatVersion(dictBuf, dictSize)),
+ // Reads information from existing dictionary buffer.
+ HeaderPolicy(const uint8_t *const dictBuf, const int dictSize)
+ : mDictFormatVersion(FormatUtils::detectFormatVersion(dictBuf, dictSize)),
mDictionaryFlags(HeaderReadWriteUtils::getFlags(dictBuf)),
mSize(HeaderReadWriteUtils::getHeaderSize(dictBuf)),
- mAttributeMap(createAttributeMapAndReadAllAttributes(mDictBuf)),
+ mAttributeMap(createAttributeMapAndReadAllAttributes(dictBuf)),
mMultiWordCostMultiplier(readMultipleWordCostMultiplier()),
- mUsesForgettingCurve(readUsesForgettingCurveFlag()),
- mLastUpdatedTime(readLastUpdatedTime()) {}
+ mIsDecayingDict(HeaderReadWriteUtils::readBoolAttributeValue(&mAttributeMap,
+ IS_DECAYING_DICT_KEY, false /* defaultValue */)),
+ mLastUpdatedTime(HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
+ LAST_UPDATED_TIME_KEY, time(0) /* defaultValue */)),
+ mUnigramCount(HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
+ UNIGRAM_COUNT_KEY, 0 /* defaultValue */)),
+ mBigramCount(HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
+ BIGRAM_COUNT_KEY, 0 /* defaultValue */)),
+ mExtendedRegionSize(HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
+ EXTENDED_REGION_SIZE_KEY, 0 /* defaultValue */)) {}
+
+ // Constructs header information using an attribute map.
+ HeaderPolicy(const FormatUtils::FORMAT_VERSION dictFormatVersion,
+ const HeaderReadWriteUtils::AttributeMap *const attributeMap)
+ : mDictFormatVersion(dictFormatVersion),
+ mDictionaryFlags(HeaderReadWriteUtils::createAndGetDictionaryFlagsUsingAttributeMap(
+ attributeMap)), mSize(0), mAttributeMap(*attributeMap),
+ mMultiWordCostMultiplier(readMultipleWordCostMultiplier()),
+ mIsDecayingDict(HeaderReadWriteUtils::readBoolAttributeValue(&mAttributeMap,
+ IS_DECAYING_DICT_KEY, false /* defaultValue */)),
+ mLastUpdatedTime(HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
+ LAST_UPDATED_TIME_KEY, time(0) /* defaultValue */)),
+ mUnigramCount(0), mBigramCount(0), mExtendedRegionSize(0) {}
~HeaderPolicy() {}
@@ -61,53 +82,60 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
return mMultiWordCostMultiplier;
}
- AK_FORCE_INLINE bool usesForgettingCurve() const {
- return mUsesForgettingCurve;
+ AK_FORCE_INLINE bool isDecayingDict() const {
+ return mIsDecayingDict;
}
AK_FORCE_INLINE int getLastUpdatedTime() const {
return mLastUpdatedTime;
}
+ AK_FORCE_INLINE int getUnigramCount() const {
+ return mUnigramCount;
+ }
+
+ AK_FORCE_INLINE int getBigramCount() const {
+ return mBigramCount;
+ }
+
+ AK_FORCE_INLINE int getExtendedRegionSize() const {
+ return mExtendedRegionSize;
+ }
+
void readHeaderValueOrQuestionMark(const char *const key,
int *outValue, int outValueSize) const;
bool writeHeaderToBuffer(BufferWithExtendableBuffer *const bufferToWrite,
- const bool updatesLastUpdatedTime) const;
+ const bool updatesLastUpdatedTime, const int unigramCount,
+ const int bigramCount, const int extendedRegionSize) const;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(HeaderPolicy);
static const char *const MULTIPLE_WORDS_DEMOTION_RATE_KEY;
- static const char *const USES_FORGETTING_CURVE_KEY;
+ static const char *const IS_DECAYING_DICT_KEY;
static const char *const LAST_UPDATED_TIME_KEY;
- static const float DEFAULT_MULTIPLE_WORD_COST_MULTIPLIER;
+ static const char *const UNIGRAM_COUNT_KEY;
+ static const char *const BIGRAM_COUNT_KEY;
+ static const char *const EXTENDED_REGION_SIZE_KEY;
+ static const int DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE;
static const float MULTIPLE_WORD_COST_MULTIPLIER_SCALE;
- const uint8_t *const mDictBuf;
const FormatUtils::FORMAT_VERSION mDictFormatVersion;
const HeaderReadWriteUtils::DictionaryFlags mDictionaryFlags;
const int mSize;
HeaderReadWriteUtils::AttributeMap mAttributeMap;
const float mMultiWordCostMultiplier;
- const bool mUsesForgettingCurve;
+ const bool mIsDecayingDict;
const int mLastUpdatedTime;
+ const int mUnigramCount;
+ const int mBigramCount;
+ const int mExtendedRegionSize;
float readMultipleWordCostMultiplier() const;
- bool readUsesForgettingCurveFlag() const;
-
- int readLastUpdatedTime() const;
-
- bool getAttributeValueAsInt(const char *const key, int *const outValue) const;
-
static HeaderReadWriteUtils::AttributeMap createAttributeMapAndReadAllAttributes(
const uint8_t *const dictBuf);
-
- static int parseIntAttributeValue(const std::vector<int> *const attributeValue);
-
- static void insertCharactersIntoVector(
- const char *const characters, std::vector<int> *const vector);
};
} // namespace latinime
#endif /* LATINIME_HEADER_POLICY_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp
index 80fe88671..2694ce8d5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp
@@ -16,6 +16,8 @@
#include "suggest/policyimpl/dictionary/header/header_read_write_utils.h"
+#include <cctype>
+#include <cstdio>
#include <vector>
#include "defines.h"
@@ -43,6 +45,13 @@ const HeaderReadWriteUtils::DictionaryFlags
const HeaderReadWriteUtils::DictionaryFlags
HeaderReadWriteUtils::FRENCH_LIGATURE_PROCESSING_FLAG = 0x4;
+// Note that these are corresponding definitions in Java side in FormatSpec.FileHeader.
+const char *const HeaderReadWriteUtils::SUPPORTS_DYNAMIC_UPDATE_KEY = "SUPPORTS_DYNAMIC_UPDATE";
+const char *const HeaderReadWriteUtils::REQUIRES_GERMAN_UMLAUT_PROCESSING_KEY =
+ "REQUIRES_GERMAN_UMLAUT_PROCESSING";
+const char *const HeaderReadWriteUtils::REQUIRES_FRENCH_LIGATURE_PROCESSING_KEY =
+ "REQUIRES_FRENCH_LIGATURE_PROCESSING";
+
/* static */ int HeaderReadWriteUtils::getHeaderSize(const uint8_t *const dictBuf) {
// See the format of the header in the comment in
// BinaryDictionaryFormatUtils::detectFormatVersion()
@@ -56,6 +65,22 @@ const HeaderReadWriteUtils::DictionaryFlags
HEADER_MAGIC_NUMBER_SIZE + HEADER_DICTIONARY_VERSION_SIZE);
}
+/* static */ HeaderReadWriteUtils::DictionaryFlags
+ HeaderReadWriteUtils::createAndGetDictionaryFlagsUsingAttributeMap(
+ const HeaderReadWriteUtils::AttributeMap *const attributeMap) {
+ const bool requiresGermanUmlautProcessing = readBoolAttributeValue(attributeMap,
+ REQUIRES_GERMAN_UMLAUT_PROCESSING_KEY, false /* defaultValue */);
+ const bool requiresFrenchLigatureProcessing = readBoolAttributeValue(attributeMap,
+ REQUIRES_FRENCH_LIGATURE_PROCESSING_KEY, false /* defaultValue */);
+ const bool supportsDynamicUpdate = readBoolAttributeValue(attributeMap,
+ SUPPORTS_DYNAMIC_UPDATE_KEY, false /* defaultValue */);
+ DictionaryFlags dictflags = NO_FLAGS;
+ dictflags |= requiresGermanUmlautProcessing ? GERMAN_UMLAUT_PROCESSING_FLAG : 0;
+ dictflags |= requiresFrenchLigatureProcessing ? FRENCH_LIGATURE_PROCESSING_FLAG : 0;
+ dictflags |= supportsDynamicUpdate ? SUPPORTS_DYNAMIC_UPDATE_FLAG : 0;
+ return dictflags;
+}
+
/* static */ void HeaderReadWriteUtils::fetchAllHeaderAttributes(const uint8_t *const dictBuf,
AttributeMap *const headerAttributes) {
const int headerSize = getHeaderSize(dictBuf);
@@ -128,4 +153,72 @@ const HeaderReadWriteUtils::DictionaryFlags
return true;
}
+/* static */ void HeaderReadWriteUtils::setBoolAttribute(AttributeMap *const headerAttributes,
+ const char *const key, const bool value) {
+ setIntAttribute(headerAttributes, key, value ? 1 : 0);
+}
+
+/* static */ void HeaderReadWriteUtils::setIntAttribute(AttributeMap *const headerAttributes,
+ const char *const key, const int value) {
+ AttributeMap::key_type keyVector;
+ insertCharactersIntoVector(key, &keyVector);
+ setIntAttributeInner(headerAttributes, &keyVector, value);
+}
+
+/* static */ void HeaderReadWriteUtils::setIntAttributeInner(AttributeMap *const headerAttributes,
+ const AttributeMap::key_type *const key, const int value) {
+ AttributeMap::mapped_type valueVector;
+ char charBuf[LARGEST_INT_DIGIT_COUNT + 1];
+ snprintf(charBuf, LARGEST_INT_DIGIT_COUNT + 1, "%d", value);
+ insertCharactersIntoVector(charBuf, &valueVector);
+ (*headerAttributes)[*key] = valueVector;
+}
+
+/* static */ bool HeaderReadWriteUtils::readBoolAttributeValue(
+ const AttributeMap *const headerAttributes, const char *const key,
+ const bool defaultValue) {
+ const int intDefaultValue = defaultValue ? 1 : 0;
+ const int intValue = readIntAttributeValue(headerAttributes, key, intDefaultValue);
+ return intValue != 0;
+}
+
+/* static */ int HeaderReadWriteUtils::readIntAttributeValue(
+ const AttributeMap *const headerAttributes, const char *const key,
+ const int defaultValue) {
+ AttributeMap::key_type keyVector;
+ insertCharactersIntoVector(key, &keyVector);
+ return readIntAttributeValueInner(headerAttributes, &keyVector, defaultValue);
+}
+
+/* static */ int HeaderReadWriteUtils::readIntAttributeValueInner(
+ const AttributeMap *const headerAttributes, const AttributeMap::key_type *const key,
+ const int defaultValue) {
+ AttributeMap::const_iterator it = headerAttributes->find(*key);
+ if (it != headerAttributes->end()) {
+ int value = 0;
+ bool isNegative = false;
+ for (size_t i = 0; i < it->second.size(); ++i) {
+ if (i == 0 && it->second.at(i) == '-') {
+ isNegative = true;
+ } else {
+ if (!isdigit(it->second.at(i))) {
+ // If not a number.
+ return defaultValue;
+ }
+ value *= 10;
+ value += it->second.at(i) - '0';
+ }
+ }
+ return isNegative ? -value : value;
+ }
+ return defaultValue;
+}
+
+/* static */ void HeaderReadWriteUtils::insertCharactersIntoVector(const char *const characters,
+ std::vector<int> *const vector) {
+ for (int i = 0; characters[i]; ++i) {
+ vector->push_back(characters[i]);
+ }
+}
+
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h
index 6cce73375..225968323 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h
@@ -54,6 +54,9 @@ class HeaderReadWriteUtils {
+ HEADER_SIZE_FIELD_SIZE;
}
+ static DictionaryFlags createAndGetDictionaryFlagsUsingAttributeMap(
+ const HeaderReadWriteUtils::AttributeMap *const attributeMap);
+
static void fetchAllHeaderAttributes(const uint8_t *const dictBuf,
AttributeMap *const headerAttributes);
@@ -69,6 +72,24 @@ class HeaderReadWriteUtils {
static bool writeHeaderAttributes(BufferWithExtendableBuffer *const buffer,
const AttributeMap *const headerAttributes, int *const writingPos);
+ /**
+ * Methods for header attributes.
+ */
+ static void setBoolAttribute(AttributeMap *const headerAttributes,
+ const char *const key, const bool value);
+
+ static void setIntAttribute(AttributeMap *const headerAttributes,
+ const char *const key, const int value);
+
+ static bool readBoolAttributeValue(const AttributeMap *const headerAttributes,
+ const char *const key, const bool defaultValue);
+
+ static int readIntAttributeValue(const AttributeMap *const headerAttributes,
+ const char *const key, const int defaultValue);
+
+ static void insertCharactersIntoVector(const char *const characters,
+ AttributeMap::key_type *const key);
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(HeaderReadWriteUtils);
@@ -87,7 +108,16 @@ class HeaderReadWriteUtils {
static const DictionaryFlags GERMAN_UMLAUT_PROCESSING_FLAG;
static const DictionaryFlags SUPPORTS_DYNAMIC_UPDATE_FLAG;
static const DictionaryFlags FRENCH_LIGATURE_PROCESSING_FLAG;
- static const DictionaryFlags CONTAINS_BIGRAMS_FLAG;
+
+ static const char *const SUPPORTS_DYNAMIC_UPDATE_KEY;
+ static const char *const REQUIRES_GERMAN_UMLAUT_PROCESSING_KEY;
+ static const char *const REQUIRES_FRENCH_LIGATURE_PROCESSING_KEY;
+
+ static void setIntAttributeInner(AttributeMap *const headerAttributes,
+ const AttributeMap::key_type *const key, const int value);
+
+ static int readIntAttributeValueInner(const AttributeMap *const headerAttributes,
+ const AttributeMap::key_type *const key, const int defaultValue);
};
}
#endif /* LATINIME_HEADER_READ_WRITE_UTILS_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp
index 5269795a4..8a84bd261 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp
@@ -31,9 +31,21 @@ void PatriciaTriePolicy::createAndGetAllChildNodes(const DicNode *const dicNode,
return;
}
int nextPos = dicNode->getChildrenPos();
+ if (nextPos < 0 || nextPos >= mDictBufferSize) {
+ AKLOGE("Children PtNode array position is invalid. pos: %d, dict size: %d",
+ nextPos, mDictBufferSize);
+ ASSERT(false);
+ return;
+ }
const int childCount = PatriciaTrieReadingUtils::getPtNodeArraySizeAndAdvancePosition(
mDictRoot, &nextPos);
for (int i = 0; i < childCount; i++) {
+ if (nextPos < 0 || nextPos >= mDictBufferSize) {
+ AKLOGE("Child PtNode position is invalid. pos: %d, dict size: %d, childCount: %d / %d",
+ nextPos, mDictBufferSize, i, childCount);
+ ASSERT(false);
+ return;
+ }
nextPos = createAndGetLeavingChildNode(dicNode, nextPos, childDicNodes);
}
}
@@ -404,6 +416,11 @@ int PatriciaTriePolicy::createAndGetLeavingChildNode(const DicNode *const dicNod
if (PatriciaTrieReadingUtils::hasBigrams(flags)) {
getBigramsStructurePolicy()->skipAllBigrams(&pos);
}
+ if (mergedNodeCodePointCount <= 0) {
+ AKLOGE("Empty PtNode is not allowed. Code point count: %d", mergedNodeCodePointCount);
+ ASSERT(false);
+ return pos;
+ }
childDicNodes->pushLeavingChild(dicNode, ptNodePos, childrenPos, probability,
PatriciaTrieReadingUtils::isTerminal(flags),
PatriciaTrieReadingUtils::hasChildrenInFlags(flags),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.h
index 19155f938..8d88c68e8 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.h
@@ -36,6 +36,7 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
PatriciaTriePolicy(const MmappedBuffer *const buffer)
: mBuffer(buffer), mHeaderPolicy(mBuffer->getBuffer(), buffer->getBufferSize()),
mDictRoot(mBuffer->getBuffer() + mHeaderPolicy.getSize()),
+ mDictBufferSize(mBuffer->getBufferSize() - mHeaderPolicy.getSize()),
mBigramListPolicy(mDictRoot), mShortcutListPolicy(mDictRoot) {}
~PatriciaTriePolicy() {
@@ -106,18 +107,27 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
AKLOGI("Warning: flushWithGC() is called for non-updatable dictionary.");
}
- bool needsToRunGC() const {
+ bool needsToRunGC(const bool mindsBlockByGC) const {
// This method should not be called for non-updatable dictionary.
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
return false;
}
+ void getProperty(const char *const query, char *const outResult,
+ const int maxResultLength) const {
+ // getProperty is not supported for this class.
+ if (maxResultLength > 0) {
+ outResult[0] = '\0';
+ }
+ }
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(PatriciaTriePolicy);
const MmappedBuffer *const mBuffer;
const HeaderPolicy mHeaderPolicy;
const uint8_t *const mDictRoot;
+ const int mDictBufferSize;
const BigramListPolicy mBigramListPolicy;
const ShortcutListPolicy mShortcutListPolicy;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp
index 1316b425f..7df55815f 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp
@@ -71,8 +71,17 @@ const PtReadingUtils::NodeFlags PtReadingUtils::FLAG_IS_BLACKLISTED = 0x01;
length = ByteArrayUtils::readStringAndAdvancePosition(buffer, maxLength, outBuffer,
pos);
} else {
- if (maxLength > 0) {
- outBuffer[0] = getCodePointAndAdvancePosition(buffer, pos);
+ const int codePoint = getCodePointAndAdvancePosition(buffer, pos);
+ if (codePoint == NOT_A_CODE_POINT) {
+ // CAVEAT: codePoint == NOT_A_CODE_POINT means the code point is
+ // CHARACTER_ARRAY_TERMINATOR. The code point must not be CHARACTER_ARRAY_TERMINATOR
+ // when the PtNode has a single code point.
+ length = 0;
+ AKLOGE("codePoint is NOT_A_CODE_POINT. pos: %d, codePoint: 0x%x, buffer[pos - 1]: 0x%x",
+ *pos - 1, codePoint, buffer[*pos - 1]);
+ ASSERT(false);
+ } else if (maxLength > 0) {
+ outBuffer[0] = codePoint;
length = 1;
}
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
index 17d2e39c2..9dc34823c 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
@@ -42,6 +42,10 @@ class BufferWithExtendableBuffer {
return mOriginalBufferSize + mUsedAdditionalBufferSize;
}
+ AK_FORCE_INLINE int getUsedAdditionalBufferSize() const {
+ return mUsedAdditionalBufferSize;
+ }
+
/**
* For reading.
*/
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.cpp
new file mode 100644
index 000000000..942a74238
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/decaying_utils.h"
+
+#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
+
+namespace latinime {
+
+const int DecayingUtils::MAX_UNIGRAM_COUNT = 12000;
+const int DecayingUtils::MAX_UNIGRAM_COUNT_AFTER_GC = 10000;
+const int DecayingUtils::MAX_BIGRAM_COUNT = 12000;
+const int DecayingUtils::MAX_BIGRAM_COUNT_AFTER_GC = 10000;
+
+const int DecayingUtils::MAX_COMPUTED_PROBABILITY = 127;
+const int DecayingUtils::MAX_UNIGRAM_PROBABILITY = 120;
+const int DecayingUtils::MIN_VALID_UNIGRAM_PROBABILITY = 24;
+const int DecayingUtils::UNIGRAM_PROBABILITY_STEP = 8;
+const int DecayingUtils::MAX_BIGRAM_PROBABILITY_DELTA = 15;
+const int DecayingUtils::MIN_VALID_BIGRAM_PROBABILITY_DELTA = 3;
+const int DecayingUtils::BIGRAM_PROBABILITY_DELTA_STEP = 1;
+
+/* static */ int DecayingUtils::getProbability(const int encodedUnigramProbability,
+ const int encodedBigramProbabilityDelta) {
+ if (encodedUnigramProbability == NOT_A_PROBABILITY) {
+ return NOT_A_PROBABILITY;
+ } else if (encodedBigramProbabilityDelta == NOT_A_PROBABILITY) {
+ const int rawProbability = ProbabilityUtils::backoff(decodeUnigramProbability(
+ encodedUnigramProbability));
+ return min(getDecayedProbability(rawProbability), MAX_COMPUTED_PROBABILITY);
+ } else {
+ const int rawProbability = ProbabilityUtils::computeProbabilityForBigram(
+ decodeUnigramProbability(encodedUnigramProbability),
+ decodeBigramProbabilityDelta(encodedBigramProbabilityDelta));
+ return min(getDecayedProbability(rawProbability), MAX_COMPUTED_PROBABILITY);
+ }
+}
+
+/* static */ int DecayingUtils::getUpdatedUnigramProbability(const int originalEncodedProbability,
+ const int newProbability) {
+ if (originalEncodedProbability == NOT_A_PROBABILITY) {
+ // The unigram is not in this dictionary.
+ if (newProbability == NOT_A_PROBABILITY) {
+ // The unigram is not in other dictionaries.
+ return 0;
+ } else {
+ return MIN_VALID_UNIGRAM_PROBABILITY;
+ }
+ } else {
+ if (newProbability != NOT_A_PROBABILITY
+ && originalEncodedProbability < MIN_VALID_UNIGRAM_PROBABILITY) {
+ return MIN_VALID_UNIGRAM_PROBABILITY;
+ }
+ return min(originalEncodedProbability + UNIGRAM_PROBABILITY_STEP, MAX_UNIGRAM_PROBABILITY);
+ }
+}
+
+/* static */ int DecayingUtils::getUnigramProbabilityToSave(const int encodedProbability) {
+ return max(encodedProbability - UNIGRAM_PROBABILITY_STEP, 0);
+}
+
+/* static */ int DecayingUtils::getBigramProbabilityDeltaToSave(const int encodedProbabilityDelta) {
+ return max(encodedProbabilityDelta - BIGRAM_PROBABILITY_DELTA_STEP, 0);
+}
+
+/* static */ int DecayingUtils::getUpdatedBigramProbabilityDelta(
+ const int originalEncodedProbabilityDelta, const int newProbability) {
+ if (originalEncodedProbabilityDelta == NOT_A_PROBABILITY) {
+ // The bigram relation is not in this dictionary.
+ if (newProbability == NOT_A_PROBABILITY) {
+ // The bigram target is not in other dictionaries.
+ return 0;
+ } else {
+ return MIN_VALID_BIGRAM_PROBABILITY_DELTA;
+ }
+ } else {
+ if (newProbability != NOT_A_PROBABILITY
+ && originalEncodedProbabilityDelta < MIN_VALID_BIGRAM_PROBABILITY_DELTA) {
+ return MIN_VALID_BIGRAM_PROBABILITY_DELTA;
+ }
+ return min(originalEncodedProbabilityDelta + BIGRAM_PROBABILITY_DELTA_STEP,
+ MAX_BIGRAM_PROBABILITY_DELTA);
+ }
+}
+
+/* static */ int DecayingUtils::isValidUnigram(const int encodedUnigramProbability) {
+ return encodedUnigramProbability >= MIN_VALID_UNIGRAM_PROBABILITY;
+}
+
+/* static */ int DecayingUtils::isValidBigram(const int encodedBigramProbabilityDelta) {
+ return encodedBigramProbabilityDelta >= MIN_VALID_BIGRAM_PROBABILITY_DELTA;
+}
+
+/* static */ int DecayingUtils::decodeUnigramProbability(const int encodedProbability) {
+ const int probability = encodedProbability - MIN_VALID_UNIGRAM_PROBABILITY;
+ if (probability < 0) {
+ return NOT_A_PROBABILITY;
+ } else {
+ return min(probability, MAX_UNIGRAM_PROBABILITY);
+ }
+}
+
+/* static */ int DecayingUtils::decodeBigramProbabilityDelta(const int encodedProbabilityDelta) {
+ const int probabilityDelta = encodedProbabilityDelta - MIN_VALID_BIGRAM_PROBABILITY_DELTA;
+ if (probabilityDelta < 0) {
+ return NOT_A_PROBABILITY;
+ } else {
+ return min(probabilityDelta, MAX_BIGRAM_PROBABILITY_DELTA);
+ }
+}
+
+/* static */ int DecayingUtils::getDecayedProbability(const int rawProbability) {
+ return rawProbability;
+}
+
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.h
new file mode 100644
index 000000000..1ca03918f
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/decaying_utils.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_DECAYING_UTILS_H
+#define LATINIME_DECAYING_UTILS_H
+
+#include "defines.h"
+
+namespace latinime {
+
+// TODO: Check the elapsed time and decrease the probability depending on the time. Time field is
+// required to introduced to each terminal PtNode and bigram entry.
+// TODO: Quit using bigram probability to indicate the delta.
+// TODO: Quit using bigram probability delta.
+class DecayingUtils {
+ public:
+ static const int MAX_UNIGRAM_COUNT;
+ static const int MAX_UNIGRAM_COUNT_AFTER_GC;
+ static const int MAX_BIGRAM_COUNT;
+ static const int MAX_BIGRAM_COUNT_AFTER_GC;
+
+ static int getProbability(const int encodedUnigramProbability,
+ const int encodedBigramProbabilityDelta);
+
+ static int getUpdatedUnigramProbability(const int originalEncodedProbability,
+ const int newProbability);
+
+ static int getUpdatedBigramProbabilityDelta(const int originalEncodedProbabilityDelta,
+ const int newProbability);
+
+ static int isValidUnigram(const int encodedUnigramProbability);
+
+ static int isValidBigram(const int encodedProbabilityDelta);
+
+ static int getUnigramProbabilityToSave(const int encodedProbability);
+
+ static int getBigramProbabilityDeltaToSave(const int encodedProbabilityDelta);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DecayingUtils);
+
+ static const int MAX_COMPUTED_PROBABILITY;
+ static const int MAX_UNIGRAM_PROBABILITY;
+ static const int MIN_VALID_UNIGRAM_PROBABILITY;
+ static const int UNIGRAM_PROBABILITY_STEP;
+ static const int MAX_BIGRAM_PROBABILITY_DELTA;
+ static const int MIN_VALID_BIGRAM_PROBABILITY_DELTA;
+ static const int BIGRAM_PROBABILITY_DELTA_STEP;
+
+ static int decodeUnigramProbability(const int encodedProbability);
+
+ static int decodeBigramProbabilityDelta(const int encodedProbability);
+
+ static int getDecayedProbability(const int rawProbability);
+};
+} // namespace latinime
+#endif /* LATINIME_DECAYING_UTILS_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
new file mode 100644
index 000000000..f22e94c6a
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h"
+
+#include <cstdio>
+#include <cstring>
+
+#include "suggest/policyimpl/dictionary/header/header_policy.h"
+#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h"
+#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
+#include "suggest/policyimpl/dictionary/utils/format_utils.h"
+
+namespace latinime {
+
+const char *const DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE = ".tmp";
+
+/* static */ bool DictFileWritingUtils::createEmptyDictFile(const char *const filePath,
+ const int dictVersion, const HeaderReadWriteUtils::AttributeMap *const attributeMap) {
+ switch (dictVersion) {
+ case 3:
+ return createEmptyV3DictFile(filePath, attributeMap);
+ default:
+ // Only version 3 dictionary is supported for now.
+ return false;
+ }
+}
+
+/* static */ bool DictFileWritingUtils::createEmptyV3DictFile(const char *const filePath,
+ const HeaderReadWriteUtils::AttributeMap *const attributeMap) {
+ BufferWithExtendableBuffer headerBuffer(0 /* originalBuffer */, 0 /* originalBufferSize */);
+ HeaderPolicy headerPolicy(FormatUtils::VERSION_3, attributeMap);
+ headerPolicy.writeHeaderToBuffer(&headerBuffer, true /* updatesLastUpdatedTime */,
+ 0 /* unigramCount */, 0 /* bigramCount */, 0 /* extendedRegionSize */);
+ BufferWithExtendableBuffer bodyBuffer(0 /* originalBuffer */, 0 /* originalBufferSize */);
+ if (!DynamicPatriciaTrieWritingUtils::writeEmptyDictionary(&bodyBuffer, 0 /* rootPos */)) {
+ return false;
+ }
+ return flushAllHeaderAndBodyToFile(filePath, &headerBuffer, &bodyBuffer);
+}
+
+/* static */ bool DictFileWritingUtils::flushAllHeaderAndBodyToFile(const char *const filePath,
+ BufferWithExtendableBuffer *const dictHeader, BufferWithExtendableBuffer *const dictBody) {
+ const int tmpFileNameBufSize = strlen(filePath)
+ + strlen(TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE) + 1 /* terminator */;
+ // Name of a temporary file used for writing that is a connected string of original name and
+ // TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE.
+ char tmpFileName[tmpFileNameBufSize];
+ snprintf(tmpFileName, tmpFileNameBufSize, "%s%s", filePath,
+ TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE);
+ FILE *const file = fopen(tmpFileName, "wb");
+ if (!file) {
+ AKLOGE("Dictionary file %s cannnot be opened.", tmpFileName);
+ ASSERT(false);
+ return false;
+ }
+ // Write the dictionary header.
+ if (!writeBufferToFile(file, dictHeader)) {
+ remove(tmpFileName);
+ AKLOGE("Dictionary header cannnot be written. size: %d", dictHeader->getTailPosition());
+ ASSERT(false);
+ return false;
+ }
+ // Write the dictionary body.
+ if (!writeBufferToFile(file, dictBody)) {
+ remove(tmpFileName);
+ AKLOGE("Dictionary body cannnot be written. size: %d", dictBody->getTailPosition());
+ ASSERT(false);
+ return false;
+ }
+ fclose(file);
+ rename(tmpFileName, filePath);
+ return true;
+}
+
+// This closes file pointer when an error is caused and returns whether the writing was succeeded
+// or not.
+/* static */ bool DictFileWritingUtils::writeBufferToFile(FILE *const file,
+ const BufferWithExtendableBuffer *const buffer) {
+ const int originalBufSize = buffer->getOriginalBufferSize();
+ if (originalBufSize > 0 && fwrite(buffer->getBuffer(false /* usesAdditionalBuffer */),
+ originalBufSize, 1, file) < 1) {
+ fclose(file);
+ return false;
+ }
+ const int additionalBufSize = buffer->getUsedAdditionalBufferSize();
+ if (additionalBufSize > 0 && fwrite(buffer->getBuffer(true /* usesAdditionalBuffer */),
+ additionalBufSize, 1, file) < 1) {
+ fclose(file);
+ return false;
+ }
+ return true;
+}
+
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h
new file mode 100644
index 000000000..bd4ac66fd
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_DICT_FILE_WRITING_UTILS_H
+#define LATINIME_DICT_FILE_WRITING_UTILS_H
+
+#include <cstdio>
+
+#include "defines.h"
+#include "suggest/policyimpl/dictionary/header/header_read_write_utils.h"
+
+namespace latinime {
+
+class BufferWithExtendableBuffer;
+
+class DictFileWritingUtils {
+ public:
+ static bool createEmptyDictFile(const char *const filePath, const int dictVersion,
+ const HeaderReadWriteUtils::AttributeMap *const attributeMap);
+
+ static bool flushAllHeaderAndBodyToFile(const char *const filePath,
+ BufferWithExtendableBuffer *const dictHeader,
+ BufferWithExtendableBuffer *const dictBody);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DictFileWritingUtils);
+
+ static const char *const TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE;
+
+ static bool createEmptyV3DictFile(const char *const filePath,
+ const HeaderReadWriteUtils::AttributeMap *const attributeMap);
+
+ static bool writeBufferToFile(FILE *const file,
+ const BufferWithExtendableBuffer *const buffer);
+};
+} // namespace latinime
+#endif /* LATINIME_DICT_FILE_WRITING_UTILS_H */
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp
index 408b12ae9..5b6b5e874 100644
--- a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp
+++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp
@@ -47,7 +47,7 @@ ErrorType TypingWeighting::getErrorType(const CorrectionType correctionType,
case CT_TERMINAL_INSERTION:
case CT_TRANSPOSITION:
return ET_EDIT_CORRECTION;
- case CT_NEW_WORD_SPACE_OMITTION:
+ case CT_NEW_WORD_SPACE_OMISSION:
case CT_NEW_WORD_SPACE_SUBSTITUTION:
return ET_NEW_WORD;
case CT_TERMINAL:
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
index b6aa85896..9f0a331e3 100644
--- a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
+++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
@@ -74,7 +74,8 @@ class TypingWeighting : public Weighting {
// Note: min() required since length can be MAX_POINT_TO_KEY_LENGTH for characters not on
// the keyboard (like accented letters)
const float normalizedSquaredLength = traverseSession->getProximityInfoState(0)
- ->getPointToKeyLength(pointIndex, dicNode->getNodeCodePoint());
+ ->getPointToKeyLength(pointIndex,
+ CharUtils::toBaseLowerCase(dicNode->getNodeCodePoint()));
const float normalizedDistance = TouchPositionCorrectionUtils::getSweetSpotFactor(
traverseSession->isTouchPositionCorrectionEnabled(), normalizedSquaredLength);
const float weightedDistance = ScoringParams::DISTANCE_WEIGHT_LENGTH * normalizedDistance;
@@ -113,10 +114,10 @@ class TypingWeighting : public Weighting {
const int16_t parentPointIndex = parentDicNode->getInputIndex(0);
const int prevCodePoint = parentDicNode->getNodeCodePoint();
const float distance1 = traverseSession->getProximityInfoState(0)->getPointToKeyLength(
- parentPointIndex + 1, prevCodePoint);
+ parentPointIndex + 1, CharUtils::toBaseLowerCase(prevCodePoint));
const int codePoint = dicNode->getNodeCodePoint();
const float distance2 = traverseSession->getProximityInfoState(0)->getPointToKeyLength(
- parentPointIndex, codePoint);
+ parentPointIndex, CharUtils::toBaseLowerCase(codePoint));
const float distance = distance1 + distance2;
const float weightedLengthDistance =
distance * ScoringParams::DISTANCE_WEIGHT_LENGTH;
@@ -133,7 +134,7 @@ class TypingWeighting : public Weighting {
const bool existsAdjacentProximityChars = traverseSession->getProximityInfoState(0)
->existsAdjacentProximityChars(insertedPointIndex);
const float dist = traverseSession->getProximityInfoState(0)->getPointToKeyLength(
- insertedPointIndex + 1, dicNode->getNodeCodePoint());
+ insertedPointIndex + 1, CharUtils::toBaseLowerCase(dicNode->getNodeCodePoint()));
const float weightedDistance = dist * ScoringParams::DISTANCE_WEIGHT_LENGTH;
const bool singleChar = dicNode->getNodeCodePointCount() == 1;
float cost = (singleChar ? ScoringParams::INSERTION_COST_FIRST_CHAR : 0.0f);
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
new file mode 100644
index 000000000..cf85d97a0
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import com.android.inputmethod.latin.makedict.FormatSpec;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+@LargeTest
+public class BinaryDictionaryDecayingTests extends AndroidTestCase {
+ private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
+ private static final String TEST_LOCALE = "test";
+
+ private static final int DUMMY_PROBABILITY = 0;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private void forcePassingShortTime(final BinaryDictionary binaryDictionary) {
+ binaryDictionary.flushWithGC();
+ }
+
+ private void forcePassingLongTime(final BinaryDictionary binaryDictionary) {
+ // Currently, probabilities are decayed when GC is run. All entries that have never been
+ // typed in 32 GCs are removed.
+ final int count = 32;
+ for (int i = 0; i < count; i++) {
+ binaryDictionary.flushWithGC();
+ }
+ }
+
+ private File createEmptyDictionaryAndGetFile(final String filename) throws IOException {
+ final File file = File.createTempFile(filename, TEST_DICT_FILE_EXTENSION,
+ getContext().getCacheDir());
+ Map<String, String> attributeMap = new HashMap<String, String>();
+ attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
+ attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_ATTRIBUTE,
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
+ if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
+ 3 /* dictVersion */, attributeMap)) {
+ return file;
+ } else {
+ throw new IOException("Empty dictionary cannot be created.");
+ }
+ }
+
+ public void testAddValidAndInvalidWords() {
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ assertFalse(binaryDictionary.isValidWord("a"));
+ binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ assertFalse(binaryDictionary.isValidWord("a"));
+ binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ assertFalse(binaryDictionary.isValidWord("a"));
+ binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ assertTrue(binaryDictionary.isValidWord("a"));
+
+ binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ assertTrue(binaryDictionary.isValidWord("b"));
+
+ final int unigramProbability = binaryDictionary.getFrequency("a");
+ binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ assertFalse(binaryDictionary.isValidBigram("a", "b"));
+ binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ assertFalse(binaryDictionary.isValidBigram("a", "b"));
+ binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ assertFalse(binaryDictionary.isValidBigram("a", "b"));
+ binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ assertTrue(binaryDictionary.isValidBigram("a", "b"));
+
+ binaryDictionary.addUnigramWord("c", DUMMY_PROBABILITY);
+ binaryDictionary.addBigramWords("a", "c", DUMMY_PROBABILITY);
+ assertTrue(binaryDictionary.isValidBigram("a", "c"));
+
+ binaryDictionary.close();
+ dictFile.delete();
+ }
+
+ // TODO: Add large tests.
+ public void testDecayingProbability() {
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ assertTrue(binaryDictionary.isValidWord("a"));
+ forcePassingShortTime(binaryDictionary);
+ assertFalse(binaryDictionary.isValidWord("a"));
+
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ forcePassingShortTime(binaryDictionary);
+ assertTrue(binaryDictionary.isValidWord("a"));
+ forcePassingLongTime(binaryDictionary);
+ assertFalse(binaryDictionary.isValidWord("a"));
+
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ assertTrue(binaryDictionary.isValidBigram("a", "b"));
+ forcePassingShortTime(binaryDictionary);
+ assertFalse(binaryDictionary.isValidBigram("a", "b"));
+
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ assertTrue(binaryDictionary.isValidBigram("a", "b"));
+ forcePassingShortTime(binaryDictionary);
+ assertTrue(binaryDictionary.isValidBigram("a", "b"));
+ forcePassingLongTime(binaryDictionary);
+ assertFalse(binaryDictionary.isValidBigram("a", "b"));
+
+ binaryDictionary.close();
+ dictFile.delete();
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index 96a2217a3..6a21522f9 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -21,24 +21,19 @@ import android.test.suitebuilder.annotation.LargeTest;
import android.util.Pair;
import com.android.inputmethod.latin.makedict.CodePointUtils;
-import com.android.inputmethod.latin.makedict.DictEncoder;
import com.android.inputmethod.latin.makedict.FormatSpec;
-import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
-import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
import java.util.Random;
@LargeTest
public class BinaryDictionaryTests extends AndroidTestCase {
- private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
- new FormatSpec.FormatOptions(3 /* version */, true /* supportsDynamicUpdate */);
private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
private static final String TEST_LOCALE = "test";
@@ -52,15 +47,18 @@ public class BinaryDictionaryTests extends AndroidTestCase {
super.tearDown();
}
- private File createEmptyDictionaryAndGetFile(final String filename) throws IOException,
- UnsupportedFormatException {
- final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false));
+ private File createEmptyDictionaryAndGetFile(final String filename) throws IOException {
final File file = File.createTempFile(filename, TEST_DICT_FILE_EXTENSION,
getContext().getCacheDir());
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
- return file;
+ Map<String, String> attributeMap = new HashMap<String, String>();
+ attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
+ if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
+ 3 /* dictVersion */, attributeMap)) {
+ return file;
+ } else {
+ throw new IOException("Empty dictionary cannot be created.");
+ }
}
public void testIsValidDictionary() {
@@ -69,8 +67,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -95,8 +91,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -139,8 +133,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -169,8 +161,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -240,8 +230,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -294,8 +282,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -342,8 +328,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -392,8 +376,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
@@ -445,8 +427,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
@@ -516,8 +496,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
@@ -617,8 +595,6 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
}
final ArrayList<String> words = new ArrayList<String>();
@@ -630,7 +606,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
- while(!binaryDictionary.needsToRunGC()) {
+ while(!binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
final String word = CodePointUtils.generateWord(random, codePointSet);
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
@@ -650,4 +626,57 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile.delete();
}
+
+ public void testUnigramAndBigramCount() {
+ final int flashWithGCIterationCount = 10;
+ final int codePointSetSize = 50;
+ final int unigramCountPerIteration = 1000;
+ final int bigramCountPerIteration = 2000;
+ final int seed = 1123581321;
+
+ final Random random = new Random(seed);
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+
+ final ArrayList<String> words = new ArrayList<String>();
+ final HashSet<Pair<String, String>> bigrams = new HashSet<Pair<String, String>>();
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+
+ BinaryDictionary binaryDictionary;
+ for (int i = 0; i < flashWithGCIterationCount; i++) {
+ binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ for (int j = 0; j < unigramCountPerIteration; j++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ words.add(word);
+ final int unigramProbability = random.nextInt(0xFF);
+ binaryDictionary.addUnigramWord(word, unigramProbability);
+ }
+ for (int j = 0; j < bigramCountPerIteration; j++) {
+ final String word0 = words.get(random.nextInt(words.size()));
+ final String word1 = words.get(random.nextInt(words.size()));
+ bigrams.add(new Pair<String, String>(word0, word1));
+ final int bigramProbability = random.nextInt(0xF);
+ binaryDictionary.addBigramWords(word0, word1, bigramProbability);
+ }
+ assertEquals(new HashSet<String>(words).size(), Integer.parseInt(
+ binaryDictionary.getPropertyForTests(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
+ assertEquals(new HashSet<Pair<String, String>>(bigrams).size(), Integer.parseInt(
+ binaryDictionary.getPropertyForTests(BinaryDictionary.BIGRAM_COUNT_QUERY)));
+ binaryDictionary.flushWithGC();
+ assertEquals(new HashSet<String>(words).size(), Integer.parseInt(
+ binaryDictionary.getPropertyForTests(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
+ assertEquals(new HashSet<Pair<String, String>>(bigrams).size(), Integer.parseInt(
+ binaryDictionary.getPropertyForTests(BinaryDictionary.BIGRAM_COUNT_QUERY)));
+ binaryDictionary.close();
+ }
+
+ dictFile.delete();
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java b/tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java
new file mode 100644
index 000000000..132483d5e
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Random;
+
+/**
+ * Unit tests for SparseTable.
+ */
+@LargeTest
+public class SparseTableTests extends AndroidTestCase {
+ private static final String TAG = SparseTableTests.class.getSimpleName();
+
+ private static final int[] SMALL_INDEX = { SparseTable.NOT_EXIST, 0 };
+ private static final int[] BIG_INDEX = { SparseTable.NOT_EXIST, 1, 2, 3, 4, 5, 6, 7};
+
+ private final Random mRandom;
+ private final ArrayList<Integer> mRandomIndex;
+
+ private static final int DEFAULT_SIZE = 10000;
+ private static final int BLOCK_SIZE = 8;
+
+ public SparseTableTests() {
+ this(System.currentTimeMillis(), DEFAULT_SIZE);
+ }
+
+ public SparseTableTests(final long seed, final int tableSize) {
+ super();
+ Log.d(TAG, "Seed for test is " + seed + ", size is " + tableSize);
+ mRandom = new Random(seed);
+ mRandomIndex = new ArrayList<Integer>(tableSize);
+ for (int i = 0; i < tableSize; ++i) {
+ mRandomIndex.add(SparseTable.NOT_EXIST);
+ }
+ }
+
+ public void testInitializeWithArray() {
+ final SparseTable table = new SparseTable(SMALL_INDEX, BIG_INDEX, BLOCK_SIZE);
+ for (int i = 0; i < 8; ++i) {
+ assertEquals(SparseTable.NOT_EXIST, table.get(i));
+ }
+ assertEquals(SparseTable.NOT_EXIST, table.get(8));
+ for (int i = 9; i < 16; ++i) {
+ assertEquals(i - 8, table.get(i));
+ }
+ }
+
+ public void testSet() {
+ final SparseTable table = new SparseTable(16, BLOCK_SIZE);
+ table.set(3, 6);
+ table.set(8, 16);
+ for (int i = 0; i < 16; ++i) {
+ if (i == 3 || i == 8) {
+ assertEquals(i * 2, table.get(i));
+ } else {
+ assertEquals(SparseTable.NOT_EXIST, table.get(i));
+ }
+ }
+ }
+
+ private void generateRandomIndex(final int size, final int prop) {
+ for (int i = 0; i < DEFAULT_SIZE; ++i) {
+ if (mRandom.nextInt(100) < prop) {
+ mRandomIndex.set(i, mRandom.nextInt());
+ } else {
+ mRandomIndex.set(i, SparseTable.NOT_EXIST);
+ }
+ }
+ }
+
+ private void runTestRandomSet() {
+ final SparseTable table = new SparseTable(DEFAULT_SIZE, BLOCK_SIZE);
+ int elementCount = 0;
+ for (int i = 0; i < DEFAULT_SIZE; ++i) {
+ if (mRandomIndex.get(i) != SparseTable.NOT_EXIST) {
+ table.set(i, mRandomIndex.get(i));
+ elementCount++;
+ }
+ }
+
+ Log.d(TAG, "table size = " + table.getLookupTableSize() + " + "
+ + table.getContentTableSize());
+ Log.d(TAG, "the table has " + elementCount + " elements");
+ for (int i = 0; i < DEFAULT_SIZE; ++i) {
+ assertEquals(table.get(i), (int)mRandomIndex.get(i));
+ }
+
+ // flush and reload
+ OutputStream lookupOutStream = null;
+ OutputStream contentOutStream = null;
+ InputStream lookupInStream = null;
+ InputStream contentInStream = null;
+ try {
+ final File lookupIndexFile = File.createTempFile("testRandomSet", ".small");
+ final File contentFile = File.createTempFile("testRandomSet", ".big");
+ lookupOutStream = new FileOutputStream(lookupIndexFile);
+ contentOutStream = new FileOutputStream(contentFile);
+ table.write(lookupOutStream, contentOutStream);
+ lookupInStream = new FileInputStream(lookupIndexFile);
+ contentInStream = new FileInputStream(contentFile);
+ final byte[] lookupArray = new byte[(int) lookupIndexFile.length()];
+ final byte[] contentArray = new byte[(int) contentFile.length()];
+ lookupInStream.read(lookupArray);
+ contentInStream.read(contentArray);
+ final SparseTable newTable = new SparseTable(lookupArray, contentArray, BLOCK_SIZE);
+ for (int i = 0; i < DEFAULT_SIZE; ++i) {
+ assertEquals(table.get(i), newTable.get(i));
+ }
+ } catch (IOException e) {
+ Log.d(TAG, "IOException while flushing and realoding", e);
+ } finally {
+ if (lookupOutStream != null) {
+ try {
+ lookupOutStream.close();
+ } catch (IOException e) {
+ Log.d(TAG, "IOException while closing the stream", e);
+ }
+ }
+ if (contentOutStream != null) {
+ try {
+ contentOutStream.close();
+ } catch (IOException e) {
+ Log.d(TAG, "IOException while closing contentStream.", e);
+ }
+ }
+ }
+ }
+
+ public void testRandomSet() {
+ for (int i = 0; i <= 100; i += 10) {
+ generateRandomIndex(DEFAULT_SIZE, i);
+ runTestRandomSet();
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
index d605cdb84..ddc9546c5 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
@@ -75,38 +75,33 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
return new ArrayList<String>(wordSet);
}
- private void addToDict(final UserHistoryPredictionDictionary dict, final List<String> words) {
+ private void addToDict(final UserHistoryDictionary dict, final List<String> words) {
String prevWord = null;
for (String word : words) {
- dict.addToPersonalizationPredictionDictionary(prevWord, word, true);
+ dict.addToDictionary(prevWord, word, true);
prevWord = word;
}
}
/**
- * @param checksContents if true, checks whether written words are actually in the dictionary
+ * @param checkContents if true, checks whether written words are actually in the dictionary
* or not.
*/
private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords,
- final Random random, final boolean checksContents) {
+ final Random random, final boolean checkContents) {
final List<String> words = generateWords(numberOfWords, random);
- final UserHistoryPredictionDictionary dict =
- PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
+ final UserHistoryDictionary dict =
+ PersonalizationHelper.getUserHistoryDictionary(getContext(),
testFilenameSuffix /* locale */, mPrefs);
// Add random words to the user history dictionary.
addToDict(dict, words);
- if (checksContents) {
+ if (checkContents) {
try {
Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS));
} catch (InterruptedException e) {
}
- // Limit word count to check when using a Java on memory dictionary.
- final int wordCountToCheck =
- ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE ?
- numberOfWords : 10;
- for (int i = 0; i < wordCountToCheck; ++i) {
+ for (int i = 0; i < numberOfWords; ++i) {
final String word = words.get(i);
- // This may fail as long as we use tryLock on inserting the bigram words
assertTrue(dict.isInDictionaryForTests(word));
}
}
@@ -127,8 +122,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
true /* checksContents */);
} finally {
try {
- final UserHistoryPredictionDictionary dict =
- PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
+ final UserHistoryDictionary dict =
+ PersonalizationHelper.getUserHistoryDictionary(getContext(),
testFilenameSuffix, mPrefs);
Log.d(TAG, "waiting for writing ...");
dict.shutdownExecutorForTests();
@@ -139,7 +134,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
Log.d(TAG, "InterruptedException: " + e);
}
- final String fileName = UserHistoryPredictionDictionary.NAME + "." + testFilenameSuffix
+ final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
+ ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
dictFile = new File(getContext().getFilesDir(), fileName);
@@ -164,7 +159,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
// Create filename suffixes for this test.
for (int i = 0; i < numberOfLanguages; i++) {
testFilenameSuffixes[i] = "testSwitchingLanguages" + i;
- final String fileName = UserHistoryPredictionDictionary.NAME + "." +
+ final String fileName = UserHistoryDictionary.NAME + "." +
testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
dictFiles[i] = new File(getContext().getFilesDir(), fileName);
}
@@ -186,8 +181,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
try {
Log.d(TAG, "waiting for writing ...");
for (int i = 0; i < numberOfLanguages; i++) {
- final UserHistoryPredictionDictionary dict =
- PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
+ final UserHistoryDictionary dict =
+ PersonalizationHelper.getUserHistoryDictionary(getContext(),
testFilenameSuffixes[i], mPrefs);
dict.shutdownExecutorForTests();
while (!dict.isTerminatedForTests()) {
@@ -215,8 +210,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
10000 : 1000;
final Random random = new Random(123456);
- UserHistoryPredictionDictionary dict =
- PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
+ UserHistoryDictionary dict =
+ PersonalizationHelper.getUserHistoryDictionary(getContext(),
testFilenameSuffix, mPrefs);
try {
addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random,
@@ -232,7 +227,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
} catch (InterruptedException e) {
Log.d(TAG, "InterruptedException: ", e);
}
- final String fileName = UserHistoryPredictionDictionary.NAME + "." + testFilenameSuffix
+ final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
+ ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
dictFile = new File(getContext().getFilesDir(), fileName);
if (dictFile != null) {
diff --git a/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java
new file mode 100644
index 000000000..fa6ad16c1
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.style.SuggestionSpan;
+import android.text.style.URLSpan;
+import android.text.SpannableStringBuilder;
+import android.text.Spannable;
+import android.text.Spanned;
+
+@SmallTest
+public class SpannableStringUtilsTests extends AndroidTestCase {
+ public void testConcatWithSuggestionSpansOnly() {
+ SpannableStringBuilder s = new SpannableStringBuilder("test string\ntest string\n"
+ + "test string\ntest string\ntest string\ntest string\ntest string\ntest string\n"
+ + "test string\ntest string\n");
+ final int N = 10;
+ for (int i = 0; i < N; ++i) {
+ // Put a PARAGRAPH-flagged span that should not be found in the result.
+ s.setSpan(new SuggestionSpan(getContext(),
+ new String[] {"" + i}, Spannable.SPAN_PARAGRAPH),
+ i * 12, i * 12 + 12, Spannable.SPAN_PARAGRAPH);
+ // Put a normal suggestion span that should be found in the result.
+ s.setSpan(new SuggestionSpan(getContext(), new String[] {"" + i}, 0), i, i * 2, 0);
+ // Put a URL span than should not be found in the result.
+ s.setSpan(new URLSpan("http://a"), i, i * 2, 0);
+ }
+
+ final CharSequence a = s.subSequence(0, 15);
+ final CharSequence b = s.subSequence(15, s.length());
+ final Spanned result =
+ (Spanned)SpannableStringUtils.concatWithNonParagraphSuggestionSpansOnly(a, b);
+
+ Object[] spans = result.getSpans(0, result.length(), SuggestionSpan.class);
+ for (int i = 0; i < spans.length; i++) {
+ final int flags = result.getSpanFlags(spans[i]);
+ assertEquals("Should not find a span with PARAGRAPH flag",
+ flags & Spannable.SPAN_PARAGRAPH, 0);
+ assertTrue("Should be a SuggestionSpan", spans[i] instanceof SuggestionSpan);
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
index eb9fb984e..4e396a1cf 100644
--- a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
@@ -20,11 +20,6 @@ import com.android.inputmethod.latin.settings.SettingsValues;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import android.text.style.SuggestionSpan;
-import android.text.style.URLSpan;
-import android.text.SpannableStringBuilder;
-import android.text.Spannable;
-import android.text.Spanned;
import java.util.Arrays;
import java.util.List;
@@ -285,34 +280,4 @@ public class StringUtilsTests extends AndroidTestCase {
assertEquals(objs[i], newObjArray.get(i));
}
}
-
- public void testConcatWithSuggestionSpansOnly() {
- SpannableStringBuilder s = new SpannableStringBuilder("test string\ntest string\n"
- + "test string\ntest string\ntest string\ntest string\ntest string\ntest string\n"
- + "test string\ntest string\n");
- final int N = 10;
- for (int i = 0; i < N; ++i) {
- // Put a PARAGRAPH-flagged span that should not be found in the result.
- s.setSpan(new SuggestionSpan(getContext(),
- new String[] {"" + i}, Spannable.SPAN_PARAGRAPH),
- i * 12, i * 12 + 12, Spannable.SPAN_PARAGRAPH);
- // Put a normal suggestion span that should be found in the result.
- s.setSpan(new SuggestionSpan(getContext(), new String[] {"" + i}, 0), i, i * 2, 0);
- // Put a URL span than should not be found in the result.
- s.setSpan(new URLSpan("http://a"), i, i * 2, 0);
- }
-
- final CharSequence a = s.subSequence(0, 15);
- final CharSequence b = s.subSequence(15, s.length());
- final Spanned result =
- (Spanned)StringUtils.concatWithNonParagraphSuggestionSpansOnly(a, b);
-
- Object[] spans = result.getSpans(0, result.length(), SuggestionSpan.class);
- for (int i = 0; i < spans.length; i++) {
- final int flags = result.getSpanFlags(spans[i]);
- assertEquals("Should not find a span with PARAGRAPH flag",
- flags & Spannable.SPAN_PARAGRAPH, 0);
- assertTrue("Should be a SuggestionSpan", spans[i] instanceof SuggestionSpan);
- }
- }
}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
index fa80385fc..bd06e9f3a 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
@@ -80,17 +80,17 @@ public final class BinaryDictOffdeviceUtils {
}
/**
- * Returns a decrypted/uncompressed binary dictionary.
+ * Returns a decrypted/uncompressed dictionary.
*
- * This will decrypt/uncompress any number of times as necessary until it finds the binary
+ * This will decrypt/uncompress any number of times as necessary until it finds the
* dictionary signature, and copy the decoded file to a temporary place.
- * If this is not a binary dictionary, the method returns null.
+ * If this is not a dictionary, the method returns null.
*/
- public static DecoderChainSpec getRawBinaryDictionaryOrNull(final File src) {
- return getRawBinaryDictionaryOrNullInternal(new DecoderChainSpec(), src, 0);
+ public static DecoderChainSpec getRawDictionaryOrNull(final File src) {
+ return getRawDictionaryOrNullInternal(new DecoderChainSpec(), src, 0);
}
- private static DecoderChainSpec getRawBinaryDictionaryOrNullInternal(
+ private static DecoderChainSpec getRawDictionaryOrNullInternal(
final DecoderChainSpec spec, final File src, final int depth) {
// Unfortunately the decoding scheme we use can consider any data to be encrypted
// and will product some output, meaning it's not possible to reliably detect encrypted
@@ -98,7 +98,8 @@ public final class BinaryDictOffdeviceUtils {
// over and over, ending in a stack overflow. Hence we limit the depth at which we try
// decoding the file.
if (depth > MAX_DECODE_DEPTH) return null;
- if (BinaryDictDecoderUtils.isBinaryDictionary(src)) {
+ if (BinaryDictDecoderUtils.isBinaryDictionary(src)
+ || CombinedInputOutput.isCombinedDictionary(src.getAbsolutePath())) {
spec.mFile = src;
return spec;
}
@@ -106,7 +107,7 @@ public final class BinaryDictOffdeviceUtils {
final File uncompressedFile = tryGetUncompressedFile(src);
if (null != uncompressedFile) {
final DecoderChainSpec newSpec =
- getRawBinaryDictionaryOrNullInternal(spec, uncompressedFile, depth + 1);
+ getRawDictionaryOrNullInternal(spec, uncompressedFile, depth + 1);
if (null == newSpec) return null;
return newSpec.addStep(COMPRESSION);
}
@@ -114,7 +115,7 @@ public final class BinaryDictOffdeviceUtils {
final File decryptedFile = tryGetDecryptedFile(src);
if (null != decryptedFile) {
final DecoderChainSpec newSpec =
- getRawBinaryDictionaryOrNullInternal(spec, decryptedFile, depth + 1);
+ getRawDictionaryOrNullInternal(spec, decryptedFile, depth + 1);
if (null == newSpec) return null;
return newSpec.addStep(ENCRYPTION);
}
@@ -175,17 +176,18 @@ public final class BinaryDictOffdeviceUtils {
return XmlDictInputOutput.readDictionaryXml(
new BufferedInputStream(new FileInputStream(file)),
null /* shortcuts */, null /* bigrams */);
- } else if (CombinedInputOutput.isCombinedDictionary(filename)) {
- if (report) System.out.println("Format : Combined format");
- return CombinedInputOutput.readDictionaryCombined(
- new BufferedInputStream(new FileInputStream(file)));
} else {
- final DecoderChainSpec decodedSpec = getRawBinaryDictionaryOrNull(file);
+ final DecoderChainSpec decodedSpec = getRawDictionaryOrNull(file);
if (null == decodedSpec) {
crash(filename, new RuntimeException(
filename + " does not seem to be a dictionary file"));
+ } else if (CombinedInputOutput.isCombinedDictionary(
+ decodedSpec.mFile.getAbsolutePath())){
+ if (report) System.out.println("Format : Combined format");
+ return CombinedInputOutput.readDictionaryCombined(
+ new BufferedInputStream(new FileInputStream(decodedSpec.mFile)));
} else {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file,
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(decodedSpec.mFile,
DictDecoder.USE_BYTEARRAY);
if (report) {
System.out.println("Format : Binary dictionary format");
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Package.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Package.java
index 9274dcd2e..dff3387be 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Package.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Package.java
@@ -79,7 +79,7 @@ public class Package {
throw new RuntimeException("Too many/too few arguments for command " + COMMAND);
}
final BinaryDictOffdeviceUtils.DecoderChainSpec decodedSpec =
- BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(new File(mArgs[0]));
+ BinaryDictOffdeviceUtils.getRawDictionaryOrNull(new File(mArgs[0]));
if (null == decodedSpec) {
System.out.println(mArgs[0] + " does not seem to be a dictionary");
return;
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
index 1eff497c1..1baeb7a47 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
@@ -64,7 +64,7 @@ public class BinaryDictOffdeviceUtilsTests extends TestCase {
// Test for an actually compressed dictionary and its contents
final BinaryDictOffdeviceUtils.DecoderChainSpec decodeSpec =
- BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(dst);
+ BinaryDictOffdeviceUtils.getRawDictionaryOrNull(dst);
for (final String step : decodeSpec.mDecoderSpec) {
assertEquals("Wrong decode spec", BinaryDictOffdeviceUtils.COMPRESSION, step);
}
@@ -90,7 +90,7 @@ public class BinaryDictOffdeviceUtilsTests extends TestCase {
// Test that a random data file actually fails
assertNull("Wrongly identified data file",
- BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(dst));
+ BinaryDictOffdeviceUtils.getRawDictionaryOrNull(dst));
final File gzDst = File.createTempFile("testGetRawDict", ".tmp");
gzDst.deleteOnExit();
@@ -103,6 +103,6 @@ public class BinaryDictOffdeviceUtilsTests extends TestCase {
// Test that a compressed random data file actually fails
assertNull("Wrongly identified data file",
- BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(gzDst));
+ BinaryDictOffdeviceUtils.getRawDictionaryOrNull(gzDst));
}
}