Compare commits

...

5 Commits

16 changed files with 29819 additions and 101 deletions

View File

@@ -0,0 +1,26 @@
Copyright (c) 2005,2006 Choe Hwanjin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the author nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,5 +1,8 @@
# License inventory
- `BSD-3-Clause-libhangul-hanja.txt` contains the terms for the
single-character Hanja data in `map/hanja.src` and generated
`map/hanja.dict`, derived from libhangul's `data/hanja/hanja.txt`.
- `GPL-2.0-or-later.txt` contains GNU GPL version 2. The header of
`map/kanji.dict` grants the option to use GPL version 2 or any later
version.

View File

@@ -63,8 +63,10 @@ test:
verify-map:
python3 map/mktelex.py | cmp - map/telex.map
python3 -B map/mkemoji | cmp - map/emoji.dict
python3 -B map/mkhanja | cmp - map/hanja.dict
python3 -B map/verifymap.py map/*.map map/*.dict
python3 -B tests/mkemoji_test.py
python3 -B tests/mkhanja_test.py
python3 -B tests/skk2ktrans_test.py
.PHONY: all check test verify-map clean xim gtk bench docker docker-image \

View File

@@ -20,7 +20,7 @@ input boundary, or an explicit mode change. Backspace first removes pending
romaji, then accumulated kana. The Japanese modes support doubled consonants
and combinations such as `nya`, `nnya`, and `matcha`.
Modes are selected with Ctrl and one letter:
Modes and temporary searches use Ctrl and one letter:
```text
Ctrl+N Japanese Hiragana and Kanji conversion
@@ -29,12 +29,13 @@ Ctrl+S Korean Hangul
Ctrl+T English passthrough
Ctrl+V Vietnamese Telex compatibility mode
Ctrl+E Emoji and symbol search
Ctrl+H One-shot Hanja search
Ctrl+P Toggle popup preedit
```
While candidates are visible, Up and Down move the selection, Enter accepts
the selected candidate, and an unmodified `1`-`9` selects the corresponding
visible row. Tab cycles emoji search results. `0` commits an unconverted
visible row. Tab cycles temporary search results. `0` commits an unconverted
language reading. Escape cancels the current composition. Ctrl, Alt, or
Super combined with a number does not select a candidate.
@@ -46,6 +47,14 @@ English aliases or the active language's input rules, including Japanese
Ctrl+E → smile → Enter → 😀
```
Hanja search is temporary and returns to the active language after one
conversion. Press Ctrl+H and type with that language's normal input rules,
then select with Up, Down, Tab, Enter, or `1`-`9`. The bundled dictionary
currently indexes exactly one modern Hangul syllable. Incomplete jamo,
multiple syllables, and other languages therefore have no candidates; Enter
commits the displayed reading unchanged. Escape cancels the search. It does
not convert words or text already surrounding the cursor.
## Build and test
The supported build uses Docker so host and container toolchains are not
@@ -76,14 +85,15 @@ build is still possible with the dependencies and Plan 9 setup recorded in
`Dockerfile`; use `make all`, `make check`, and `make bench` inside that
environment.
After editing `map/emoji.src`, regenerate and verify its dictionary with:
After editing an input source, regenerate and verify its dictionary with:
```sh
map/mkemoji >map/emoji.dict
map/mkhanja >map/hanja.dict
make verify-map
```
Japanese dictionary regeneration and verification are documented in
Hanja import and Japanese dictionary regeneration are documented in
[`map/README`](map/README). The converter output is deterministic UTF-8,
tab-separated data consumable by the runtime dictionary reader.
@@ -159,6 +169,9 @@ Data and third-party provenance is recorded in
[`font/PROVENANCE`](font/PROVENANCE). The historical SKK-derived Kanji
dictionary is distributed under GPL version 2 or later; its license text is
in [`LICENSES/GPL-2.0-or-later.txt`](LICENSES/GPL-2.0-or-later.txt).
The single-character Hanja data derived from libhangul is distributed under
the BSD 3-Clause license in
[`LICENSES/BSD-3-Clause-libhangul-hanja.txt`](LICENSES/BSD-3-Clause-libhangul-hanja.txt).
The repository does not currently declare a license for the strans project
source as a whole. The licenses of bundled data, fonts, generated protocol

1
dat.h
View File

@@ -13,6 +13,7 @@ enum
LangJP = 0x0e,
LangJPK = 0x0b,
LangKO = 0x13,
LangHANJA = 0x08,
LangEMOJI = 0x05,
LangVI = 0x16,

View File

@@ -14,6 +14,27 @@ carry a separate data license. `map/telex.map` is generated by
`map/emoji.dict` is generated deterministically from the repository-maintained
`map/emoji.src` by `map/mkemoji`. No external dataset is required.
`map/hanja.src` is a single-character subset of libhangul's
`data/hanja/hanja.txt` from release tag `libhangul-0.2.0`. Its immutable
identifiers are:
- annotated tag object: `20afc38922e3595ee3ed5b186f2ea05afe663763`
- peeled commit: `41c702f5d3581325b646ef6249f1f641b0427ae0`
- input blob: `199cfd70c4b306257ac2e018714a1285f7cf0ed3`
- input SHA-256: `dd44dcc856cf542b1022d0f39c2e9b9f8805fdcc5923be80f04849ed97ce0996`
`map/libhangul2hanja` keeps only a one-syllable modern Hangul reading paired
with one BMP Hanja rune supported by the popup. It writes one
`Hanja<TAB>Hangul syllable` pair per row in upstream order; word entries are
not part of this data. `map/mkhanja` groups those rows by reading for the
runtime dictionary without changing candidate order, retaining the first 32
candidates supported by the engine. Exact import and regeneration commands
are in `map/README`.
The upstream data header is BSD 3-Clause licensed, copyright 2005, 2006 Choe
Hwanjin. Its complete license text is in
`LICENSES/BSD-3-Clause-libhangul-hanja.txt`.
`map/kanji.dict` identifies itself as SKK Medium dictionary version 8.1,
May 24, 1995, rearranged for Plan 9 ktrans by Kenji Okamoto on February 17,
2000. Its header names its copyright holders and grants GPL version 2 or

View File

@@ -1,4 +1,44 @@
# Japanese dictionary data
# Dictionary data
## Korean Hanja data
`hanja.src` is the tracked, reviewable source for Korean Hanja conversion.
Every data row is exactly one Hanja character, a tab, and one modern Hangul
syllable:
```
漢 한
```
It contains no word rows such as `견출지` or `방학`. `mkhanja` validates this
contract and groups rows by their Hangul reading to produce the existing
runtime dictionary format. Candidate order follows source order. The source
keeps all retained pairs for review; the generated dictionary stores the first
32 candidates per reading because that is the engine's lookup limit.
The source is derived from libhangul release tag `libhangul-0.2.0`. The
annotated tag object is `20afc38922e3595ee3ed5b186f2ea05afe663763`, its
peeled commit is `41c702f5d3581325b646ef6249f1f641b0427ae0`, and
`data/hanja/hanja.txt` has blob ID
`199cfd70c4b306257ac2e018714a1285f7cf0ed3`. Import and regenerate it from
the repository root with:
```sh
curl -L https://raw.githubusercontent.com/libhangul/libhangul/41c702f5d3581325b646ef6249f1f641b0427ae0/data/hanja/hanja.txt -o upstream
printf '%s %s\n' dd44dcc856cf542b1022d0f39c2e9b9f8805fdcc5923be80f04849ed97ce0996 upstream | sha256sum -c -
map/libhangul2hanja upstream >map/hanja.src
map/mkhanja >map/hanja.dict
```
`libhangul2hanja` retains only rows whose reading is one modern Hangul
syllable and whose value is one Hanja character supported by the current
popup: U+3400U+4DBF, U+4E00U+9FFF, or U+F900U+FAFF. Thus word readings,
multi-character values, jamo readings, and supplementary-plane ideographs
are omitted. The import preserves the upstream license header and row order.
The retained data is BSD 3-Clause licensed by Choe Hwanjin; the complete text
is in `LICENSES/BSD-3-Clause-libhangul-hanja.txt`.
## Japanese dictionary data
`kanji.dict` is the historical dictionary bundled with strans. Its own header
identifies it as the SKK Medium dictionary, version 8.1 of May 24, 1995,

582
map/hanja.dict Normal file
View File

@@ -0,0 +1,582 @@
;; Copyright (c) 2005,2006 Choe Hwanjin
;; All rights reserved.
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions are met:
;;
;; 1. Redistributions of source code must retain the above copyright notice,
;; this list of conditions and the following disclaimer.
;; 2. Redistributions in binary form must reproduce the above copyright notice,
;; this list of conditions and the following disclaimer in the documentation
;; and/or other materials provided with the distribution.
;; 3. Neither the name of the author nor the names of its contributors
;; may be used to endorse or promote products derived from this software
;; without specific prior written permission.
;;
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
;; POSSIBILITY OF SUCH DAMAGE.
가 可 家 加 歌 價 街 假 佳 暇 架 价 賈 伽 柯 迦 軻 嘉 駕 嫁 稼 哥 呵 苛 袈 訶 枷 珂 茄 痂 跏 斝 葭
각 各 角 脚 覺 閣 刻 却 珏 恪 殼 慤 榷 骼 桷 礭 搉 卻 躩 咯 埆 擱 塙 阁 愨 覚 礐 殻 胳 傕 崅 茖 佫
간 間 干 看 乾 幹 姦 刊 肝 簡 懇 奸 艮 杆 諫 艱 揀 澗 竿 墾 癎 侃 柬 磵 桿 稈 赶 衎 慳 榦 玕 迀 偘
갈 渴 葛 鞨 竭 喝 褐 曷 碣 蝎 乫 羯 秸 鶡 楬 噶 蠍 暍 渇 輵 轕 鍻 鹖 圿 嵑 嶱 扴 擖 毼 獦 礍 鞂 騔
감 感 減 敢 甘 監 鑑 憾 邯 堪 勘 瞰 紺 柑 疳 坎 戡 鑒 嵌 橄 龕 歛 酣 撼 欿 减 弇 嵁 闞 憨 澉 轗 坩
갑 甲 閘 岬 鉀 匣 胛 韐 瞌 帢 㠷 钾 闸 厒 搕 敆 玾 笚 筪 舺 醘 㓣 㕅 㕉 㗐 㧁 㪉 㭱 䐦 䖬 䗘 䘥 䪺
갓 㖙
강 江 强 講 降 康 綱 鋼 姜 剛 疆 岡 彊 崗 慷 腔 薑 糠 舡 絳 襁 羌 堈 畺 鱇 杠 僵 忼 跫 橿 韁 茳 壃
개 改 開 個 皆 豈 槪 介 蓋 慨 价 塏 箇 漑 芥 凱 愾 盖 鎧 愷 恝 疥 槩 剴 玠 揩 匃 闓 磕 个 丐 葢 㮣
객 客 喀 塥 揢 碦 衉 㗆 䘔
갯 㖋 㖎
갱 更 坑 羹 粳 賡 鏗 硜 秔 鍞 阬 硻 䎴 硁 赓 铿 劥 坈 妔 稉 羮 銵 㧶 㰢 㹴 䃘 䡖 䡠 䡰 䢚
갹 醵 蹻 噱 谻 臄 勪 㖸 㷾 䣰
거 車 去 居 巨 擧 拒 距 據 渠 倨 醵 遽 据 祛 鉅 炬 踞 鋸 迲 裾 袪 蘧 莒 蕖 秬 籧 駏 腒 苣 胠 筥 佉
걱 巪
건 建 乾 件 健 巾 鍵 虔 腱 愆 蹇 騫 楗 褰 謇 鞬 揵 犍 睷 搴 鶱 䖍 諐 湕 徤 乹 寋 㨜 骞 亁 囝 墘 寈
걸 傑 乞 杰 桀 偈 朅 乬 榤 嵥 㐦 滐 搩 櫭 芞 藒 㘶 㹇 䎢 䒗
검 檢 儉 劍 劒 黔 鈐 瞼 撿 芡 岒 臉 劎 俭 倹 剑 剣 捡 检 検 睑 脸 钤 仱 剱 劔 忴 㧄 䇜 䈩 䩎
겁 怯 劫 迲 刦 刧 刼 㤼 㥘 袷 跲 昅 抾 极 砝 蜐 衱 鉣 魥 鵖 㭲 㹤 㾀 䀷 䂲 䂶
것 唟
게 揭 憩 偈 愒 垍 掲 憇
격 格 激 擊 隔 檄 膈 覡 翮 骼 闃 鬲 挌 鴃 毄 撃 繳 閴 綌 鵙 愅 滆 薂 諽 击 绤 缂 缴 觋 阒 䴗 呄 嗝
견 見 犬 堅 遣 牽 肩 絹 甄 譴 鵑 繭 俔 蠲 畎 縳 狷 繾 筧 羂 樫 鰹 牵 掔 汧 岍 熞 縴 梘 罥 汱 甽 詃
결 結 決 潔 缺 訣 拮 抉 闋 觖 絜 玦 鴃 决 鴂 鈌 駃 袺 刔 洯 逫 㓗 结 诀 阕 僪 妜 挗 炔 焆 砄 缼 芵
겸 兼 謙 慊 箝 鉗 鎌 歉 蒹 嗛 縑 傔 拑 檶 鹻 黚 鼸 岒 㻩 鶼 缣 谦 钳 鳒 鹣 嵰 槏 羬 膁 趝 鰜 䈤 䈴
겹 裌 唊 䛟 郟 郏 圶 掐 殎 鵊 䀫 䁍 䩡
경 京 敬 輕 經 慶 更 景 庚 驚 耕 競 境 竟 警 鏡 傾 卿 頃 徑 硬 梗 瓊 儆 璟 炅 勁 鯨 磬 頸 莖 脛 憬
계 計 界 癸 溪 季 鷄 啓 繼 戒 係 系 階 契 桂 械 繫 悸 谿 稽 棨 誡 蹊 屆 磎 堺 雞 烓 罽 薊 堦 髻 禊
고 古 高 告 苦 固 故 考 姑 孤 庫 鼓 稿 枯 顧 雇 賈 皐 錮 拷 痼 辜 膏 叩 股 袴 敲 呱 誥 槁 藁 攷 沽
곡 曲 谷 穀 哭 鵠 梏 斛 轂 嚳 縠 觳 槲 糓 榖 毂 牿 瑴 喾 鹄 俈 匤 唂 唃 嘝 浀 濲 瀔 瀫 焀 焅 硞 硲
곤 困 坤 昆 棍 袞 崑 梱 鯤 滾 琨 衮 閫 悃 髡 鵾 崐 褌 捆 堃 緄 裍 錕 鶤 齫 鯀 壼 滚 髠 璭 綑 稇 晜
골 骨 滑 汨 鶻 矻 榾 搰 汩 杚 圣 馉 鹘 傦 尳 愲 抇 縎 蓇 顝 餶 㐔 㐣 㒴 㾶 䮩 䯇
곱 䯩
곳 廤 蒊 㖛 㖜
공 工 公 功 空 共 恐 恭 供 貢 孔 攻 控 拱 鞏 珙 蚣 跫 倥 崆 蛩 釭 箜 悾 栱 槓 贛 蛬 龔 筇 㓛 㳟 羾
곶 串
과 果 過 科 課 寡 誇 瓜 戈 菓 顆 袴 蝸 跨 鍋 裹 夸 窠 夥 媧 胯 撾 侉 踝 銙 蝌 騍 倮 堝 猓 稞 姱 薖
곽 郭 廓 槨 藿 霍 癨 躩 鞹 椁 矡 漷 钁 崞 瀖 墎 欔 籗 鞟 㗥 㸌 䣤 䦆 䧐
관 官 觀 關 館 管 冠 寬 貫 慣 款 灌 串 莞 琯 棺 瓘 罐 菅 梡 顴 盥 祼 錧 綰 丱 鸛 筦 窾 爟 雚 髖 鑵
괄 括 檜 刮 适 恝 聒 栝 筈 髺 佸 鴰 鸹 劀 懖 桰 葀 銽 頢 颳 鬠 䒷 䟯 䣶 䦚 䯏 䯺
광 光 廣 狂 鑛 匡 曠 壙 胱 筐 洸 侊 珖 炚 絖 誑 纊 恇 獷 磺 桄 茪 框 爌 誆 礦 撗 劻 眶 迋 矌 灮 垙
괘 掛 卦 罫 挂 詿 罣 咼 喎 絓 呙 诖 㖞 叧 啩 枴 柺 褂
괴 怪 愧 壞 塊 槐 傀 乖 魁 拐 媿 坏 恠 瑰 蒯 闠 廥 襘 璝 壊 蕢 瓌 烠 凷 欳 膭 块 蒉 墤 巜 旝 晆 櫆
괵 馘 虢 㶁 蟈 幗 帼 掴 蝈 剨 啯 嘓 慖 摑 漍 聝 腘 膕 䂸 䬎
굉 宏 肱 轟 紘 閎 觥 黌 訇 浤 硡 鍠 鍧 汯 翃 翝 纮 轰 锽 闳 厷 咣 渹 竤 綋 耾 觵 軣 錓 鞃 㚚 䆖 䡌
교 校 交 敎 橋 巧 較 郊 矯 膠 絞 僑 嬌 攪 酵 驕 喬 轎 狡 皎 蛟 咬 嶠 翹 鮫 蕎 餃 徼 榷 嘐 嚙 磽 鉸
구 九 口 求 句 救 究 久 舊 具 苟 俱 區 丘 拘 球 構 懼 驅 狗 龜 邱 歐 鳩 購 鷗 玖 寇 仇 矩 溝 舅 衢
국 國 局 菊 鞠 鞫 麴 匊 跼 掬 麯 国 囯 踘 閰 囗 椈 鵴 锔 侷 囶 囻 圀 婅 巈 挶 梮 檋 毩 毱 泦 淗 焗
군 軍 君 郡 群 窘 裙 捃 皸 桾 羣 頵 涒 军 皲 鲪 侰 僒 宭 帬 攈 攟 珺 皹 莙 蜠 裠 輑 鍕 鮶 鵘 㖥 㪊
굴 屈 窟 掘 堀 崛 詘 矻 倔 淈 朏 胐 诎 崫 弡 煀 虳 袦 誳 趉 镼 鶌 㐇 㐝 㩿 㪂 㭾 㵠 㻕 䂗 䓛 䖦 䘿
굿 㖌
궁 弓 宮 窮 躬 穹 芎 躳 宫 穷 藭 匔 杛 竆 㑋 匑 宆 焪 熍 㴦 䓖 䛪 䠻 䤝
궉 鴌
권 權 卷 勸 券 拳 圈 眷 倦 捲 淃 惓 綣 睠 蜷 棬 勌 勧 劵 巻 踡 鬈 帣 䄅 劝 权 権 绻 锩 勬 啳 圏 埢
궐 厥 闕 蹶 蕨 獗 劂 撅 橛 蹷 橜 鱖 欮 灍 蟨 鷢 镢 阙 鳜 亅 噘 孒 孓 嶡 嶥 憠 氒 瘚 蟩 鐝 㙭 㵐 䙠
궤 軌 蹶 潰 机 詭 櫃 饋 几 跪 匱 樻 簋 餽 憒 劂 繢 闠 佹 氿 麂 撅 簣 䡄 匭 㧪 垝 觤 鐀 陒 馈 匦 匮
귀 貴 句 歸 鬼 龜 晷 巋 帰 䢜 宄 瞶 劌 撌 㱕 嘳 尯 腃 蘬 騩 䝿 刿 归 瞆 贵 椢 槶 櫷 皈 聭 㸵 䁛 䌆
규 規 奎 圭 糾 叫 揆 珪 閨 窺 葵 逵 硅 繆 畦 竅 赳 槻 虬 跬 睽 虯 闚 樛 巋 糺 楏 刲 嬀 潙 暌 頍 馗
균 均 菌 龜 鈞 筠 勻 畇 囷 麏 匀 稛 麕 袀 钧 呁 峮 抣 汮 碅 箘 箟 蚐 覠 銁 銞 麇 㚬 㟒 䇹 䐃
귤 橘 蹫 䤎 䰬
극 極 克 劇 隙 棘 戟 剋 亟 屐 郄 尅 殛 郤 㦸 茍 鋴 隟 㞃 蕀 㥛 剧 丮 勀 勊 娔 撠 橶 氪 裓 襋 㘌 㳳
근 近 根 勤 謹 斤 僅 筋 饉 瑾 槿 覲 懃 芹 菫 劤 跟 靳 卺 蘄 厪 觔 墐 巹 釿 廑 漌 堇 㘦 殣 慬 斳 䈽
글 契 訖 㐎 㔕 䞘 䰴
금 金 今 禁 錦 禽 琴 襟 衾 擒 衿 鈐 芩 檎 昑 妗 噤 嶔 笒 唫 黅 紟 琹 顉 菳 赺 㯲 嵚 钅 锦 僸 凎 凚
급 給 急 及 級 汲 扱 伋 岌 皀 笈 礏 圾 芨 彶 级 给 喼 嬆 忣 礘 觙 鷑 﨤 㤂 㧀 㬤 㽺 䏜 䏠 䲯
긍 肯 兢 矜 亘 亙 殑 矝 堩 絚 緪 肎 刯 奟 掯 揯 搄 縆 肻 褃 錹 鹶 㥤 㮓 䱍 䱎 䱭 䱴
기 己 記 氣 技 起 期 基 其 旣 幾 豈 器 奇 機 旗 紀 棄 忌 企 欺 飢 祈 乞 騎 寄 畿 冀 箕 耆 岐 沂 驥
긴 緊 紧 菣
길 吉 拮 佶 桔 姞 鴶 蛣 洁 趌 鲒 咭 狤 郆 銡 鞊 鮚 㐞 㐟 㣟 䓀 䟌
김 金
끗 㖝
끝 唜
끽 喫 噄
나 羅 那 奈 拿 裸 懶 儺 懦 螺 拏 邏 癩 蘿 喇 娜 挐 挪 糯 梛 糥 郍 砈 穤 傩 镎 乸 哪 嗱 懧 橠 稬 蒘
낙 落 樂 諾 洛 駱 烙 酪 珞 诺 掿
난 難 暖 卵 亂 蘭 欄 爛 鸞 煖 赧 煗 偄 餪 㬉 难 奻 戁 渜 㫱 㬮 䎡 愞
날 捺 捏 涅 陧 苶 䖓 䖧
남 南 男 濫 藍 嵐 楠 枏 湳 襤 喃 柟 娚 揇 㑲 侽 婻 暔 煵 畘 罱 腩 莮 萳 蝻 諵 遖 㓓 㣮 㭷 㵜 㽖 䈒
납 納 拉 臘 蠟 衲 蒳 鈉 纳 钠 妠 笝 軜 靹 魶 㨥 䈫 䪏
낭 浪 娘 廊 狼 囊 朗 郎 曩 嚢 乪 儾 囔 擃 攮 欜 灢 饢 齉 㚂 㶞 䁸
내 內 來 乃 耐 奈 柰 迺 鼐 内 匂 嬭 奶 廼 㮏 褦 㮈 撆 耏 釢 孻 摨 氖 氝 渿 熋 疓 萘 螚 錼 㐻 㚷 㜨
냉 冷
냑 蹃 逽
냥 娘 孃
녀 女 䋈 袽 钕 帤 釹 㵖 䘫
녁 惄 疒 䭆
년 年 撚 秊 碾 涊 䄵 哖 姩 簐 脌 躎 鵇 鼰 㬗 㮟 䄭
녈 涅 圼 篞 夨 㖏 㘿 䂼
념 念 恬 拈 捻 鮎 埝 焾 艌 踗 㑫 䧔 䬯
녑 鑷 喦 惗 䳖 帇 幉 敜 鈢 鉩 錜 㚔 㩶 㵊 䇣 䌰 䎎
녕 寧 獰 寗 佞 濘 嚀 儜 侫 寕 寜 甯 擰 聹 咛 拧 聍 嬣 寍 橣 檸 澝 矃 薴 鑏 鬡 鸋 㝕 㣷 㲌 㲰 㿦 䆨
녘 榒
녜 禰 祢 䄲
노 老 路 勞 怒 露 奴 努 盧 魯 爐 駑 蘆 鷺 虜 擄 弩 帑 櫓 瑙 孥 呶 猱 笯 臑 峱 砮 巙 怓 鑥 镥 驽 䜧
녹 綠 錄 祿 鹿 碌 菉 傉 搙
논 論 嫩 㯎
놀 㐐 㐗
놈 㖈
농 農 弄 籠 濃 膿 聾 壟 穠 儂 醲 噥 禯 癑 侬 农 哝 浓 秾 脓 㶶 嶩 檂 欁 燶 繷 蕽 襛 辳 鬞 齈 䙶 䢉
놔 雫
놜 豽 貀
뇌 雷 腦 惱 賂 牢 磊 餒 餧 脳 挼 憹 垴 恼 悩 脑 馁 匘 堖 娞 捼 碯 腇 鮾 鯘 㑎 㛴 㼏
뇨 溺 尿 撓 鬧 橈 嫋 裊 淖 鐃 嬲 嬈 磠 閙 褭 譊 䙚 袅 铙 闹 嫐 嬝 硇 硵 脲 㒟 㜵 㞙 㠡 㳮 䃩 䃵 䦊
누 樓 漏 淚 累 屢 陋 壘 縷 耨 啂 㝅 鎒 槈 檽 獳 羺 譨 譳 鐞 㜌 㝹 䅶 䨲
눈 嫩 媆 嫰 㜛 㡪 㶧
눌 訥 吶 肭 呐 讷 抐 㕯 䟜
뉴 紐 杻 忸 靵 狃 鈕 扭 䋴 纽 钮 妞 沑 炄 粈 莥 㖻 㺲 䂇 䏔
뉵 忸 衄 恧 朒 衂 䖡 䘐 䚼 䶊
늑 勒 肋 䅞 䎪
늠 凜
능 能 陵 凌 綾 菱 稜 䏻 㴰 䘅
늦 莻
니 泥 尼 禰 怩 膩 呢 柅 祢 你 旎 埮 濔 臡 妳 檷 蚭 迡 腻 铌 伱 倷 坭 妮 屔 您 抳 狔 秜 胒 苨 跜 鈮
닉 溺 匿 搦 嫟 糑 嬺 愵 搻 氼 㥾 㲻
닐 昵 暱 䁥 痆 䘌 䵑 䵒
님 拰 䋻 䌾
닙 㘝 囡
다 多 茶 爹 嗲 夛 茤 觰 跢 鯺 䫂 䯬
단 單 短 端 但 丹 斷 段 團 壇 檀 旦 湍 鍛 緞 簞 蛋 亶 蓴 袒 彖 鄲 坍 担 胆 椴 慱 漙 靼 癉 蜑 耑 澶
달 達 撻 疸 獺 澾 怛 闥 韃 靼 妲 㺚 逹 橽 鐽 呾 燵 㼀 炟 狚 哒 挞 荙 跶 闼 鞑 噠 垯 墶 笪 繨 羍 薘
담 談 擔 淡 潭 膽 譚 痰 澹 曇 憺 湛 聃 覃 啖 蕁 坍 錟 担 胆 墰 禫 啗 毯 郯 噉 儋 薝 黮 壜 忐 罎 黵
답 答 踏 畓 遝 沓 荅 剳 蹋 涾 溚 褡 譶 匒 崉 榙 濌 畣 眔 褟 誻 蹹 躢 鎉 龖 龘 㙮 㜓 㟷 㧺 㭼 㯚 㳫
당 堂 當 唐 黨 糖 塘 撞 棠 螳 幢 戇 倘 儻 党 讜 搪 璫 瑭 瞠 鐺 襠 鏜 溏 餳 檔 礑 蟷 餹 螗 簹 戅 嵣
대 大 代 待 對 帶 隊 貸 臺 台 戴 垈 袋 擡 岱 黛 玳 錞 坮 懟 碓 儓 汏 隶 旲 鐓 㐲 䑓 帯 帒 憝 襨 濧
댁 宅
덕 德 悳 徳 恴 惪 㤫 㥁
도 刀 道 度 圖 島 都 到 徒 逃 導 渡 盜 途 倒 桃 跳 陶 塗 稻 挑 禱 悼 燾 濤 蹈 屠 滔 睹 鍍 掉 堵 兜
독 讀 獨 督 毒 篤 瀆 禿 牘 犢 纛 黷 櫝 髑 独 讟 秃 凟 匵 殰 蝳 錖 韣 椟 渎 牍 犊 笃 読 读 黩 㱩 嬻
돈 敦 豚 頓 惇 沌 燉 褪 遯 旽 暾 墩 焞 潡 噸 弴 瓲 躉 鐓 炖 橔 獤 㬿 㹠 㻻 礅 伅 囤 墪 忳 扥 撉 趸
돌 突 乭 咄 堗 宊 腯 湥 揬 柮 㐑 㟮 㻠 饳 嚉 怢 葖 迌 鈯 鍎 飿 鶟 鼵 㷝 䃐 䠈
돗 㘏
동 同 東 冬 動 洞 童 銅 凍 董 桐 棟 憧 疼 瞳 胴 仝 潼 錬 僮 蕫 彤 侗 峒 佟 蝀 涷 垌 朣 橦 艟 茼 哃
두 頭 讀 斗 豆 杜 兜 痘 竇 逗 荳 枓 斁 蠹 肚 陡 蚪 抖 脰 吋 紏 蠧 餖 㞳 㪷 兠 㺶 阧 﨣 䇺 䢏 䲧 头
둑 㪲
둔 鈍 屯 遁 臀 芚 遯 窀 迍 吨 钝 坉 臋 踲 霕 㩔 㼊 䜳 䤜
둘 乧 㐈 㐙
둣 㖍
둥 㪳
득 得 淂 嘚 锝 棏 鍀 㝶 䙷 䙸
등 等 登 燈 騰 藤 鄧 嶝 謄 橙 滕 鐙 灯 磴 縢 螣 墱 凳 籐 䓁 蹬 䒭 簦 豋 驣 㽅 籘 膯 隥 㔁 腾 誊 邓
똥 㖯 㖰
뜰 㐢
라 羅 裸 懶 螺 拏 邏 癩 蘿 喇 騾 囉 鑼 瘰 臝 砢 倮 曪 驘 覼 蠃 灕 覶 玀 躶 㞅 纙 㼈 䇔 罗 懒 椤 猡
락 落 樂 諾 絡 洛 駱 烙 酪 珞 犖 嗠 硌 濼 鉻 雒 泺 络 荦 铬 饹 骆 峈 笿 餎 鮥 鴼 㓢 㦡 䀩 䈷 䎊
란 丹 卵 亂 蘭 欄 爛 鸞 懶 瀾 欒 闌 鑾 攔 襴 嬾 幱 灓 乱 䦨 滦 灤 斕 圝 圞 灡 籣 兰 拦 斓 栏 栾 澜
랄 剌 辣 喇 埒 辢 捋 獭 垃 埓 揦 揧 攋 楋 瓎 瘌 蝲 頱 鬎 鯻 㸊 㻋 㻝 䀳 䏀 䓥 䓶 䱫 䶛
람 覽 濫 藍 籃 攬 嵐 纜 欖 擥 襤 婪 惏 覧 灠 壈 㲯 䰐 㩜 囕 㑣 岚 揽 榄 滥 漤 篮 缆 蓝 褴 览 䍀 儖
랍 拉 臘 蠟 摺 鑞 臈 爉 䗶 镴 啦 搚 柆 磖 翋 菈 蝋 邋 鞡 㕇 㡴 䂰 䃳 䇱
랑 郞 浪 廊 狼 朗 琅 郎 螂 瀧 瑯 踉 閬 蜋 稂 榔 硠 莨 桹 烺 蓈 鋃 欴 艆 㫰 锒 阆 勆 啷 埌 塱 嫏 崀
래 來 萊 賚 崍 徠 来 淶 騋 顂 勑 徕 莱 䅘 猍 琜 倈 箂 棶 睞 錸 鵣 䋱 䚅 崃 俫 梾 涞 睐 铼 儽 唻 婡
랭 冷 唥
략 略 掠 畧 攊 圙 撂 洜 㑼 㗉 㨼 䂮 䌎 䛚
량 兩 場 良 量 凉 梁 糧 諒 亮 樑 輛 粱 倆 粮 涼 魎 踉 椋 悢 喨 两 両 惊 㾗 湸 緉 裲 輌 輬 俍 俩 唡
려 旅 慮 麗 勵 呂 廬 礪 驪 閭 戾 黎 侶 濾 犁 驢 藜 儷 蠣 櫚 厲 臚 癘 膂 蠡 糲 唳 梠 鑢 儢 邌 吕 沴
력 力 歷 曆 瀝 礫 轢 靂 櫟 櫪 鬲 酈 攊 癧 轣 歴 暦 䔉 厯 皪 屴 朸 檪 磿 礰 躒 历 呖 坜 枥 栎 沥 疬
련 連 練 鍊 憐 戀 聯 蓮 漣 輦 煉 怜 璉 攣 錬 臠 孌 鰱 楝 鏈 孿 湅 鰊 恋 堜 摙 䏈 縺 聨 㜻 链 娈 挛
렬 列 烈 劣 裂 冽 洌 捩 颲 挒 茢 迾 鋢 鴷 㭩 锊 䴕 劽 咧 哷 姴 挘 栵 浖 烮 煭 爄 睙 脟 蛚 蛶 趔 迣
렴 廉 濂 斂 簾 殮 歛 籟 瀲 奩 獫 磏 帘 㢘 嬚 鐮 搛 溓 薕 蘝 蠊 奁 敛 潋 莶 蔹 镰 亷 劆 匲 匳 澰 濓
렵 獵 鬣 躐 儠 擸 猟 巤 犣 聗 鱲 㯿 㲱 㼃 㼲 䁽 䉭 䜲 䝓 䪉
령 令 領 寧 靈 嶺 零 鈴 玲 囹 齡 逞 聆 怜 伶 翎 羚 岺 笭 另 岭 泠 苓 鴒 蛉 欞 呤 昤 姈 秢 軨 鹷 灵
례 禮 例 豊 隷 醴 澧 隸 鱧 礼 㘑 鳢 櫔 欚 濿 犡 瓥 砅 㡂 㤡 㽝 䅄 䵩
로 老 路 勞 怒 露 盧 魯 爐 蘆 鷺 虜 擄 撈 輅 鹵 潞 芦 櫓 瀘 潦 鑪 鱸 壚 騾 艪 顱 艫 鸕 轤 玈 窂 滷
록 綠 錄 祿 鹿 麓 碌 菉 淥 漉 彔 騄 簏 轆 圥 录 盝 籙 禄 醁 緑 廘 録 㖨 睩 蔍 逯 绿 渌 箓 辘 塶 娽
론 論 掄 惀 碖 菕 论 婨 溣 㤻
롱 弄 籠 龐 聾 壟 瓏 朧 瀧 隴 礱 曨 蘢 儱 攏 龎 櫳 壠 巃 哢 礲 䏊 嚨 竉 㺯 胧 厐 咙 垄 垅 拢 昽 栊
뢰 雷 賴 賂 儡 牢 磊 賚 瀨 罍 耒 籟 酹 誄 礧 纇 蕾 顂 攂 礌 頼 瀬 㵢 䨓 藾 鐳 傫 櫑 瓃 礨 䒹 濑 籁
료 料 了 僚 遼 療 聊 寮 燎 瞭 廖 寥 鬧 蓼 潦 醪 繚 膋 撩 暸 獠 鐐 嘹 嫽 飂 飉 憀 憭 鷯 䝤 璙 炓 㵳
룡 龍 龒 矓 眬 龙 徿 爖 竜 蠬 贚 躘 驡 㡣
루 樓 漏 淚 累 屢 陋 壘 縷 婁 鏤 褸 蔞 瘻 螻 僂 髏 嶁 慺 嘍 耬 楼 屡 泪 蝼 塁 摟 塿 䮫 嫘 屚 廔 䫫
류 流 留 柳 類 劉 謬 溜 琉 瘤 繆 瑠 旒 榴 硫 瀏 纍 鶹 縲 瑬 遛 橊 飂 霤 騮 鏐 旈 䄂 鎏 罶 飀 藟 鎦
륙 六 陸 戮 勠 僇 稑 穋 陆 剹 勎 坴 淕 磟 踛 鯥 鵱 㓐 㛬 䡜
륜 倫 輪 崙 綸 淪 侖 掄 錀 踚 崘 圇 棆 仑 伦 囵 抡 沦 纶 轮 嗧 埨 磮 稐 耣 腀 蜦 陯 鯩 㓆 㖮 㷍 䈁
률 律 率 栗 慄 嵂 溧 篥 㟳 硉 瑮 膟 㮚 峍 侓 傈 凓 垏 塛 寽 徍 搮 箻 繂 葎 鷅 麜 㖀 㗚 㪐 䔁 䔞 䡃
륭 隆 瀜 癃 窿 烿 嶐 蕯 湰 霳 㚅 㝫 㦕 䃧 䥢
륵 勒 肋 泐 玏 仂 扐 鳓 嘞 忇 椚 氻 竻 簕 艻 阞 鰳
를 㔹
름 凜 廩 凛 澟 檩 廪 懍 懔 檁 癛 癝 菻 㐭 㨆 䕲
릉 陵 楞 凌 綾 菱 稜 倰 蔆 棱 崚 淩 夌 庱 掕 睖 鯪 绫 鲮 堎 婈 愣 琌 碐 祾 蓤 薐 裬 踜 輘 錂 㖫 㘄
리 里 利 理 異 李 吏 離 履 裏 梨 驪 罹 裡 籬 厘 俚 痢 悧 羸 釐 狸 犁 璃 鯉 唎 莉 浬 漓 莅 离 螭 俐
린 鄰 隣 麟 鱗 吝 躪 燐 璘 藺 潾 獜 磷 粼 嶙 驎 轔 繗 悋 躙 鏻 粦 遴 恡 瞵 䗲 疄 撛 僯 厸 轥 蔺 躏
림 林 臨 淋 琳 霖 痳 惏 冧 崊 晽 棽 瀮 瀶 碄 箖 醂 㝝 㣩 㵉 䫐 玪
립 立 笠 粒 砬 岦 雴 苙 鴗 湁 鉝 㕸 䇉 䢂 䲞 䶘
마 馬 麻 磨 摩 魔 痲 瑪 碼 麽 麿 劘 媽 螞 蟇 麼 蟆 亇 嗎 禡 䔍 嘛 鎷 㦄 吗 唛 妈 嬷 杩 犸 玛 码 祃
막 莫 幕 漠 膜 寞 邈 藐 鏌 瞙 瘼 幙 暯 嗼 鄚 饃 馍 镆 劰 塻 瞐 縸 㠳 㦝 㱳 㷬 䒬 䮬
만 萬 滿 晩 慢 漫 蠻 灣 娩 挽 蔓 瞞 輓 彎 饅 鰻 卍 万 曼 巒 謾 幔 懣 嫚 蹣 墁 悗 縵 鏝 鬘 鏋 湾 晚
말 末 靺 抹 襪 沫 唜 茉 帕 秣 昩 袜 妺 韈 眜 枺 帓 怽 瀎 皌 睰 砞 礣 粖 袹 閁 韤 魩 㑻 㨸 㭐 㶬 䍪
맘 鋄 錽 鎫 㛧 䥑
망 亡 望 忘 忙 妄 罔 茫 網 芒 莽 邙 輞 惘 魍 莾 蟒 漭 汒 网 亾 鋩 蠎 㒺 㤀 兦 㕵 䋄 恾 朢 杗 蘉 誷
매 賣 買 每 妹 梅 媒 埋 枚 魅 昧 寐 罵 邁 煤 呆 楳 眛 莓 玫 沬 苺 酶 霉 浼 霾 䨪 禖 毎 抺 痗 佅 凂
맥 麥 脈 貊 陌 驀 脉 貃 貘 霡 貉 霢 眽 覛 麦 蓦 帞 眿 絈 蛨 衇 㵹 㹮 䘑 䨫 䮮 䳮
맹 孟 盟 猛 盲 萌 氓 黽 甍 甿 虻 儚 蝱 艋 蕄 鄳 锰 勐 掹 擝 橗 瓾 莔 蜢 錳 鯭 鼆 䁅 䇇 䈍 䉚 䓝 䖟
먀 乜
며 旀 厼 㢱
멱 覓 汨 蓂 冪 糸 幎 羃 覔 幂 纟 觅 冖 塓 幦 淿 漞 濗 簚 糹 鼏 㯒 䈿 䌐 䖑 䣾 䮭
면 面 免 勉 眠 綿 冕 沔 娩 緬 眄 麵 棉 俛 緜 麪 糆 湎 靣 丏 偭 㴐 勔 愐 櫋 莬 葂 麫 绵 缅 腼 丆 喕
멸 滅 蔑 衊 篾 㓕 蠛 搣 櫗 灭 孭 幭 懱 揻 薎 鑖 鱴 鴓 㒝 㩢 䁾 䈼 䌩 䘊 䡸 䩏
명 明 命 名 鳴 銘 冥 溟 暝 皿 螟 酩 瞑 蓂 茗 椧 黽 洺 㝠 眀 凕 㫥 詺 䏃 铭 鸣 佲 姳 嫇 慏 掵 朙 榠
몌 袂
모 母 毛 暮 慕 募 模 某 謀 冒 侮 貌 謨 牟 帽 茅 矛 耗 摸 牡 眸 摹 瑁 芼 姆 糢 耄 侔 髦 旄 媢 蟊 嫫
목 目 木 牧 睦 穆 沐 鶩 苜 凩 楘 莯 霂 䳱 㜈 毣 炑 钼 鹜 坶 杢 狇 蚞 鉬 雮 㣎 㾇 䀲 䊾 䑵 䜼 䲷
몰 沒 歿 没 殁 圽 朰 歽 歾 莈
몸 鯍
몽 夢 蒙 朦 矇 濛 曚 瞢 幪 雺 懞 艨 儚 溕 鸏 梦 懵 冡 懜 䑃 蠓 㠓 饛 矒 霿 䤓 䝉 鹲 夣 檬 氋 獴 甮
묘 卯 妙 廟 墓 秒 苗 猫 昴 描 畝 渺 杳 竗 錨 眇 藐 淼 貓 庙 緲 畒 玅 茆 篎 缈 锚 鹋 冇 喵 媌 嫹 峁
묠 乮
무 無 武 務 戊 茂 舞 貿 霧 誣 巫 毋 撫 畝 蕪 憮 拇 无 懋 繆 鵡 珷 楙 廡 騖 膴 儛 嘸 抚 瞀 袤 鍪 婺
묵 墨 黙 默 嘿 纆 嚜 爅 嫼 濹 癦 蟔 㩏 㫯 㷵 䁼 䁿 䘃
문 門 問 文 聞 紊 汶 紋 蚊 吻 刎 們 雯 捫 懣 抆 忞 悗 炆 匁 忟 璊 闻 问 门 懑 㦖 脗 暪 絻 蚉 閿 馼
물 物 勿 沕 岉 昒 粅 㫚 䥼
미 美 米 未 味 尾 微 迷 眉 彌 靡 媚 薇 楣 湄 嵋 渼 謎 黴 梶 弥 弭 糜 縻 亹 瀰 麋 敉 媺 獼 娓 蘼 媄
민 民 敏 閔 憫 悶 旻 旼 珉 玟 愍 泯 岷 緡 黽 閩 忞 暋 緍 湣 忟 罠 苠 鰵 黾 僶 渑 澠 慜 潣 敃 燘 痻
밀 密 蜜 謐 宓 樒 滵 宻 谧 嘧 峚 櫁 淧 蔤 藌 蠠 㫘 㳴 㴵 㵥 䁇 䌏 䛑 䤉
박 朴 迫 博 泊 拍 薄 駁 舶 剝 縛 撲 搏 樸 珀 箔 粕 膊 雹 璞 亳 駮 鎛 墣 欂 牔 髆 剥 敀 礴 襮 廹 愽
반 半 反 飯 班 般 返 伴 盤 叛 頒 槃 斑 潘 搬 磻 攀 畔 蟠 絆 礬 拌 泮 盼 磐 瘢 胖 蹣 扳 搫 頖 攽 朌
발 發 髮 拔 跋 鉢 潑 渤 撥 勃 魃 醱 孛 浡 鈸 鵓 哱 脖 钵 発 彂 綍 髪 沷 㪍 墢 茇 㧞 䟦 袚 襏 抜 犮
밤 湴
방 方 放 防 房 訪 邦 妨 芳 傍 倣 旁 彷 紡 龐 坊 榜 昉 謗 棒 枋 幇 肪 尨 膀 滂 蚌 磅 舫 蒡 仿 牓 髣
배 北 拜 杯 輩 背 配 倍 培 排 裵 俳 賠 陪 徘 胚 湃 裴 盃 褙 焙 坏 坯 琲 扒 蓓 軰 环 桮 辈 拝 醅 禙
백 百 白 伯 栢 帛 魄 柏 佰 粨 苩 銆 洦 鲌 兡 岶 湐 瓸 竡 絔 鮊 㓦 㡍 㼟 㼣 㿟 䞟 䳆 珀
뱀 㖱
번 番 煩 繁 飜 磻 蕃 藩 燔 幡 樊 翻 蘩 繙 膰 袢 畨 璠 旛 轓 旙 瀿 笲 蹯 墦 橎 㺕 嬏 籓 蠜 烦 僠 勫
벌 伐 罰 閥 筏 橃 罸 罚 阀 傠 垡 栰 浌 瞂 藅 㕹 㘺 䇅 䑔 䣹
범 凡 犯 範 范 汎 泛 帆 梵 氾 颿 笵 訉 凢 軓 杋 㠶 舤 㕨 䭵 钒 凣 忛 柉 滼 盕 舧 諚 釩 㴀 䀀 䑺 䒦
법 法 琺 㳒 疺 珐 佱 灋 鍅
벽 壁 碧 僻 闢 璧 癖 劈 擘 霹 蘗 檗 辟 擗 甓 椑 襞 疈 鷿 鼊 薜 皕 躄 躃 湢 澼 綼 鐴 䌟 鲾 䴙 噼 堛
변 便 變 邊 辯 辨 卞 弁 騈 玭 籩 抃 徧 忭 汴 辮 駢 腁 匾 賆 萹 骿 鴘 拚 邉 変 釆 变 辺 昪 㺹 跰 胼
별 別 瞥 鱉 鼈 鷩 彆 别 撇 蹩 莂 潎 䠥 瘪 鳖 丿 嫳 徶 憋 暼 癟 虌 蛂 蟞 襒 覕 鐅 龞 㔡 㢼 㿜 䇷 䋢
병 兵 病 丙 竝 屛 秉 炳 柄 倂 昺 昞 甁 餠 幷 騈 浜 輧 棅 並 迸 駢 缾 搒 塀 絣 鈵 鉼 鋲 并 屏 併 餅
보 步 保 報 寶 補 普 譜 輔 甫 逋 堡 潽 菩 洑 褓 珤 湺 靌 簠 俌 黼 葆 捗 鞴 鴇 盙 宝 寳 莆 歩 踄 椺
복 福 服 復 伏 卜 腹 覆 複 馥 僕 撲 輻 匐 鰒 洑 宓 茯 蔔 輹 仆 扑 幞 濮 鵩 蝮 墣 蝠 箙 菔 袱 㒒 菐
본 本 呠 楍 絊 㡷 㮺 㯻 㶱 䬱
볼 乶
봉 奉 逢 封 鳳 峯 蜂 蓬 俸 縫 捧 鋒 烽 棒 峰 熢 琫 丰 綘 篷 葑 夆 菶 鴌 篈 鳯 塜 賵 芃 捀 艂 蠭 髼
부 父 不 夫 部 富 復 否 婦 浮 扶 府 副 付 負 賦 培 赴 附 簿 符 腐 釜 傅 敷 訃 阜 膚 俯 賻 斧 剖 芙
북 北 踣 僰 鉳
분 分 憤 奮 粉 紛 奔 墳 頒 芬 焚 盆 忿 糞 噴 雰 扮 吩 賁 汾 昐 体 氛 棼 坌 犇 濆 蕡 枌 畚 朌 湓 轒
불 不 佛 拂 弗 彿 黻 紱 髴 祓 茀 芾 岪 艴 韍 咈 巿 紼 怫 昢 刜 坲 帗 煘 笰 仏 払 绂 绋 韨 乀 冹 柫
붓 㖚
붕 朋 崩 鵬 棚 硼 繃 鬅 堋 漰 萠 弸 塴 掤 椖 綳 绷 镚 鹏 倗 傰 嘣 焩 痭 蹦 鏰 㥊 㬟 㵯 㻚 䙖 䨜
비 非 鼻 悲 備 比 飛 秘 費 妃 卑 碑 肥 批 婢 匪 丕 毖 泌 毘 鄙 扉 譬 庇 臂 裨 沸 憊 緋 脾 誹 痺 蜚
빈 貧 賓 頻 彬 嬪 殯 濱 嚬 瀕 贇 牝 斌 浜 玭 檳 鬢 擯 儐 蘋 邠 苹 顰 繽 豳 霦 鑌 鬂 矉 臏 賔 䎙 份
빙 氷 聘 馮 憑 騁 冰 凭 娉 凴 俜 砯 䀻 骋 仌 冫 慿 泵 涄 淜 靐 㓈 㵗 䛣
뿐 兺 哛
사 四 事 食 士 死 思 使 史 私 寺 師 仕 絲 舍 謝 巳 射 司 辭 似 賜 社 斯 祀 査 沙 詞 寫 捨 邪 詐 斜
삭 數 削 索 朔 鑠 槊 爍 箾 蒴 矟 搠 烁 铄 嗍 揱 溹 獡 鎙 㩂 㮶 䀥 䁻 䅴 䌇 䖛
산 山 産 散 算 酸 傘 刪 珊 疝 霰 蒜 汕 繖 訕 餕 潸 毿 狻 鏟 澘 剷 橵 姍 孿 閊 產 筭 删 㪚 跚 滻 㦃
살 殺 蔡 薩 撒 煞 乷 杀 摋 㐊 蔱 萨 榝 樧 脎 虄 閷 䊛
삼 三 參 蔘 森 滲 渗 衫 芟 杉 叅 纔 摻 毿 糝 鬖 椙 櫼 釤 彡 縿 槮 襂 穇 穼 糁 钐 仨 俕 剼 嘇 幓 弎
삽 揷 澁 颯 鈒 歃 翣 鍤 卅 霎 霅 唼 挿 澀 鎝 插 牐 箑 靸 趿 涩 渋 钑 锸 飒 偛 喢 帹 歰 甴 箿 翜 臿
상 上 相 想 常 賞 商 尙 喪 傷 霜 狀 嘗 詳 祥 象 床 桑 像 償 裳 庠 箱 爽 觴 翔 孀 廂 湘 牀 橡 嫦 瀧
새 塞 璽 賽 鰓 崽 壐 玺 赛 鳃 噻 愢 瓕 簺 㗷 㘔 䈢 䚡 䰄 䵘
색 色 塞 索 嗇 薔 穡 愬 槭 濇 瀒 賾 摵 矠 繬 鎍 啬 穑 赜 铯 嗦 懎 擌 栜 歮 歵 泎 洓 瘷 穯 轖 銫 齚
생 生 省 牲 甥 笙 眚 鉎 泩 栍 鼪 殅 湦 珄 苼 貹 﨡 㗂 㽒 㽓 䚇 䲼 䴤
서 西 書 序 暑 庶 徐 署 恕 緖 誓 敍 逝 瑞 舒 曙 棲 胥 黍 鼠 犀 薯 嶼 抒 壻 栖 筮 鋤 絮 墅 捿 婿 叙
석 石 夕 席 昔 惜 釋 析 錫 奭 碩 晳 潟 汐 淅 蓆 腊 舃 蜥 鉐 晰 矽 鼫 释 穸 螫 祏 裼 焬 皙 襫 邜 桞
선 先 仙 善 單 線 船 選 鮮 洗 宣 旋 禪 膳 繕 扇 煽 璿 璇 瑄 癬 腺 亘 羨 銑 蟬 詵 饍 嬋 霰 僊 蘚 跣
설 雪 說 設 舌 泄 薛 卨 屑 洩 渫 褻 楔 齧 偰 揲 爇 紲 稧 媟 碟 暬 挈 絏 䙝 枻 囓 焫 躠 緤 褉 樰 㻡
섬 暹 纖 蟾 陝 殲 閃 贍 剡 憸 摻 銛 譫 睒 韱 孅 笘 殱 爓 纎 棎 掞 㴸 䃸 纤 掺 歼 繊 谵 赡 铦 闪 嬐
섭 葉 涉 攝 燮 躡 懾 歙 囁 聶 鑷 灄 顳 爕 摂 讋 屧 籋 渉 夑 鍱 欇 鞢 躞 嗫 慑 摄 滠 聂 蹑 镊 颞 屟
성 成 星 省 性 姓 城 誠 聖 聲 盛 晟 醒 宬 惺 腥 珹 猩 筬 騂 餳 瑆 渻 垶 峸 狌 晠 煋 郕 鋮 偗 箵 絾
세 世 說 歲 細 洗 勢 稅 貰 笹 洒 繐 蛻 帨 税 嵗 歳 挩 裞 檅 涗 䵻 岁 细 贳 丗 亗 卋 朑 涚 祱 蔧 跩
소 小 少 所 笑 消 素 召 昭 訴 掃 蘇 燒 騷 疎 蔬 巢 紹 邵 沼 蕭 宵 逍 簫 梢 搔 遡 梳 塑 甦 瘙 疏 嘯
속 速 俗 續 束 屬 粟 贖 涑 謖 洬 遬 属 蔌 餗 觫 鋉 梀 誎 簌 続 续 谡 赎 僳 憟 樕 殐 潥 藗 藚 趚 㑛
손 孫 損 遜 巽 飡 蓀 飧 飱 喰 噀 孙 损 狲 荪 逊 巺 愻 搎 槂 潠 猻 蕵 薞 顨 㢲 䁚 䐣 䕖
솔 率 蟀 窣 卛 乺 摔 甩 碿 蜶 㲞 䢦 帥
솟 㕾
송 送 松 訟 誦 頌 宋 悚 淞 竦 柗 鬆 菘 荣 㩳 㞞 讼 诵 锶 颂 倯 凇 庺 彸 愯 憽 捒 枀 枩 梥 楤 檧 蜙
솨 惢 䐝
솰 唰
쇄 殺 刷 鎖 灑 碎 洒 瑣 曬 惢 晒 鎻 鏁 锁 縰 鎩 嗩 埣 㬠 唢 琐 铩 嗮 涮 溑 砕 繀 㕞 䈗 䞆 䣔 䵀
쇠 衰 釗 钊 哸 夊 鞖 㲤 䪎
수 水 手 數 守 首 樹 受 授 收 雖 修 壽 須 誰 秀 愁 遂 隨 囚 殊 輸 需 獸 垂 帥 洙 睡 搜 隋 髓 銖 蒐
숙 宿 叔 淑 孰 熟 肅 夙 菽 塾 璹 潚 琡 倏 俶 橚 儵 鷫 驌 婌 䎘 璛 埱 蓿 倐 焂 鱐 玊 掓 㶖 䃤 䨹 粛
순 順 純 脣 巡 循 旬 殉 瞬 舜 淳 珣 盾 洵 筍 醇 馴 荀 唇 詢 諄 徇 恂 蓴 楯 錞 焞 蕣 栒 橓 肫 鶉 紃
술 戌 述 術 鉥 卹 潏 絉 銊 㺷 荗 珬 沭 欰 蒁 袕 錰 鶐 㖅 㞊 㾁 䢞 䢤 䮅 䳳
숭 崇 嵩 崧 滕 菘 硹 㓽 㟣 㣝 䯷
쉬 倅 晬 淬 焠 伜 琗 㳃 䘹
슬 瑟 膝 蝨 虱 飋 㻭 厀 鲺 濏 璱 鯴 㺩 㻎
습 習 拾 襲 濕 褶 隰 慴 熠 湿 霫 謵 习 袭 鳛 啃 嶍 槢 溼 漝 飁 騽 鰼 㒊 㗩 㠄 㦻 㿇 䏉 䒁 䗑
승 勝 承 乘 僧 昇 升 繩 丞 陞 蠅 塍 鬙 乗 蝇 䋲 鱦 椉 氶 㱡 嵊 憴 縄 绳 冼 呏 堘 抍 斘 枡 桝 榺 橳
시 十 時 始 示 市 寺 視 詩 試 是 施 侍 矢 柴 屍 諡 弑 匙 猜 豺 媤 柿 尸 恃 蓍 謚 豕 翅 屎 嘶 蒔 昰
식 食 式 植 識 息 飾 湜 殖 軾 蝕 拭 熄 寔 埴 篒 栻 喰 媳 鉽 烒 蚀 轼 饣 饰 煶 瘜 禃 籂 蒠 遈 鄎 鎴
신 身 信 臣 新 神 申 辰 辛 愼 伸 晨 紳 訊 迅 腎 燼 宸 薪 呻 蜃 娠 藎 莘 侁 汕 矧 贐 哂 汛 頣 脤 駪
실 室 失 實 悉 蟋 飋 窸 实 実 怸 榁 螅 鏭 鰘 㗭 㣰 㺙 䊝 䶡
심 心 甚 深 沈 尋 審 瀋 沁 諶 芯 沉 潯 梣 椹 燖 葚 鐔 鱏 淰 愖 諗 杺 伈 蕈 㴱 襑 㝷 宷 枔 鬵 煁 瞫
십 十 拾 什 辻 兙 卌 椞 瓧 竍 籵 趇 䦹
쌀 㐘
쌍 雙 双 䨇 艭 孇 欆 﨎 㕠 䉶 䝄
씨 氏
씻 㘒
아 兒 我 雅 亞 餓 芽 牙 阿 衙 俄 訝 啞 鴉 峨 娥 鵝 莪 蛾 迓 疴 哦 婀 丫 峩 娿 砑 笌 錏 鵞 痾 児 婭
악 樂 惡 岳 握 愕 堊 顎 嶽 幄 渥 鰐 鄂 鍔 齷 萼 諤 鶚 咢 喔 噩 卾 腭 偓 覨 齶 楽 鸑 遌 崿 蕚 㮙 堮
안 安 案 眼 顔 岸 雁 鞍 按 晏 鮟 鴈 犴 贋 桉 顏 鷃 贗 䬶 楌 㷳 䅁 赝 颜 铵 顸 侒 偐 垵 堓 妟 姲 婩
알 謁 閼 軋 斡 遏 訐 戞 頞 揠 鴶 嘎 穵 戛 歹 嶭 猰 圠 捾 堨 钀 䵝 讦 谒 轧 阏 劜 咹 嘠 屵 挖 擜 歺
암 暗 巖 癌 庵 闇 岩 菴 俺 唵 諳 黯 嵓 頷 馣 晻 媕 啽 腤 葊 蓭 嵒 碞 韽 揞 黭 痷 萻 鵪 黤 䳺 埯 谙
압 壓 押 鴨 岬 狎 礏 罨 鸭 庒 岋 姶 㔩 䑪 压 圧 儑 匎 圔 庘 曱 炠 砐 硆 鞥 鰪 㕎 㛕 㳌 㷈 㾎 䆘 䑥
앙 仰 殃 央 怏 昻 鴦 秧 盎 鞅 泱 卬 坱 昂 枊 䭹 抰 胦 㟅 䀚 鸯 佒 傟 咉 姎 岇 岟 慃 炴 眏 紻 羻 詇
애 愛 哀 涯 礙 埃 艾 喝 崖 隘 靄 曖 厓 碍 藹 欸 騃 睚 皚 瞹 挨 僾 薆 靉 捱 獃 磑 娭 唉 啀 噯 崕 漄
액 額 厄 液 腋 扼 縊 掖 阨 搤 戹 呝 詻 軛 頟 缢 轭 额 峉 涱 砨 磀 苊 蚅 豟 貖 軶 鈪 阸 㟯 㧖 䘸 䝈
앳 厑
앵 鶯 櫻 鸚 罌 嚶 鷪 罃 嫈 鸎 甖 䴍 嘤 桜 樱 罂 莺 鹦 奣 甇 譻 㴄 㹙 㹚 䁝 䨉
야 夜 野 也 若 射 耶 惹 倻 椰 爺 冶 揶 埜 捓 枒 喏 琊 鋣 嘢 焲 瑘 䤳 爷 铘 乛 亱 偌 吔 壄 婼 擨 漜
약 弱 藥 約 若 略 躍 掠 葯 蒻 鑰 籥 禴 爚 篛 鰯 龠 鶸 瀹 礿 㵸 箬 箹 蘥 㿑 药 哟 约 薬 跃 叒 喲 嵶
양 羊 兩 陽 洋 良 養 量 讓 揚 凉 梁 樣 糧 楊 壤 諒 亮 襄 孃 瘍 攘 釀 恙 禳 痒 佯 暘 穰 瀁 敭 煬 癢
어 魚 語 漁 於 御 禦 圄 瘀 馭 齬 圉 飫 敔 淤 茣 扵 蘓 峿 籞 菸 鋙 渔 语 铻 饫 驭 鱼 龉 仒 唹 棜 秗
억 億 憶 抑 臆 檍 薏 嶷 繶 澺 亿 忆 悥 癔 肊 訲 餩 㫇 䖁 䗷
언 言 焉 彦 諺 堰 偃 讞 嫣 鄢 鼴 匽 鼹 傿 彥 琂 唁 漹 蔫 喭 蝘 讠 谚 谳 嘕 墕 娮 嵃 愝 椻 牪 甗 篶
얼 蘖 孼 臬 孽 糱 乻 臲 闑 隉 嵲 糵 枿 㜸 櫱 蠥 镍 巕 槷 鎳 㙞 㮆 㴪 䡾
엄 嚴 掩 奄 儼 俺 淹 广 閹 晻 崦 弇 罨 曮 醃 釅 渰 揜 顩 㤿 㛪 隒 严 俨 厂 腌 觃 阉 剦 厈 厳 噞 孍
업 業 嶪 鄴 嶫 业 㡤 澲 邺 殗 餣 驜 鸈 㗼 㡋 㪑 㱉 㸣 䁆 䌜 䎨 䤶 䧨 䱒 䲜
엇 旕
엉 㫈
에 恚 曀 饐 殪 㤬
엔 円
여 女 如 餘 與 余 汝 旅 予 麗 輿 勵 呂 廬 礪 驪 閭 黎 濾 歟 轝 茹 璵 艅 礖 舁 与 欤 畬 洳 旟 䂊 蕷
역 力 亦 易 逆 歷 役 驛 譯 曆 域 疫 繹 轢 斁 嶧 懌 鬩 閾 淢 埸 蜮 晹 㴒 湙 帟 棫 燡 睪 鶂 坄 歝 琙
연 年 然 連 煙 練 硏 鍊 宴 延 緣 演 憐 戀 聯 蓮 燃 軟 淵 燕 沿 鉛 咽 衍 捐 硯 漣 姸 筵 輦 懦 椽 鳶
열 說 熱 列 悅 烈 劣 裂 閱 咽 涅 爇 噎 拽 揑 潱 閲 恱 湼 阅 悦 热 蠮 㖶 䆕 䆢 䊦 䭇
염 念 炎 鹽 染 廉 厭 閻 焰 簾 艶 殮 苒 髥 琰 剡 捻 枏 錟 塩 冉 灎 饜 魘 灩 靨 黶 扊 檿 焱 懕 檶 釅
엽 葉 獵 燁 曄 叶 揲 楪 魘 爗 熀 靨 曅 饁 瞱 曗 擛 晔 烨 靥 馌 偞 僷 嚈 擪 擫 枼 枽 殜 皣 瞸 鐷 㒯
엿 㖲 㖳
영 永 英 令 領 榮 迎 營 寧 靈 嶺 影 詠 映 泳 零 盈 塋 鈴 瑛 玲 囹 暎 穎 纓 瑩 聆 怜 楹 瀛 潁 嶸 霙
예 禮 例 藝 豫 譽 銳 隷 預 睿 泄 醴 濊 芮 詣 曳 裔 穢 洩 刈 乂 倪 霓 猊 汭 蘂 叡 隸 翳 繄 睨 蕊 鯢
오 五 午 惡 吾 誤 烏 悟 吳 嗚 汚 娛 傲 奧 梧 墺 伍 寤 懊 禑 澳 鰲 鼇 晤 敖 塢 熬 獒 筽 蜈 俉 旿 忤
옥 玉 屋 獄 沃 鈺 鋈 狱 莹 钰 剭 媉 砡 箼 軉 鳿 㓇 䑁 䞝
온 溫 穩 蘊 縕 瘟 瑥 醞 慍 氳 韞 媼 昷 薀 轀 熅 饂 鰮 温 愠 藴 蕰 氲 醖 馧 鞰 榲 蒕 塭 瘒 鎾 蕴 酝
올 兀 膃 嗢 腽 杌 卼 屼 扤 矹 㐏 乯 䪲 淴 瞃 阢 靰 鼿 齀 㐚 㐳 㽾 䑢 䦍
옹 翁 擁 雍 壅 甕 邕 瓮 饔 癰 顒 喁 蓊 雝 滃 罋 禺 廱 癕 痈 臃 䩺 㙲 㝘 拥 颙 勜 嗈 嗡 噰 塕 嵡 暡
와 臥 瓦 訛 蝸 渦 蛙 窩 鍋 窪 娃 洼 哇 媧 涴 譌 萵 囮 枙 窊 婐 猧 卧 鼃 吪 䨟 捰 漥 鈋 涡 窝 莴 蜗
왁 䢲
완 完 緩 莞 頑 宛 婉 阮 琓 玩 浣 腕 翫 椀 琬 碗 梡 脘 豌 惋 岏 蜿 盌 刓 涴 忨 垸 妧 薍 剜 抏 輐 园
왈 曰 刖 嗗 聉 䚴
왕 王 往 旺 汪 枉 尫 迬 瀇 徃 尢 仼 㲿 尣 尩 尪 彺 忹 暀 蚟 㑌 㒬 㞷 㳝 㳹 㴏 䤑 䶭
왜 倭 矮 娃 歪 媧 騧 娲 劸 緺 躷 㗏 㰪 䶐
외 外 畏 猥 巍 嵬 聵 煨 隗 磈 偎 崴 碨 嵔 渨 隈 廆 桅 椳 詴 懀 揋 腲 聩 鳂 峞 徻 愄 溾 瘣 葨 鍡 鮠
욋 夞
요 要 樂 料 了 謠 僚 遙 陶 搖 腰 遼 堯 妖 耀 療 曜 姚 尿 擾 撓 饒 邀 夭 寮 僥 燎 窈 咬 凹 拗 窯 寥
욕 欲 浴 辱 慾 褥 縟 溽 蓐 鵒 鄏 昙 缛 鹆 嗕 媷 峪 輍 鋊 㦺
용 用 容 勇 龍 庸 踊 鏞 茸 鎔 傭 溶 瑢 熔 聳 湧 蓉 涌 冗 墉 俑 甬 慂 榕 埇 舂 慵 宂 踴 憃 嵱 筩 硧
우 右 牛 雨 友 又 宇 于 尤 憂 遇 愚 優 羽 郵 偶 佑 祐 禹 迂 虞 寓 隅 禑 雩 紆 瑀 盂 旴 亐 芋 藕 玗
욱 旭 郁 煜 頊 昱 勖 澳 彧 栯 稶 燠 隩 勗 䤋 薁 稢 㮋 顼 喐 旮 朂 礇 㤢 㦽 㰲 䉛 䜡
운 雲 運 云 韻 芸 暈 隕 殞 耘 蕓 澐 橒 熉 紜 韵 惲 沄 霣 篔 餫 鄆 鄖 溳 夽 愪 抎 縜 韗 䩵 殒 恽 筼
울 鬱 蔚 亐 熨 欝 㭗 菀 鬰 爩 黦 䁌 欎 灪 㐛 㠨 䖇 䵥
웅 雄 熊 䧺 僌 㞲 㷱
원 元 原 遠 園 願 圓 怨 院 員 源 援 苑 瑗 袁 媛 寃 猿 鴛 阮 轅 垣 爰 愿 琬 湲 沅 嫄 洹 円 冤 圜 鵷
월 月 越 鉞 粤 刖 粵 樾 軏 戉 抈 狘 钺 钥 仴 岄 怴 枂 泧 蚎 蚏 跀 鈅 㜧 㞽 㳉 䄴 䋐 䎳 䞲 䟠 䡇 䢁
위 位 危 爲 威 偉 謂 衛 委 慰 圍 僞 胃 違 倭 緯 尉 魏 蔚 渭 韋 萎 瑋 葦 蝟 暐 褘 蔿 為 諉 闈 衞 逶
유 有 流 由 油 留 猶 柳 遺 遊 酉 唯 幼 柔 惟 類 裕 悠 誘 乳 儒 維 愈 幽 劉 兪 踰 庾 楡 紐 癒 諭 游
육 六 肉 育 陸 戮 堉 毓 儥 淯 錥 哊 唷 喅 宍 棛 焴 蒮 蘛 蜟 袬 逳 㣃 㥔 㻙 䋭 䘻
윤 倫 輪 尹 允 潤 閏 崙 胤 鈗 淪 贇 勻 畇 奫 玧 昀 鋆 酳 閠 狁 蝡 㣧 阭 润 赟 闰 橍 膶 荺 蜳 馻 㠈
율 律 率 栗 慄 聿 潏 矞 茟 䢖 欥 鴥 噊 燏 繘 銉 驈 鱊 鴧 㐕 㐠 㯨 䋖 䫻 䮇 汩
융 隆 融 戎 絨 瀜 狨 羢 漋 娀 㭜 肜 駥 绒 曧 毧 茙 螎 䘬
은 銀 恩 隱 殷 誾 垠 圻 慇 訔 听 憖 嚚 狺 溵 檼 癮 垽 鄞 圁 珢 齗 齦 隠 隐 穏 稳 垦 㤙 檃 㥯 櫽 泿
을 乙 鳦 圪 钇 釔 䎲
음 音 飮 陰 吟 淫 蔭 喑 愔 霪 崟 廕 隂 䕃 飲 瘖 婬 霠 阥 霒 荫 阴 饮 乑 侌 噖 噾 崯 摿 淾 烎 癊 碒
읍 邑 泣 揖 挹 悒 浥 裛 湆 䭂 俋 唈 歞 湇 㘊 㱞 㴔 㵫 䇼 䉗 䓃 䔱
응 應 凝 鷹 膺 譍 应 応 鹰 噟 軈 㒣 㣹 㶐 㶝 䧹
의 衣 意 義 依 醫 矣 議 宜 儀 疑 誼 擬 毅 椅 縊 倚 懿 蟻 薏 艤 錡 猗 嶷 欹 漪 儗 劓 螘 饐 凒 礒 医
이 二 耳 里 利 理 異 以 而 李 已 移 易 吏 離 履 裏 梨 伊 夷 泥 珥 弛 貳 怡 罹 餌 裡 痍 爾 痢 姨 貽
익 益 翼 翊 溺 翌 匿 謚 瀷 弋 鷁 熤 榏 釴 杙 嗌 艗 黓 䄩 谥 鹢 浳 熼 獈 穓 膉 芅 蛡 隿 霬 骮 齸 㔴
인 人 仁 因 引 印 寅 忍 認 鄰 隣 姻 咽 麟 刃 湮 鱗 吝 燐 蚓 靭 璘 茵 絪 靷 藺 堙 仞 禋 夤 氤 裀 婣
일 一 日 逸 壹 鎰 佾 溢 佚 馹 軼 泆 釰 皼 衵 壱 轶 镒 驲 劮 呹 囸 夁 嬄 弌 浂 燚 辷 鈤 鴩 鷧 㳑 䒤
임 林 壬 任 臨 賃 姙 淋 稔 荏 恁 妊 衽 飪 絍 銋 袵 餁 紝 棯 腍 鈓 㶵 䄒 临 纴 赁 饪 栠 栣 祍 秹 菍
입 入 立 笠 粒 卄 廿 込 圦 扖 杁 魞 鳰
잇 㗡
잉 剩 孕 仍 芿 媵 剰 賸 礽 陾 䞉 扔 膡 艿 辸 㑞 㚺 㞌 㭁 㺱 䄧 䚮 䵴
자 子 自 者 字 姉 慈 資 姿 玆 紫 恣 刺 滋 疵 雌 磁 炙 諮 藉 煮 仔 蔗 瓷 炸 咨 孜 茨 薺 茲 貲 眦 孶
작 作 昨 爵 酌 杓 灼 雀 鵲 綽 勺 嚼 芍 醋 炸 斫 酢 怍 焯 碏 柞 岝 汋 犳 斱 妁 鷟 婥 爝 皭 圴 扚 禚
잔 殘 盞 棧 孱 潺 戔 剗 驏 残 醆 僝 刬 戋 栈 盏 骣 嶘 拃 桟 潹 琖 菚 虥 虦 輚 轏 㟞 㥇 㮍 㱚 㻵 䎒
잘 囐 乽
잠 潛 暫 蠶 箴 簪 湛 岑 潜 蚕 涔 梣 笒 濳 蹔 蘸 埁 簮 熸 篸 賺 撏 蠺 挦 暂 臜 赚 兂 喒 寁 揝 撍 昝
잡 雜 閘 襍 磼 霅 卡 囃 眨 匝 迊 雑 帀 啑 煠 咂 币 杂 咔 嘁 抸 拤 沞 疀 砸 譗 鉔 雥 韴 㧜 㬁 䕹 䙄
잣 㗯
장 長 場 將 章 壯 狀 張 掌 丈 腸 帳 障 獎 葬 藏 莊 墻 裝 粧 臟 匠 庄 璋 蔣 樟 杖 仗 獐 醬 漿 檣 薔
재 在 才 材 再 財 哉 栽 載 災 裁 宰 滓 齋 梓 縡 渽 齎 灾 纔 菑 榟 夈 扗 崽 賫 㢤 䝴 賷 㦲 捚 烖 賳
쟁 爭 錚 諍 箏 崢 鎗 瞠 鐺 琤 猙 争 峥 筝 掁 崝 掙 䋫 挣 狰 诤 铮 噌 崡 棦 碀 趟 鏳 鏿 饓 鬇 㓌 㬹
저 低 貯 諸 著 底 抵 沮 躇 猪 邸 咀 箸 詛 狙 苧 儲 楮 佇 這 渚 紵 杵 疽 雎 樗 菹 姐 觝 藷 齟 詆 氐
적 赤 的 敵 適 賊 積 籍 跡 績 摘 寂 滴 蹟 笛 炙 迹 嫡 藉 謫 狄 吊 迪 勣 翟 鏑 荻 糴 逖 覿 幘 磧 樀
전 田 前 全 電 戰 展 傳 典 錢 專 轉 殿 顚 甸 悛 奠 箭 銓 箋 塡 餞 篆 纏 剪 煎 廛 氈 輾 顫 澱 癲 栓
절 節 絶 切 折 竊 截 浙 癤 窃 軼 晢 岊 卩 晣 蕝 嶻 絕 㔾 绝 棁 疖 节 卪 尐 幯 撧 擮 棳 楶 沏 聺 苆
점 店 點 占 漸 粘 霑 点 拈 岾 鮎 玷 覘 佔 簟 苫 墊 黏 颭 蔪 笘 蛅 坫 阽 痁 扂 蒧 㸃 磹 鲇 垫 渐 觇
접 接 蝶 渫 摺 揲 楪 鰈 慴 檝 蹀 跕 椄 蜨 艓 褋 䐑 鲽 挕 擑 聑 菨 襵 㑙 㢎 䐲 䝃 䝕 䪓
정 正 定 丁 政 情 庭 停 精 靜 貞 井 淨 頂 廷 征 程 亭 整 鄭 訂 晶 呈 鼎 旌 挺 禎 偵 汀 楨 艇 珽 靖
제 弟 第 題 諸 祭 除 帝 製 制 濟 提 際 齊 堤 劑 悌 蹄 梯 啼 霽 臍 薺 醍 荑 齎 儕 躋 擠 隄 娣 禔 睇
조 朝 祖 助 鳥 調 造 早 兆 條 照 操 租 弔 潮 組 跳 趙 曺 祚 燥 措 遭 釣 彫 曹 詔 阻 粗 漕 凋 稠 藻
족 足 族 簇 鏃 蔟 瘯 哫 镞 踿 㞺 㵀
존 存 尊 拵 鐏 燇 橂 袸 銌
졸 卒 拙 猝 倅 脺 捽 㐒 稡 椊 踤 卆 炪 箤 㐍 㰵 䂐 䘚 䚝 䯿 䱣
종 終 宗 種 從 鐘 縱 腫 琮 綜 踵 踪 慫 鍾 淙 悰 棕 倧 蹤 瘇 螽 椶 蓯 粽 伀 慒 柊 樅 瑽 従 縦 嵸 騣
좌 左 坐 佐 座 挫 髽 剉 莝 痤 㘴 脞 袏 锉 侳 咗 夎 屮 睉 矬 蓌 蓙 趖 遳 銼 㔫 㘸 㛗 㝾 㟇 㭫 䂳 䟶
죄 罪 辠 嶵 檌 㠑 㪓
주 主 住 走 注 晝 朱 宙 酒 州 周 舟 柱 洲 珠 株 奏 鑄 駐 疇 週 躊 誅 註 紬 做 稠 廚 紂 嗾 呪 輳 冑
죽 竹 粥 鬻 俼
준 準 俊 遵 准 浚 峻 駿 埈 濬 晙 樽 竣 蠢 儁 雋 畯 逡 寯 焌 罇 蹲 隼 餕 撙 惷 綧 噂 踆 皴 埻 墫 鐏
줄 茁 乼 崒 崪 窋 笜 㤕
줏 㗟
중 中 重 衆 仲 眾 褈 众 妕 媑 狆 筗 舯 茽 蚛 蝩 衶 迚 鈡 隀 㐺 㑖 㣡 㲴 㴢 䌬 䝦 䦿 䳯
즉 則 卽 即 喞 鯽 唧 萴 崱 莭 蝍 鲗 鲫 揤 皍 荝 鰂 鱡 㑡 䐚
즐 櫛 騭 喞 瀄 堲 栉 骘 擳 楖 㘉
즘 怎
즙 輯 汁 葺 楫 檝 蕺 濈 湒 霵
증 曾 增 證 贈 症 憎 蒸 拯 烝 甑 繒 証 嶒 矰 罾 曽 増 璔 橧 鄫 熷 驓 䎖 缯 赠 囎 撜 潧 磳 竲 篜 譄
지 地 知 至 志 之 止 紙 持 指 識 支 只 枝 智 池 誌 遲 旨 址 芝 脂 肢 祉 咫 摯 枳 祗 趾 祇 砥 贄 漬
직 直 職 織 稷 稙 禝 溭 㮨 聀 犆 樴 嬂 织 职 膱 蘵 蟙 軄 㞋 㹄 䐈
진 眞 進 盡 辰 陳 振 震 陣 珍 鎭 晉 塵 津 秦 診 嗔 疹 賑 晋 軫 唇 搢 臻 殄 縉 榛 袗 瑨 畛 璡 縝 瞋
질 質 疾 秩 姪 迭 跌 窒 叱 嫉 帙 佚 桎 膣 侄 蛭 瓆 絰 軼 躓 騭 垤 郅 鑕 蒺 咥 耋 晊 抶 銍 袠 瓞 袟
짐 朕 斟 鴆 酖 酙 㯢 鸩 栚 㘰 㪸 㮳 㴨 㼉 䧵 䲴
집 集 執 輯 什 緝 潗 鏶 戢 咠 諿 縶 㠍 慹 㙫 㠎 䌖 蓻 䐕 执 絷 缉 辑 亼 偮 卙 嶯 瓡 艥 謺 鍓 雦 雧
짓 嗭
징 徵 懲 澄 澂 瀓 瞪 癥 徴 憕 惩 㠞
차 車 次 此 且 借 差 茶 叉 遮 嗟 蹉 箚 嵯 釵 磋 侘 槎 苴 瑳 佽 奓 硨 岔 偖 徣 姹 䂨 劄 汊 杈 莗 唶
착 着 著 捉 錯 躇 搾 鑿 窄 齪 斲 戳 擉 斵 斮 諑 娖 浞 笮 娕 珿 凿 诼 错 龊 丵 剒 撯 擆 灂 穛 篧 簎
찬 贊 讚 餐 瓚 燦 鑽 璨 撰 饌 纂 簒 竄 纘 粲 飡 澯 攢 爨 賛 欑 巑 趲 儧 儹 劗 湌 纉 㸑 攅 讃 酇 篡
찰 察 刹 札 擦 紮 扎 拶 咱 哳 巀 剎 檫 礸 詧 鑔 铡 镲 乲 偺 嚓 攃 桚 櫒 礤 糌 紥 耫 蚻 蠿 鍘 㞉 㦫
참 參 慘 慙 斬 站 讒 僭 讖 塹 懺 叅 慚 驂 譖 黲 巉 嶄 槧 鑱 憯 摻 攙 饞 欃 儳 毚 鏨 参 惨 僣 㕘 叁
창 唱 窓 昌 倉 創 蒼 暢 彰 滄 敞 昶 倡 漲 槍 瘡 愴 脹 娼 猖 菖 廠 艙 悵 搶 鬯 刱 倀 蹌 鎗 閶 氅 惝
채 採 菜 采 彩 債 蔡 埰 寨 綵 釵 寀 砦 茝 棌 瘵 蠆 瘥 倸 囆 债 虿 钗 䌽 婇 榸 睬 縩 踩 靫 㥒 㦅 㳗
책 責 冊 策 柵 翟 簀 嘖 磔 幘 笧 蚱 栅 册 筞 䇿 㥽 舴 茦 謮 啧 帻 箦 责 厇 嫧 憡 拺 敇 皟 瞔 箣 籷
처 處 妻 悽 凄 萋 淒 覷 褄 郪 䖏 处 処 覰 觑 刞 竌 紪 緀 耝 覻 霋 鶈 㜘 䁦
척 尺 拓 斥 戚 刺 隻 陟 滌 擲 瘠 脊 倜 慽 剔 蹠 惕 跖 摭 躑 俶 蜴 塉 捗 呎 坧 褁 慼 蹐 掦 鶺 隲 蹢
천 天 千 川 泉 淺 遷 賤 薦 踐 串 釧 擅 穿 喘 闡 阡 舛 韆 仟 玔 蚕 荐 倩 濺 洊 蕆 蒨 茜 芊 俴 儃 辿
철 鐵 哲 徹 撤 澈 喆 轍 綴 凸 輟 銕 掇 啜 惙 餮 歠 剟 埑 錣 飻 鉄 腏 鐡 畷 䮕 醊 㯙 悊 㬚 彻 缀 辍
첨 添 尖 瞻 僉 諂 籤 沾 詹 簽 甛 忝 簷 憸 檐 槧 襜 栝 惉 瀸 幨 櫼 甜 韂 籖 悿 湉 掭 沗 裧 冿 噡 婖
첩 妾 諜 帖 牒 疊 貼 捷 輒 堞 睫 褶 喋 鰈 怗 褺 倢 呫 輙 㡇 疂 倿 氎 耴 䴴 婕 牃 疉 穕 䩞 钻 叠 畳
청 靑 淸 請 聽 晴 廳 菁 鯖 倩 听 凊 圊 婧 蜻 鶄 青 清 㕔 聼 聴 廰 厅 庁 请 鲭 䴖 厛 夝 掅 暒 氰 甠
체 體 切 遞 滯 替 逮 締 涕 綴 諦 剃 体 軆 砌 棣 彘 泚 蕞 蔕 薙 蒂 殢 靆 嚏 髰 遆 滞 逓 禘 掣 遰 杕
초 草 初 招 超 礎 抄 肖 秒 哨 楚 焦 礁 稍 樵 貂 梢 炒 憔 硝 蕉 醋 醮 椒 酢 剿 艸 湫 苕 迢 誚 勦 悄
촉 觸 屬 燭 促 蜀 囑 矗 鏃 躅 矚 髑 爥 曯 薥 嘱 瞩 斸 瘃 蠋 劚 歜 灟 触 烛 㔉 亍 孎 斶 欘 竐 脨 臅
촌 寸 村 忖 邨 吋 刌 屗 澊 籿
총 總 聰 銃 寵 叢 塚 摠 悤 蔥 憁 葱 驄 蓯 鏦 騘 冢 捴 総 揔 匆 偬 漎 怱 緫 聦 傯 棇 潨 聡 忩 璁 藂
촬 撮 娺 攥 窡 繓 襊 㔍 㭮 㵶 䆯 䵵
쵀 啐 啛 祽 錊 䦤
최 最 催 崔 摧 蕞 淬 榱 璀 漼 縗 脧 嘬 磪 㝡 嗺 墔 慛 槯 綷 缞 凗 樶 欼 熣 獕 皠 穝 紣 羧 膗 鋷 鏙
추 秋 推 丑 追 抽 醜 趨 鄒 楸 椎 樞 墜 酋 芻 錐 槌 錘 鎚 鰍 藪 雛 騶 皺 諏 湫 杻 萩 麤 蒭 瘳 惆 簉
축 祝 丑 築 逐 縮 畜 蓄 軸 蹴 柚 蹙 筑 竺 舳 蹜 豖 槭 妯 鼀 踧 柷 滀 拀 閦 笁 蓫 䠞 缩 轴 丒 傗 嘼
춘 春 椿 瑃 櫄 杶 橁 䞐 堾 媋 旾 暙 杽 湷 睶 萅 萶 蝽 賰 鰆 鶞 㖺 㫩 㿤 䞺 䡅 䦮 䲠
출 出 黜 朮 秫 术 怵 絀 岀 础 绌 怷 樎 欪 泏 炢 莍 黢 㑁 㔘 䘤 䟣 䢺
충 忠 充 蟲 衝 衷 沖 冲 虫 忡 珫 艟 种 䖝 翀 盅 揰 浺 漴 茺 㤝 茧 嘃 爞 痋 祌 㓍 㥙 㧤 㮔 㳘 㳞 䂌
췌 悴 萃 贅 膵 瘁 揣 惴 顇 疩 赘 忰
취 取 就 吹 趣 臭 醉 聚 炊 娶 翠 脆 驟 鷲 嘴 揣 觜 毳 冣 橇 酔 竁 翆 骤 鹫 噿 嶉 槜 檇 欈 濢 璻 脃
측 測 側 惻 仄 厠 廁 昃 稄 厕 侧 恻 测 庂 捑 昗 汄 畟 㳁 䈟
츤 襯 櫬 藽 齔 儭
츰 闖
층 層 蹭 层 䁬
치 治 致 齒 置 恥 値 徵 雉 痴 稚 峙 馳 侈 熾 幟 嗤 緻 痔 癡 緇 蚩 穉 嵯 埴 梔 淄 輜 寘 鴟 螭 廁 巵
칙 則 勅 飭 敕 恜 侙 慗 遫 鶒 鷘 则 饬 淔 趩 鉓 䳵
친 親 襯 櫬 齔 藽 嚫 瀙 䞋 亲 榇 衬 龀 儬 媇 寴 澵 齓 䠳 䠴
칠 七 漆 柒 㓒 㭍 桼 㐂 㓼 㓿 㔑 㯃 䜉 䣛
침 針 沈 侵 寢 浸 枕 鍼 砧 湛 琛 諶 忱 沉 駸 鋟 寖 梣 椹 郴 祲 碪 伔 寑 抌 踸 揕 枮 梫 賝 䆮 䑣 寝
칩 蟄 馽 蛰 漐 釞 㙷 㞏 㞚 㮑
칭 稱 秤 称 穪 偁 爯 㛵 䕝
카 㻔 佧 胩
쾌 快 獪 夬 噲 儈 侩 哙 叏 筷
타 他 打 妥 墮 隋 惰 唾 陀 駝 舵 楕 馱 朶 咤 拖 迤 駄 躱 沱 詑 跎 詫 佗 鼉 駞 柁 拕 橢 鮀 垞 阤 坨
탁 度 濁 拓 托 卓 濯 託 琢 擢 鐸 坼 啄 倬 柝 晫 琸 拆 橐 涿 逴 籜 踔 趠 沰 矺 蘀 乇 槖 椓 侂 跅 魠
탄 歎 彈 炭 誕 灘 綻 憚 呑 坦 嘆 殫 癱 攤 憻 驒 惮 殚 弹 吞 瘓 撣 僤 嘽 掸 啴 弾 摊 滩 痪 瘫 绽 诞
탈 脫 奪 侻 梲 敓 夺 捝 脱 敚 毲 痥 莌 鮵 鵽 㣞 䫄
탐 探 貪 耽 眈 酖 嗿 忐 醓 撢 躭 贪 赕 僋 沊 賧 㤾 㴷 㵅 䏙 䏥
탑 塔 搭 榻 鰈 搨 塌 傝 闒 嗒 撘 漯 㲮 鑉 鞜 鞳 㗳 阘 鳎 嚃 墖 毾 溻 狧 瘩 禢 耷 遢 錔 鎑 鮙 鰨 㛥
탕 糖 湯 蕩 宕 帑 盪 碭 蘯 燙 逿 簜 蝪 踼 璗 鐋 荡 汤 烫 砀 铴 偒 圵 婸 摥 菪 薚 趤 雼 㼒 䑗 䦒
태 太 泰 態 殆 怠 台 胎 兌 跆 颱 汰 苔 笞 邰 呆 駄 迨 蛻 駘 埭 娧 孡 抬 兑 紿 蜕 䭾 鮐 忕 呔 兊 忲
택 宅 擇 澤 択 择 沢 泽 伬 烢 礋 蠌 鸅 㡯 㭦 䕉 䕪 垞
탱 撑 撐 牚 竀 樘 橖 橕 㯑
터 攄 摅
토 土 討 吐 兎 菟 兔 圡 茔 讨 钍 堍 汢 芏 莵 釷 鵵 㫦
톤 噸 噋 瓲 啍 畽 䵯
톨 㐋
통 通 洞 統 痛 慟 筒 桶 恫 侗 筩 樋 㷁 憅 熥 綂 恸 统 嗵 捅 痌 蓪 㣚 㪌 㳆
퇴 退 椎 頹 堆 槌 腿 鎚 褪 焞 搥 隤 魋 頽 僓 蓷 痽 頺 俀 尵 䫋 颓 垖 塠 嵟 弚 桘 煺 磓 穨 脮 藬 蘈
투 投 鬪 透 套 鍮 妬 偸 渝 妒 骰 偷 闘 鬭 哣 敨 牏 秺 緰 蘣 鬦 鬬 㕻 㖣 㚐 㢏 㪗 䛠 䞬 䟝 䤅
퉁 佟
특 特 慝 忒 螣 蟘 貣 铽 忑 脦 蚮 鋱 鴏 㥂 㧹
틈 闖 闯
파 破 波 罷 播 派 頗 把 坡 巴 婆 跛 琶 芭 爬 擺 陂 杷 霸 叵 怕 葩 皤 帕 簸 灞 玻 笆 鄱 妑 岥 爸 耙
판 判 板 版 販 阪 辦 坂 瓣 鈑 汴 辧 昄 舨 蝂 办 贩 钣 岅 瓪 畈 眅 粄 鵥 㤆
팔 八 叭 捌 扒 朳 汃 仈 哵 玐 釟 㭭
팟 巼
팡 乓
패 貝 敗 牌 悖 覇 佩 沛 稗 唄 狽 浿 霈 霸 孛 旆 珮 犻 誖 邶 棑 捭 㶚 斾 矲 郥 呗 狈 贝 败 钡 伂 姵
팽 庄 彭 硼 膨 澎 烹 祊 砰 蟚 蟛 伻 閍 碰 嘭 嵭 憉 掽 梈 甏 皏 硑 磞 稝 軯 輣 錋 闏 騯 㑟 㤣 㧸 㱶
퍅 愎
편 便 篇 片 遍 偏 編 扁 鞭 騙 翩 徧 褊 艑 蝙 匾 諞 惼 緶 萹 煸 蹁 楩 楄 鯾 鯿 缏 编 谝 骗 鳊 囨 媥
폄 貶 窆 砭 贬
평 平 評 坪 萍 枰 苹 抨 怦 泙 蓱 鮃 玶 呯 䦕 评 鲆 匉 姘 岼 拼 胓 蚲 閛 駍 㛁 㺸 䍬 䓑
폐 閉 廢 肺 弊 蔽 幣 陛 斃 吠 嬖 獘 敝 癈 狴 廃 杮 梐 㢢 幤 废 毙 箅 闭 櫠 獙 砩 蕟 蜌 鄨 鐾 閇 鼣
포 布 抱 暴 捕 浦 胞 包 飽 砲 抛 鋪 逋 怖 鮑 泡 葡 褒 袍 蒲 圃 脯 哺 曝 匍 咆 疱 苞 佈 匏 庖 炮 晡
폭 暴 爆 幅 瀑 曝 輻 曓 䋹 䌿
폿 喸
표 表 標 票 漂 杓 豹 飄 剽 慓 瓢 俵 彪 驃 飇 縹 摽 殍 鑣 裱 僄 嫖 勡 嘌 熛 鏢 髟 鰾 飆 颷 醥 淲 藨
푸 䬌
품 品 稟 禀 榀
풍 風 豊 楓 諷 馮 丰 葑 豐 瘋 酆 鄷 渢 偑 凮 灃 蘴 冯 枫 沣 疯 砜 讽 风 僼 凨 凬 堸 寷 栤 檒 沨 煈
피 皮 彼 被 避 疲 披 跛 陂 辟 詖 鞁 屁 髲 柀 帔 骳 狓 鈹 佊 秛 㱟 诐 铍 鲏 䙓 怶 旇 氕 犤 紴 翍 耚
픽 腷 煏
필 必 筆 匹 畢 弼 泌 疋 苾 珌 馝 蹕 蓽 韠 篳 觱 佖 滭 駜 鵯 咇 罼 鞸 驆 弻 榓 㻶 熚 胇 袐 飶 䟆 哔
핍 乏 逼 偪 愊 姂 鴔
하 下 夏 河 何 賀 荷 瑕 遐 霞 蝦 厦 廈 鰕 昰 嚇 罅 呀 鍜 煆 岈 懗 瘕 嘏 縀 睱 谺 騢 鏬 哧 抲 菏 㙈
학 學 鶴 虐 壑 謔 瘧 确 涸 郝 狢 熇 鷽 皬 学 翯 觷 嗃 澩 矐 㕰 䳽 疟 谑 鸴 鹤 嗀 嚛 嚯 壆 峃 嶨 斈
한 韓 漢 寒 限 閑 恨 旱 汗 翰 邯 罕 悍 澣 閒 瀚 桿 捍 閈 暵 鼾 犴 僩 嫺 熯 嫻 駻 鷳 扞 狠 僴 覵 瞷
할 割 轄 蝎 黠 瞎 鶡 蠍 傄 劼 縖 舝 䫘 辖 乤 嗐 搳 硈 磍 螛 鎋 韔 鶷 㔛 㔠 㝬 㪴 㮫 㿣 䕣 䕸 䦖 䦪
함 咸 陷 含 函 艦 喊 涵 銜 緘 檻 鹹 啣 諴 菡 頷 嗛 闞 憨 莟 轞 䧟 淊 凾 醎 顑 圅 㴠 䓿 衘 谽 馠 䘖
합 合 陜 蛤 盒 閤 哈 闔 盍 溘 榼 郃 柙 匌 嗑 呷 詥 鴿 篕 㝓 峆 欱 烚 盇 鮯 䢔 陕 阖 颌 鸽 佮 峇 廅
항 行 恒 降 項 抗 巷 港 航 沆 亢 缸 肛 杭 伉 姮 桁 嫦 恆 頏 炕 夯 缿 骯 吭 閌 衖 佭 斻 闀 肮 钪 闶
해 海 害 解 亥 該 奚 偕 駭 骸 諧 楷 懈 咳 邂 孩 垓 瀣 蟹 醢 廨 薤 獬 瑎 欬 咍 嶰 痎 鮭 頦 觧 澥 晐
핵 核 劾 覈 翮 栶 势 䃒
행 行 幸 杏 倖 荇 悻 婞 涬 筕 㼬 绗 鸻 哘 啈 垳 堼 洐 烆 絎 緈 胻 莕 裄 鴴 鵆 﨨 㓑 䁄 䂔 䓷 䛭 䯒
향 向 鄕 香 享 響 饗 嚮 餉 珦 薌 鄊 晑 曏 郷 蠁 膷 鄉 銄 麘 䦳 乡 响 芗 飨 饷 亯 姠 楿 稥 萫 蚃 鱜
허 許 虛 墟 噓 詡 歔 虚 栩 虗 㠊 魖 嘘 浒 许 憈 鄦 驉 魼 㞰 䔓
헌 憲 獻 軒 櫶 掀 献 巚 幰 攇 巘 瀗 宪 轩 仚 佡 搟 㦥 䆭 䘆 䜢 䧮 䡣 昍
헐 歇 蝎 蠍 滊
험 險 驗 憸 嶮 玁 獫 硷 崄 猃 险 険 験 验 姭 忺 杴 榃 礆 譣 騐 㷿 㸝 㿌
혁 革 赫 爀 奕 嚇 洫 鬩 弈 焱 衋 虩 侐 焃 殈 赩 㷜 吓 阋 伵 捇 煂 盢 瞁 覤 赥 趘 㤸 㦦 㬨 㮝 㷦 䓇
현 見 現 賢 顯 玄 縣 懸 絃 弦 鉉 峴 炫 洵 眩 衒 絢 晛 俔 玹 泫 睍 舷 儇 嬛 昡 誢 琄 眴 繯 痃 筧 県
혈 血 穴 孑 頁 絜 趐 泬 蝢 緳 䆷 䦧 页 吷 坹 奊 娎 岤 桖 烕 疦 茓 裇 㐖 䆝 䋉 䐼 䒸 䕵 䙽 䛎 䦑 䩤
혐 嫌 鼸 馦 㾾 㺌 㽐 䵌
협 協 脅 狹 峽 陜 挾 俠 頰 夾 浹 脇 鋏 莢 叶 恊 愜 篋 悏 匧 埉 祫 峡 惬 䝱 筴 蛺 劦 冾 勰 脥 硤 陿
형 兄 形 刑 亨 螢 衡 炯 馨 邢 瀅 型 荊 熒 瑩 泂 珩 逈 烱 桁 滎 鎣 灐 迥 詗 夐 陘 娙 荆 鉶 硎 浻 蘅
혜 惠 慧 兮 彗 醯 鞋 蹊 蕙 暳 盻 徯 槥 傒 嘒 寭 謑 譿 恵 嵇 鼷 鞵 潓 嵆 橞 蟪 譓 豀 嚖 憓 㜎 䚷 䧥
호 好 戶 號 湖 乎 呼 虎 胡 護 毫 浩 豪 互 扈 鎬 皓 糊 昊 濠 祜 晧 澔 壕 狐 瑚 弧 琥 壺 槁 蒿 濩 芦
혹 或 惑 酷 鵠 豰 掝 鍙 閄 頶 嗀 㦯 㷤 㺉 㽇 䞱 熇
혼 混 婚 昏 魂 渾 煇 琿 溷 閽 睨 惛 焜 湣 圂 惽 睯 掍 鯶 鼲 䰟 挥 浑 珲 阍 馄 倱 堚 婫 忶 昬 棔 殙
홀 忽 笏 惚 囫 絗 曶 芴 㧾 䬍 锪 乥 匢 匫 唿 啒 寣 鍃 㖴 㧮 㨡 㳷 㺀 䁫 䓤 䝆 䨚 䩐 䴯
홍 紅 洪 弘 鴻 泓 訌 虹 哄 烘 汞 鬨 澒 晎 篊 鉷 洚 閧 葒 妅 唝 红 荭 讧 鸿 仜 叿 嗊 垬 娂 屸 渱 潂
화 火 花 化 話 和 畵 華 貨 禍 禾 靴 樺 嬅 譁 樗 畫 夥 擭 嘩 驊 俰 婲 龢 画 澕 槬 墷 鞾 咊 鏵 伙 楇
확 確 擴 穫 廓 濩 攫 碻 鑊 确 涸 擭 矍 礭 矡 䨥 镬 雘 矱 蠖 彍 戄 彉 攉 玃 臛 艧 靃 彠 扩 拡 鹱 劐
환 患 歡 還 換 丸 環 喚 煥 桓 幻 宦 鰥 驩 渙 紈 奐 晥 懽 圜 寰 豢 鬟 擐 轘 瓛 睆 鍰 絙 鐶 繯 垸 皖
활 活 闊 滑 猾 豁 佸 蛞 濶 䀨 敌 阔 奯 姡 眓 磆 秮 秳 萿 螖 趏 㓉 㕲 㵈 䄆 䄑 䦢 䱻 䴳
황 黃 皇 況 荒 滉 慌 徨 晃 惶 遑 煌 凰 潢 璜 蝗 榥 隍 篁 愰 簧 恍 幌 湟 晄 怳 貺 肓 喤 鎤 熀 瑝 媓
홰 罫 噦 翽 哕 噧 澅 翙
회 回 會 悔 懷 淮 恢 灰 廻 檜 膾 濊 晦 徊 誨 賄 繪 蛔 澮 匯 獪 茴 迴 燹 洄 詼 鱠 佪 繢 滙 闠 頮 沬
획 畵 獲 劃 硅 畫 擭 嚄 謢 撶 繣 㗲 获 婳 咟 嚿 嫿 湱 砉 窢 謋 讗 韄 騞 㓰 㖪 㦎 㩇 䐸 䦝 䪝 䬉 画
횡 橫 薨 宖 鐄 黌 鈜 澋 横 鋐 紭 竑 黉 吰 嚝 峵 彋 揈 撔 谹 輷 鑅 㢬 㶇 䍔 䎕 䫺 䬖 䬝
효 孝 效 曉 酵 爻 嚆 哮 梟 肴 淆 驍 斅 涍 囂 嘐 傚 殽 崤 熇 皛 虓 餚 効 暁 嘵 枵 鴞 歊 斆 憢 毊 嘋
후 後 厚 侯 后 候 喉 吼 朽 逅 嗅 煦 帿 珝 詬 涸 垕 詡 酗 猴 堠 喣 餱 篌 佝 譃 吽 糇 齅 姁 睺 矦 郈
훈 訓 薰 熏 勳 壎 暈 塤 勛 焄 燻 曛 纁 葷 獯 鑂 爋 勲 醺 坃 薫 矄 埙 勋 晕 荤 训 嚑 壦 瞓 臐 蔒 蘍
훌 欻 歘 烼 魆 㗵
훙 薨 顭
훤 喧 萱 暄 煊 諼 諠 烜 翧 晅 楦 藼 箮 䁔 咺 愋 蝖 貆 谖 吅 嚾 媗 昍 狟 睻 禤 萲 蕿 蘐 㓩 䚙 䚭 愃
훨 䎀
훼 毁 喙 卉 虫 虺 燬 芔 毀 毇 檓 譭 顪 餯 㑰 㩓 㷐 䂕 䃣 䛼
휘 揮 輝 徽 諱 麾 彙 暉 煇 褘 撝 翬 彚 椲 禈 䘗 幑 楎 汇 晖 讳 辉 㧑 媈 泋 瀈 灳 翚 鰴 㩣 㫎 㭏 㹆
휭 遤
휴 休 携 墮 烋 虧 畦 隳 亏 睢 鵂 咻 擕 髹 庥 鑴 貅 攜 巂 瓗 眭 茠 觿 雟 飍 鸺 倠 儶 婎 孈 烌 睳 蘳
휵 畜 慉 搐 槒 䛙
휼 恤 譎 鷸 卹 潏 霱 遹 鐍 䘏 獝 䎉 谲 鹬 憰 烅 瞲 肷 賉 㤜 㳚 䢕 䬄
흉 凶 胸 匈 兇 洶 胷 恟 汹 㐫 忷 訩 讻 哅 詾 㓙 㕳 㕼 䠗
흑 黑 黒 潶 釛 㱄
흔 痕 欣 昕 炘 釁 忻 訢 掀 焮 很 舋 盺 慁 俒 拫 鞎 锨 衅 䜣 俽 妡 庍 惞 煡 脪 邤 鍁 㥵 㯊 㾙
흘 汽 訖 吃 屹 紇 迄 汔 仡 疙 齕 忔 扢 虼 籺 麧 纥 讫 龁 肐 趷 釳 㐹 䇄 䏌 䢀 䬣
흠 欽 欠 歆 廞 揿 钦 噷 嬜 撳 鑫 㐸 䜗
흡 吸 洽 恰 扱 翕 潝 歙 噏 翖 熻 闟 㩉 㒆 㡊 㪧 㬛 㲸 㽏 䁯 䞩 䨐 䶋
흥 興 兴 嬹 臖 馫 㒷 䕟
희 希 喜 稀 戱 嬉 熙 噫 羲 禧 犧 姬 熹 憙 愾 僖 曦 凞 晞 憘 熺 囍 戲 嘻 餼 燹 欷 唏 暿 咥 悕 豨 爔
히 屎 忾 㕧 䐖 䦙
힐 詰 黠 頡 纈 犵 襭 肹 擷 肸 撷 缬 诘 颉 恄 欯 翓 㩪

28443
map/hanja.src Normal file

File diff suppressed because it is too large Load Diff

81
map/libhangul2hanja Executable file
View File

@@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Extract single-character Hanja readings from libhangul data."""
import sys
from pathlib import Path
def ishangul(s):
return len(s) == 1 and 0xAC00 <= ord(s) <= 0xD7A3
def ishanja(s):
if len(s) != 1:
return False
c = ord(s)
return (0x3400 <= c <= 0x4DBF
or 0x4E00 <= c <= 0x9FFF
or 0xF900 <= c <= 0xFAFF)
def extract(src, name):
comments = []
entries = []
seen = set()
leading = True
for lineno, raw in enumerate(src, 1):
line = raw.rstrip("\r\n")
if not line:
continue
if line.startswith("#"):
if leading:
comments.append(line.rstrip())
continue
leading = False
fields = line.split(":")
if len(fields) != 3:
raise ValueError(f"{name}:{lineno}: need key:value:comment")
reading, hanja, _ = fields
if not ishangul(reading) or not ishanja(hanja):
continue
pair = (hanja, reading)
if pair in seen:
raise ValueError(f"{name}:{lineno}: duplicate Hanja reading")
seen.add(pair)
entries.append(pair)
if not entries:
raise ValueError(f"{name}: no single-character Hanja readings")
return comments, entries
def main():
sys.stdin.reconfigure(encoding="utf-8")
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
if len(sys.argv) > 2:
print(f"usage: {sys.argv[0]} [libhangul-hanja.txt]", file=sys.stderr)
return 2
src = sys.stdin
name = "<stdin>"
try:
if len(sys.argv) == 2:
name = sys.argv[1]
src = Path(name).open(encoding="utf-8")
comments, entries = extract(src, name)
for line in comments:
print(line)
if comments:
print()
for hanja, reading in entries:
print(f"{hanja}\t{reading}")
except (OSError, UnicodeError, ValueError) as error:
print(error, file=sys.stderr)
return 1
finally:
if src is not sys.stdin:
src.close()
return 0
if __name__ == "__main__":
sys.exit(main())

80
map/mkhanja Executable file
View File

@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""Write hanja.dict from a one-Hanja-per-row UTF-8 source."""
import sys
from pathlib import Path
SOURCE = Path(__file__).with_name("hanja.src")
MAXCANDIDATES = 32
def ishangul(s):
return len(s) == 1 and 0xAC00 <= ord(s) <= 0xD7A3
def ishanja(s):
if len(s) != 1:
return False
c = ord(s)
return (0x3400 <= c <= 0x4DBF
or 0x4E00 <= c <= 0x9FFF
or 0xF900 <= c <= 0xFAFF)
def read(path):
comments = []
table = {}
seen = set()
leading = True
with path.open(encoding="utf-8") as src:
for lineno, raw in enumerate(src, 1):
line = raw.rstrip("\r\n")
if not line:
continue
if line.startswith("#"):
if leading:
comments.append(";;" + line[1:])
continue
leading = False
fields = line.split("\t")
if len(fields) != 2:
raise ValueError(f"{path}:{lineno}: need Hanja<TAB>reading")
hanja, reading = fields
if not ishanja(hanja):
raise ValueError(f"{path}:{lineno}: need one BMP Hanja character")
if not ishangul(reading):
raise ValueError(f"{path}:{lineno}: need one Hangul syllable")
pair = (hanja, reading)
if pair in seen:
raise ValueError(f"{path}:{lineno}: duplicate Hanja reading")
seen.add(pair)
table.setdefault(reading, []).append(hanja)
if not seen:
raise ValueError(f"{path}: no Hanja readings")
return comments, table
def main():
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
if len(sys.argv) > 2:
print(f"usage: {sys.argv[0]} [hanja.src]", file=sys.stderr)
return 2
path = Path(sys.argv[1]) if len(sys.argv) == 2 else SOURCE
try:
comments, table = read(path)
for line in comments:
print(line)
if comments:
print()
for reading, candidates in table.items():
print(f"{reading}\t{' '.join(candidates[:MAXCANDIDATES])}")
except (OSError, UnicodeError, ValueError) as error:
print(error, file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())

104
strans.c
View File

@@ -16,7 +16,7 @@ static int maplookup(Trie*, Str*, Str*);
typedef struct Search Search;
struct Search
{
int on;
int lang;
Str raw;
Str text;
};
@@ -40,6 +40,7 @@ Lang langs[] = {
{LangJP, "hira", "kanji", transmap, backjp, dictqjp, nil, nil},
{LangJPK, "kata", nil, transmap, backjp, dictqjp, nil, nil},
{LangKO, nil, nil, transko, backko, nil, nil, nil},
{LangHANJA, nil, "hanja", nil, nil, nil, nil, nil},
{LangEMOJI, nil, "emoji", nil, nil, nil, nil, nil},
{LangVI, "telex", nil, transvi, backvi, dictqmap, nil, nil},
};
@@ -115,12 +116,12 @@ show(void)
int i, first, n;
sclear(&dc.pre);
if(search.on)
if(search.lang)
pre = search.text;
else
impre(&pre);
if(popup){
if(search.on || isjp(&im) || im.l->map == nil ||
if(search.lang || isjp(&im) || im.l->map == nil ||
!mapget(im.l->map, &pre, &dc.pre))
dc.pre = pre;
}
@@ -146,7 +147,7 @@ reset(void)
{
sclear(&im.pre);
sclear(&im.raw);
search.on = 0;
search.lang = 0;
sclear(&search.raw);
sclear(&search.text);
memset(&caret, 0, sizeof caret);
@@ -460,13 +461,13 @@ addkouho(Str *s)
}
static void
emojilookup(Str *key, Dictres *res)
searchlookup(int lang, Str *key, Dictres *res)
{
Dictreq req;
req.key = *key;
req.pre = req.key;
req.lang = LangEMOJI;
req.lang = lang;
dictlookup(&req, res);
}
@@ -482,13 +483,13 @@ emojiquery(void)
transstr(im.l, &search.raw, &local);
foldascii(&local);
clearkouho();
emojilookup(&raw, &res);
searchlookup(LangEMOJI, &raw, &res);
rawhit = res.nkouho != 0;
for(i = 0; i < res.nkouho; i++)
addkouho(&res.kouho[i]);
localhit = 0;
if(scmp(&raw, &local) != 0){
emojilookup(&local, &res);
searchlookup(LangEMOJI, &local, &res);
localhit = res.nkouho != 0;
for(i = 0; i < res.nkouho; i++)
addkouho(&res.kouho[i]);
@@ -497,10 +498,45 @@ emojiquery(void)
show();
}
static void
hanjaquery(void)
{
static Dictres res;
Str key;
transstr(im.l, &search.raw, &key);
search.text = key;
if(key.n == 1 && key.r[0] >= 0xac00 && key.r[0] <= 0xd7a3){
searchlookup(LangHANJA, &key, &res);
setkouho(&res);
}else
clearkouho();
show();
}
static void
searchquery(void)
{
if(search.lang == LangEMOJI)
emojiquery();
else if(search.lang == LangHANJA)
hanjaquery();
}
static int
searchlang(Rune c, u32int mod)
{
if(mod & (Malt|Msuper))
return 0;
if(c == LangEMOJI || c == LangHANJA)
return c;
return 0;
}
static void
endsearch(void)
{
search.on = 0;
search.lang = 0;
sclear(&search.raw);
sclear(&search.text);
clearkouho();
@@ -508,14 +544,14 @@ endsearch(void)
}
static void
startsearch(Str *com)
startsearch(int lang, Str *com)
{
if(haspre(&im))
commit(com);
sclear(&im.pre);
sclear(&im.raw);
clearkouho();
search.on = 1;
search.lang = lang;
sclear(&search.raw);
sclear(&search.text);
show();
@@ -529,7 +565,7 @@ commitsearch(Str *com)
}
static int
pickemoji(int n, Str *com)
picksearch(int n, Str *com)
{
if(n < 0 || n >= im.nkouho)
return 0;
@@ -559,7 +595,7 @@ searchkey(u32int ks, u32int mod, Str *com)
n = ks - '1';
off = im.sel >= Maxdisp ? im.sel - Maxdisp + 1 : 0;
if(n >= 0 && n < Maxdisp && off + n < im.nkouho && mod == 0){
pickemoji(off + n, com);
picksearch(off + n, com);
return 1;
}
if(ks == Ktab){
@@ -579,25 +615,36 @@ searchkey(u32int ks, u32int mod, Str *com)
}
if(ks == Kret){
if(im.nkouho > 0)
return pickemoji(im.sel >= 0 ? im.sel : 0, com);
return picksearch(im.sel >= 0 ? im.sel : 0, com);
commitsearch(com);
return 1;
}
if(ks == Kback){
if(search.raw.n == 0)
return 1;
if(search.raw.n == 0){
endsearch();
return 0;
}
spopr(&search.raw);
emojiquery();
searchquery();
return 1;
}
if(ks == Kesc){
endsearch();
return 1;
}
if(ks >= Kspec || (ks < ' ' && !(mod & Mctrl)) ||
(mod & (Malt|Msuper))){
commitsearch(com);
return 0;
}
if(mod & Mctrl){
c = ctrlkey(ks);
if(c == LangEMOJI){
endsearch();
n = searchlang(c, mod);
if(n != 0){
if(n == search.lang)
endsearch();
else
startsearch(n, com);
return 1;
}
if(c == 0x10){
@@ -610,16 +657,14 @@ searchkey(u32int ks, u32int mod, Str *com)
return 1;
return 0;
}
if(ks >= Kspec || ks < ' ' || (mod & (Malt|Msuper))){
commitsearch(com);
return 0;
}
if(search.raw.n >= Maxrunes){
commitsearch(com);
return 0;
}
if(im.l->lang == LangKO)
ks = kokey(ks, mod);
sputr(&search.raw, ks);
emojiquery();
searchquery();
return 1;
}
@@ -631,7 +676,7 @@ keystroke(u32int ks, u32int mod, Str *com)
if(ismodkey(ks))
return 0;
if(search.on)
if(search.lang)
return searchkey(ks, mod, com);
if(ks == Kdown || ks == Kup){
if(im.nkouho == 0)
@@ -690,8 +735,9 @@ keystroke(u32int ks, u32int mod, Str *com)
}
if(mod & Mctrl){
c = ctrlkey(ks);
if(c == LangEMOJI){
startsearch(com);
n = searchlang(c, mod);
if(n != 0){
startsearch(n, com);
return 1;
}
if(c == 0x10){
@@ -795,7 +841,7 @@ imhandlekey(Keyreq *kr)
break;
}
if(kr->want && kr->owner == activeowner){
if(search.on)
if(search.lang)
res.preedit = search.text;
else
impre(&res.preedit);
@@ -809,7 +855,7 @@ dictresult(Dictres *res)
Str pre;
impre(&pre);
if(search.on || res->lang != im.l->lang ||
if(search.lang || res->lang != im.l->lang ||
scmp(&res->key, &pre) != 0)
return;
setkouho(res);

View File

@@ -421,15 +421,17 @@ engine_direct_language_modes(struct ct *t)
CT_EQ_INT(t, 0, im.pre.n);
CT_EQ_INT(t, 0, im.raw.n);
CT_CHECK(t, keystroke('e', Mctrl, &com));
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_EQ_INT(t, LangEN, im.l->lang);
CT_CHECK(t, keystroke(Kesc, 0, &com));
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_CHECK(t, keystroke('s', Mctrl, &com));
CT_EQ_INT(t, LangKO, im.l->lang);
CT_EQ_PTR(t, nil, im.l->mapname);
CT_EQ_PTR(t, nil, im.l->map);
CT_EQ_PTR(t, nil, im.l->dictname);
CT_EQ_PTR(t, nil, im.l->dictq);
CT_CHECK(t, strcmp(getlang(LangHANJA)->dictname, "hanja") == 0);
CT_CHECK(t, keystroke('r', 0, &com));
checkstr(t, "Korean without map", "", &im.pre);
CT_CHECK(t, keystroke(Kback, 0, &com));
@@ -509,11 +511,12 @@ engine_language_switch_state(struct ct *t)
vi->map = saved;
}
typedef struct Emojifix Emojifix;
struct Emojifix
typedef struct Searchfix Searchfix;
struct Searchfix
{
Im im;
Search search;
Lang *dictlang;
Hmap *dict;
int popup;
int visible;
@@ -535,7 +538,7 @@ draindraw(Drawcmd *last)
}
static void
setemoji(Hmap **dict, char *key, char *val)
setdict(Hmap **dict, char *key, char *val)
{
Str s;
@@ -544,33 +547,37 @@ setemoji(Hmap **dict, char *key, char *val)
}
static void
emojibegin(Emojifix *f, int showpre)
searchsave(Searchfix *f, int lang)
{
Lang *l;
l = getlang(LangEMOJI);
f->im = im;
f->search = search;
f->dict = l->dict;
f->dictlang = getlang(lang);
f->dict = f->dictlang->dict;
f->popup = popup;
f->visible = visible;
draindraw(nil);
l->dict = hmapalloc(32);
setemoji(&l->dict, "a", "A B");
setemoji(&l->dict, "", "B C");
setemoji(&l->dict, "alpha", "α");
setemoji(&l->dict, "smil", "😀 😄");
setemoji(&l->dict, "smile", "😀 😄");
setemoji(&l->dict, "웃음", "😀 😄 😂");
setemoji(&l->dict, "えがお", "😀 😄 😊");
setemoji(&l->dict, "エガオ", "😀 😄 😊");
setemoji(&l->dict, "heart", "❤️");
setemoji(&l->dict, "coffee", "☕️");
setemoji(&l->dict, "^", "¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁽");
setemoji(&l->dict, "^0", "");
setemoji(&l->dict, "_", "₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₍");
setemoji(&l->dict, "<", "← ≤ ♥ ≠");
setemoji(&l->dict, "many",
}
static void
emojibegin(Searchfix *f, int showpre)
{
searchsave(f, LangEMOJI);
f->dictlang->dict = hmapalloc(32);
setdict(&f->dictlang->dict, "a", "A B");
setdict(&f->dictlang->dict, "", "B C");
setdict(&f->dictlang->dict, "alpha", "α");
setdict(&f->dictlang->dict, "smil", "😀 😄");
setdict(&f->dictlang->dict, "smile", "😀 😄");
setdict(&f->dictlang->dict, "웃음", "😀 😄 😂");
setdict(&f->dictlang->dict, "えがお", "😀 😄 😊");
setdict(&f->dictlang->dict, "エガオ", "😀 😄 😊");
setdict(&f->dictlang->dict, "heart", "❤️");
setdict(&f->dictlang->dict, "coffee", "☕️");
setdict(&f->dictlang->dict, "^", "¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁽");
setdict(&f->dictlang->dict, "^0", "");
setdict(&f->dictlang->dict, "_", "₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₍");
setdict(&f->dictlang->dict, "<", "← ≤ ♥ ≠");
setdict(&f->dictlang->dict, "many",
"c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12");
init();
im.l = getlang(LangKO);
@@ -578,14 +585,12 @@ emojibegin(Emojifix *f, int showpre)
}
static void
emojiend(Emojifix *f)
searchend(Searchfix *f)
{
Lang *l;
Hmap *dict;
l = getlang(LangEMOJI);
dict = l->dict;
l->dict = f->dict;
dict = f->dictlang->dict;
f->dictlang->dict = f->dict;
hmapfree(dict);
draindraw(nil);
im = f->im;
@@ -594,6 +599,20 @@ emojiend(Emojifix *f)
visible = f->visible;
}
static void
hanjabegin(Searchfix *f, int lang)
{
searchsave(f, LangHANJA);
f->dictlang->dict = hmapalloc(8);
setdict(&f->dictlang->dict, "", "漢 韓");
setdict(&f->dictlang->dict, "", "");
setdict(&f->dictlang->dict, "", "");
setdict(&f->dictlang->dict, "한글", "");
setdict(&f->dictlang->dict, "", "");
init();
im.l = getlang(lang);
}
static int
typekeys(struct ct *t, char *keys, Str *com)
{
@@ -771,7 +790,7 @@ void
engine_emoji_single_candidate(struct ct *t)
{
Drawcmd dc = {0};
Emojifix f;
Searchfix f;
Str com;
emojibegin(&f, 1);
@@ -779,12 +798,12 @@ engine_emoji_single_candidate(struct ct *t)
CT_CHECK(t, keystroke('p', Mctrl, &com));
CT_EQ_INT(t, 0, popup);
CT_CHECK(t, keystroke('e', Mctrl, &com));
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
if(typekeys(t, "alpha", &com)){
checkstr(t, "no automatic commit", "", &com);
checkstr(t, "raw English query", "alpha", &search.text);
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_EQ_INT(t, 1, im.nkouho);
checkstr(t, "single candidate", "α", &im.kouho[0]);
CT_CHECK(t, draindraw(&dc) > 0);
@@ -792,21 +811,21 @@ engine_emoji_single_candidate(struct ct *t)
CT_EQ_INT(t, 1, dc.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "explicit candidate commit", "α", &com);
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
show();
CT_CHECK(t, draindraw(&dc) > 0);
CT_EQ_INT(t, 0, dc.pre.n);
CT_EQ_INT(t, 0, dc.nkouho);
}
emojiend(&f);
searchend(&f);
}
void
engine_emoji_queries(struct ct *t)
{
Drawcmd dc = {0};
Emojifix f;
Searchfix f;
Str com;
emojibegin(&f, 1);
@@ -854,16 +873,16 @@ engine_emoji_queries(struct ct *t)
CT_EQ_INT(t, 3, dc.nkouho);
CT_CHECK(t, keystroke(Kesc, 0, &com));
checkstr(t, "cancel commit", "", &com);
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
}
emojiend(&f);
searchend(&f);
}
void
engine_emoji_japanese_and_multirune(struct ct *t)
{
Emojifix f;
Searchfix f;
Str com;
emojibegin(&f, 0);
@@ -904,7 +923,7 @@ engine_emoji_japanese_and_multirune(struct ct *t)
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "multi-codepoint emoji", "☕️", &com);
}
emojiend(&f);
searchend(&f);
}
void
@@ -920,7 +939,7 @@ engine_emoji_digit_aliases(struct ct *t)
{ "_2", '_', '2', "" },
{ "<3", '<', '3', "" },
};
Emojifix f;
Searchfix f;
Str com;
int i;
@@ -932,7 +951,7 @@ engine_emoji_digit_aliases(struct ct *t)
CT_CHECK(t, im.nkouho >= cases[i].digit - '0');
CT_CHECK(t, keystroke(cases[i].digit, 0, &com));
checkstr(t, cases[i].name, cases[i].want, &com);
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
}
@@ -952,19 +971,19 @@ engine_emoji_digit_aliases(struct ct *t)
CT_CHECK(t, keystroke('9', 0, &com));
checkstr(t, "missing number query", "smile9", &search.text);
checkstr(t, "missing number commit", "", &com);
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_EQ_INT(t, 0, im.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "missing number text", "smile9", &com);
}
emojiend(&f);
searchend(&f);
}
void
engine_emoji_navigation(struct ct *t)
{
Drawcmd dc = {0};
Emojifix f;
Searchfix f;
Str com;
int i;
@@ -1008,13 +1027,13 @@ engine_emoji_navigation(struct ct *t)
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "navigated candidate", "😄", &com);
}
emojiend(&f);
searchend(&f);
}
void
engine_emoji_preedit_languages(struct ct *t)
{
Emojifix f;
Searchfix f;
Str com, shown;
int p;
@@ -1028,19 +1047,26 @@ engine_emoji_preedit_languages(struct ct *t)
checkstr(t, "modifier preserves Japanese", "", &shown);
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
checkstr(t, "committed Japanese preedit", "", &com);
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_EQ_INT(t, LangJP, im.l->lang);
CT_CHECK(t, !keystroke('E', Mctrl|Malt, &com));
CT_EQ_INT(t, 0, search.lang);
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
CT_CHECK(t, !keystroke('E', Mctrl|Msuper, &com));
CT_EQ_INT(t, 0, search.lang);
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
CT_EQ_INT(t, LangJP, im.l->lang);
CT_CHECK(t, keystroke('a', 0, &com));
p = popup;
CT_CHECK(t, !keystroke(Kmodfirst+2, 0, &com));
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
checkstr(t, "modifier preserves search", "a", &search.text);
CT_CHECK(t, keystroke('P', Mctrl|Mshift, &com));
CT_EQ_INT(t, !p, popup);
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_CHECK(t, !keystroke(Kmodfirst+2, 0, &com));
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
sclear(&com);
if(typekeys(t, "na", &com)){
shown = shownpre(&im);
@@ -1070,7 +1096,7 @@ engine_emoji_preedit_languages(struct ct *t)
CT_CHECK(t, keystroke('e', Mctrl, &com));
checkstr(t, "committed Telex preedit", "á", &com);
CT_CHECK(t, keystroke(Kesc, 0, &com));
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_EQ_PTR(t, &testvi, im.l);
sclear(&com);
if(typekeys(t, "as", &com)){
@@ -1079,13 +1105,13 @@ engine_emoji_preedit_languages(struct ct *t)
checkstr(t, "Telex raw resumed", "as", &im.raw);
}
}
emojiend(&f);
searchend(&f);
}
void
engine_emoji_start_and_unknown(struct ct *t)
{
Emojifix f;
Searchfix f;
Str com;
char want[Maxrunes+1];
int i;
@@ -1095,14 +1121,14 @@ engine_emoji_start_and_unknown(struct ct *t)
if(typekeys(t, "dkssud", &com)){
CT_CHECK(t, keystroke('e', Mctrl, &com));
checkstr(t, "committed Korean preedit", "안녕", &com);
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
if(typekeys(t, "xyz", &com)){
checkstr(t, "unknown displayed query", "xyz", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "unknown query commit", "안녕xyz", &com);
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
}
}
@@ -1112,7 +1138,7 @@ engine_emoji_start_and_unknown(struct ct *t)
if(typekeys(t, "xyz", &com)){
CT_CHECK(t, !keystroke(Kspec|0x51, 0, &com));
checkstr(t, "special commits shown query", "xyz", &com);
CT_CHECK(t, !search.on);
CT_CHECK(t, !search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
}
@@ -1121,20 +1147,20 @@ engine_emoji_start_and_unknown(struct ct *t)
for(i = 0; i < Maxrunes; i++)
CT_CHECK(t, keystroke('q', 0, &com));
CT_EQ_INT(t, Maxrunes, search.raw.n);
CT_CHECK(t, search.on);
CT_CHECK(t, search.lang);
CT_CHECK(t, !keystroke('z', 0, &com));
memset(want, 'q', Maxrunes);
want[Maxrunes] = '\0';
checkstr(t, "bounded query commit", want, &com);
CT_CHECK(t, !search.on);
emojiend(&f);
CT_CHECK(t, !search.lang);
searchend(&f);
}
void
engine_emoji_dictionary_identity(struct ct *t)
{
Dictres res;
Emojifix f;
Searchfix f;
emojibegin(&f, 0);
im.pre = mkstr("same");
@@ -1157,18 +1183,224 @@ engine_emoji_dictionary_identity(struct ct *t)
checkstr(t, "wrong preedit ignored", "old", &im.kouho[0]);
res.key = im.pre;
search.on = 1;
search.lang = LangEMOJI;
dictresult(&res);
CT_EQ_INT(t, 1, im.nkouho);
checkstr(t, "search response ignored", "old", &im.kouho[0]);
search.on = 0;
search.lang = 0;
res.kouho[0] = mkstr("right");
dictresult(&res);
CT_EQ_INT(t, 1, im.nkouho);
CT_EQ_INT(t, -1, im.sel);
checkstr(t, "matching response accepted", "right", &im.kouho[0]);
emojiend(&f);
searchend(&f);
}
void
engine_hanja_search(struct ct *t)
{
Searchfix f;
Str com;
hanjabegin(&f, LangKO);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
CT_EQ_INT(t, LangHANJA, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
if(!typekeys(t, "gks", &com))
goto cleanup;
checkstr(t, "Hanja reading", "", &search.text);
CT_EQ_INT(t, 2, im.nkouho);
CT_CHECK(t, keystroke(Kdown, 0, &com));
CT_CHECK(t, keystroke(Kdown, 0, &com));
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "navigated Hanja", "", &com);
CT_EQ_INT(t, 0, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
cleanup:
searchend(&f);
}
void
engine_hanja_unknown_and_cancel(struct ct *t)
{
Searchfix f;
Str com;
hanjabegin(&f, LangKO);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
if(!typekeys(t, "rmf", &com))
goto cleanup;
checkstr(t, "unknown Hanja reading", "", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "unknown Hanja commit", "", &com);
CT_EQ_INT(t, 0, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
if(!typekeys(t, "r", &com))
goto cleanup;
checkstr(t, "incomplete Hanja reading", "", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "incomplete Hanja commit", "", &com);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
if(!typekeys(t, "gksrmf", &com))
goto cleanup;
checkstr(t, "multiple Hanja syllables", "한글", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "multiple Hanja syllable commit", "한글", &com);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
if(!typekeys(t, "gks", &com))
goto cleanup;
CT_EQ_INT(t, 2, im.nkouho);
CT_CHECK(t, keystroke(Kesc, 0, &com));
checkstr(t, "cancelled Hanja", "", &com);
CT_EQ_INT(t, 0, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
sclear(&com);
CT_CHECK(t, keystroke('h', Mctrl, &com));
CT_EQ_INT(t, LangHANJA, search.lang);
CT_CHECK(t, keystroke('h', Mctrl, &com));
CT_EQ_INT(t, 0, search.lang);
cleanup:
searchend(&f);
}
void
engine_hanja_korean_keys(struct ct *t)
{
Searchfix f;
Str com;
hanjabegin(&f, LangKO);
sclear(&com);
CT_CHECK(t, keystroke('h', Mctrl, &com));
CT_CHECK(t, keystroke('r', Mshift, &com));
CT_CHECK(t, keystroke('k', 0, &com));
checkstr(t, "shifted Hanja reading", "", &search.text);
CT_CHECK(t, keystroke(Kesc, 0, &com));
CT_CHECK(t, keystroke('h', Mctrl, &com));
CT_CHECK(t, keystroke('R', 0, &com));
CT_CHECK(t, keystroke('k', 0, &com));
checkstr(t, "Caps Lock Hanja reading", "", &search.text);
CT_EQ_INT(t, 1, im.nkouho);
CT_CHECK(t, keystroke(Kesc, 0, &com));
searchend(&f);
}
void
engine_hanja_backspace(struct ct *t)
{
Searchfix f;
Str com;
hanjabegin(&f, LangKO);
sclear(&com);
CT_CHECK(t, keystroke('h', Mctrl, &com));
if(!typekeys(t, "gks", &com))
goto cleanup;
checkstr(t, "Hanja before backspace", "", &search.text);
CT_EQ_INT(t, 2, im.nkouho);
CT_CHECK(t, keystroke(Kback, 0, &com));
checkstr(t, "Hanja final backspace", "", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_CHECK(t, keystroke(Kback, 0, &com));
checkstr(t, "Hanja vowel backspace", "", &search.text);
CT_CHECK(t, keystroke(Kback, 0, &com));
checkstr(t, "empty Hanja search", "", &search.text);
CT_EQ_INT(t, LangHANJA, search.lang);
CT_CHECK(t, !keystroke(Kback, 0, &com));
CT_EQ_INT(t, 0, search.lang);
if(!typekeys(t, "gks", &com))
goto cleanup;
CT_CHECK(t, keystroke('h', Mctrl, &com));
checkstr(t, "preedit committed before Hanja", "", &com);
CT_EQ_INT(t, LangHANJA, search.lang);
CT_CHECK(t, !keystroke(Kback, 0, &com));
CT_EQ_INT(t, 0, search.lang);
CT_EQ_INT(t, LangKO, im.l->lang);
cleanup:
searchend(&f);
}
void
engine_hanja_input_languages(struct ct *t)
{
Searchfix f;
Str com;
hanjabegin(&f, LangEN);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
if(!typekeys(t, "gks", &com))
goto cleanup;
checkstr(t, "English Hanja input", "gks", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_EQ_INT(t, LangEN, im.l->lang);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "English Hanja commit", "gks", &com);
CT_EQ_INT(t, LangEN, im.l->lang);
init();
im.l = getlang(LangJP);
sclear(&com);
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
goto cleanup;
if(!typekeys(t, "ka", &com))
goto cleanup;
checkstr(t, "Japanese Hanja input", "", &search.text);
CT_EQ_INT(t, 0, im.nkouho);
CT_EQ_INT(t, LangJP, im.l->lang);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "Japanese Hanja commit", "", &com);
CT_EQ_INT(t, LangJP, im.l->lang);
init();
im.l = getlang(LangEN);
sclear(&com);
CT_CHECK(t, keystroke('h', Mctrl, &com));
CT_CHECK(t, keystroke(L'', 0, &com));
checkstr(t, "direct Hanja input", "", &search.text);
CT_EQ_INT(t, 2, im.nkouho);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "direct Hanja selection", "", &com);
CT_EQ_INT(t, LangEN, im.l->lang);
init();
im.l = getlang(LangJP);
sclear(&com);
CT_CHECK(t, keystroke('h', Mctrl, &com));
if(!typekeys(t, "ka", &com))
goto cleanup;
CT_CHECK(t, !keystroke('e', Mctrl|Malt, &com));
checkstr(t, "modified search boundary", "", &com);
CT_EQ_INT(t, 0, search.lang);
CT_EQ_INT(t, LangJP, im.l->lang);
sclear(&com);
CT_CHECK(t, !keystroke('h', Mctrl|Msuper, &com));
CT_EQ_INT(t, 0, search.lang);
CT_EQ_INT(t, LangJP, im.l->lang);
cleanup:
searchend(&f);
}
static u32int
@@ -1192,7 +1424,7 @@ engine_randomized_stress(struct ct *t)
'u', 'w', 'y', '1', '2', '9', '\'', ' ', L'',
};
static Rune modes[] = { 't', 'n', 'k', 's', 'v' };
Emojifix f;
Searchfix f;
Lang *vi;
Trie *vimap;
Keyres res;
@@ -1280,7 +1512,7 @@ engine_randomized_stress(struct ct *t)
break;
}
}
emojiend(&f);
searchend(&f);
vi->map = vimap;
}

138
tests/mkhanja_test.py Normal file
View File

@@ -0,0 +1,138 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
IMPORT = ROOT / "map" / "libhangul2hanja"
GENERATE = ROOT / "map" / "mkhanja"
def run(program, source=None, stdin=None, hostile=False):
command = [sys.executable, "-B", str(program)]
if source is not None:
command.append(str(source))
env = None
if hostile:
env = os.environ.copy()
env.update(LC_ALL="C", LANG="C", PYTHONCOERCECLOCALE="0", PYTHONUTF8="0")
env.pop("PYTHONIOENCODING", None)
return subprocess.run(
command,
input=stdin,
capture_output=True,
encoding="utf-8",
env=env,
check=False,
)
class MkhanjaTest(unittest.TestCase):
def source(self, text):
tmp = tempfile.TemporaryDirectory()
path = Path(tmp.name) / "hanja.txt"
path.write_text(text, encoding="utf-8")
self.addCleanup(tmp.cleanup)
return path
def test_imports_single_bmp_hanja_rows(self):
result = run(
IMPORT,
self.source(
"# Copyright holder\n"
"# BSD license\n"
"한:漢:first\n"
"가:㐀:extension A\n"
"김:金:compatibility\n"
"방학:放:word reading\n"
"학:學校:word value\n"
"한:𠀀:astral\n"
"ㄱ:加:jamo\n"
),
)
self.assertEqual(result.returncode, 0, result.stderr)
lines = result.stdout.splitlines()
self.assertEqual(lines[:2], ["# Copyright holder", "# BSD license"])
self.assertEqual(lines[2:], ["", "\t", "\t", "\t"])
def test_import_rejects_malformed_and_duplicate_rows(self):
bad = [
"한 漢\n",
"한:漢:first\n한:漢:again\n",
]
for text in bad:
with self.subTest(text=repr(text)):
self.assertEqual(run(IMPORT, self.source(text)).returncode, 1)
def test_import_uses_utf8_without_locale(self):
text = "# 저작권\n한:漢:first\n"
expected = "# 저작권\n\n\t\n"
for source, stdin in ((self.source(text), None), (None, text)):
with self.subTest(source=source):
result = run(IMPORT, source, stdin, hostile=True)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout, expected)
def test_groups_readings_and_preserves_order(self):
result = run(
GENERATE,
self.source(
"# Copyright holder\n"
"# BSD license\n"
"\t\n"
"\t\n"
"\t\n"
"\t\n"
"\t\n"
),
)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(
result.stdout.splitlines(),
[
";; Copyright holder",
";; BSD license",
"",
"\t漢 韓",
"\t㐀 家",
"\t",
],
)
def test_generator_rejects_bad_rows(self):
bad = [
"漢韓\t\n",
"\t한자\n",
"𠀀\t\n",
"\t\n\t\n",
"漢 한\n",
]
for text in bad:
with self.subTest(text=repr(text)):
self.assertEqual(run(GENERATE, self.source(text)).returncode, 1)
def test_generator_uses_utf8_without_locale(self):
result = run(GENERATE, self.source("# 저작권\n\t\n"), hostile=True)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout, ";; 저작권\n\n\t\n")
result = run(GENERATE, hostile=True)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("\t", result.stdout)
def test_generator_keeps_runtime_candidate_limit(self):
rows = "".join(f"{chr(0x4E00 + n)}\t\n" for n in range(33))
result = run(GENERATE, self.source(rows))
self.assertEqual(result.returncode, 0, result.stderr)
candidates = result.stdout.rstrip().split("\t", 1)[1].split()
self.assertEqual(len(candidates), 32)
self.assertEqual(candidates[-1], chr(0x4E00 + 31))
if __name__ == "__main__":
unittest.main()

View File

@@ -54,6 +54,11 @@ void engine_emoji_navigation(struct ct*);
void engine_emoji_preedit_languages(struct ct*);
void engine_emoji_start_and_unknown(struct ct*);
void engine_emoji_dictionary_identity(struct ct*);
void engine_hanja_search(struct ct*);
void engine_hanja_unknown_and_cancel(struct ct*);
void engine_hanja_korean_keys(struct ct*);
void engine_hanja_backspace(struct ct*);
void engine_hanja_input_languages(struct ct*);
void engine_randomized_stress(struct ct*);
void engine_full_boundary_passthrough(struct ct*);
void dictionary_candidates(struct ct*);

View File

@@ -108,6 +108,11 @@ static const struct ct_test tests[] = {
{ "engine/emoji-preedit-languages", engine_emoji_preedit_languages },
{ "engine/emoji-start-and-unknown", engine_emoji_start_and_unknown },
{ "engine/emoji-dictionary-identity", engine_emoji_dictionary_identity },
{ "engine/hanja-search", engine_hanja_search },
{ "engine/hanja-unknown-cancel", engine_hanja_unknown_and_cancel },
{ "engine/hanja-korean-keys", engine_hanja_korean_keys },
{ "engine/hanja-backspace", engine_hanja_backspace },
{ "engine/hanja-input-languages", engine_hanja_input_languages },
{ "engine/randomized-stress", engine_randomized_stress },
{ "engine/full-boundary-passthrough", engine_full_boundary_passthrough },
{ "dict/candidates", dictionary_candidates },