JacobLinCool commited on
Commit
6cc3500
·
verified ·
1 Parent(s): bbaebec

Twinity-1: weights, compiled dictionary, inference code

Browse files
README.md ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ language:
4
+ - zh
5
+ tags:
6
+ - chinese
7
+ - traditional-chinese
8
+ - taiwan
9
+ - text-normalization
10
+ - zh-tw
11
+ - opencc
12
+ library_name: twlat
13
+ pipeline_tag: text2text-generation
14
+ ---
15
+
16
+ # Twinity-1
17
+
18
+ **中國大陸中文 → 臺灣正體中文的確定性轉換器。8.86M 參數,CPU 單執行緒 11,300 字/秒。**
19
+
20
+ Twinity-1 不生成文字。字典編譯成 conversion lattice,界定「哪些位置可以改、可以改成什麼」;
21
+ 模型只在每個歧義位點裁決「這個語境該不該改」;Viterbi 選出全域一致的編輯集合,
22
+ 最後對原文做**最小 splice**——編輯範圍以外的每一個位元組原樣保留。
23
+
24
+ 因此它結構上**不可能**改寫語句、增刪內容、或破壞外語片段與程式碼。
25
+
26
+ ```python
27
+ import twlat
28
+ twlat.convert("这个程序有bug,请在服务器上重新部署。")
29
+ # '這個程式有 bug,請在伺服器上重新部署。'
30
+ ```
31
+
32
+ ## 為什麼不用查表或 LLM
33
+
34
+ | | 查表(OpenCC) | LLM 改寫 | **Twinity-1** |
35
+ | --- | --- | --- | --- |
36
+ | 語境判斷 | ✗ 無 | ✓ | ✓ |
37
+ | 確定性 | ✓ | ✗ | ✓ 100% |
38
+ | 只改該改的 | ✓ | ✗ 會潤飾/增刪 | ✓ 最小 splice |
39
+ | 外語/程式碼保留 | ✓ | ✗ | ✓ 1,248/1,248 |
40
+ | 成本 | $0 | API | $0 |
41
+ | 延遲(p95) | <1 ms | 秒級 | 23 ms |
42
+
43
+ 「程序」在軟體語境是**程式**、在法律語境就是**程序**;「里」在「那里」該轉**裡**、
44
+ 在「公里」不能動。查表沒有語境;LLM 有語境但不確定且會多改。
45
+
46
+ ## 評測
47
+
48
+ TWBench-Neutral(1,496 題/8,438 個歧義位點,gold = 臺灣正體語料原文,
49
+ 不由任何系統產生;gold 自身誤差經分層盲審量測並逐條修正):
50
+
51
+ | 系統 | site accuracy | 維持 | 改動 |
52
+ | --- | --- | --- | --- |
53
+ | OpenCC | 0.9176 | 0.9411 | 0.8604 |
54
+ | zhtw-mcp(規則層) | 0.9263 | 0.9510 | 0.8661 |
55
+ | 前代 V1(6.06M) | 0.9456 | 0.9694 | 0.8877 |
56
+ | 前代 V2(3.32M) | 0.9445 | 0.9565 | 0.9153 |
57
+ | **Twinity-1(8.86M)** | **0.9712** | **0.9941** | **0.9153** |
58
+
59
+ 對前代顯著勝出(+2.7pp/+2.6pp,paired bootstrap p < 0.001)。
60
+ 與 frontier LLM 基線在 320 題子集上**無顯著差異**(0.9782 vs 0.9709,p = 0.34)——
61
+ 本模型不主張比 LLM 更準,而是在同等準確度下提供確定性、零成本與 23 ms 延遲。
62
+
63
+ 盲測排序(103 題、14 位獨立評審、匿名、正反序雙輪):Twinity-1 平均名次 **1.296**,
64
+ 優於 V2(1.612)與 V1(2.199)。
65
+
66
+ ## 怎麼訓練的
67
+
68
+ **Confusion-set cloze 自監督**,在 6.5 億字真實臺灣正體語料上:
69
+ 每個 lattice 位點收合成單一 `[MASK]`,模型預測臺灣書寫者實際用了哪個形式。
70
+ 這把無標註語料變成上億個監督事件,且消除了「相信輸入表面形式」的捷徑。
71
+
72
+ 雙 pass 架構:masked pass 提供無洩漏的語境證據,clean pass(陸式汙染文本)
73
+ 提供表面證據與文件級領域向量。候選一律由**與文本共用的字元 embedding**
74
+ 動態編碼,沒有 per-candidate 查表參數——這是字典熱更新的前提。
75
+
76
+ 架構:d=256,8 層(6 層 dilated TCN dilation 1..128 + 2 層 local attention),
77
+ 預訓練 120k 步 + finetune 8k 步,RTX 4080 約 2.8 小時。
78
+
79
+ ## 操作點
80
+
81
+ 模型與字典相同,只差「要多少證據才動手」(τ 是對數勝算比門檻):
82
+
83
+ | preset | 語意 | site acc |
84
+ | --- | --- | --- |
85
+ | `accuracy` | 20:1 勝算才改,benchmark 最佳 | 0.9712 |
86
+ | `balanced` | 2.7:1 即改,**預設** | 0.9668 |
87
+ | `taiwanize` | 額外壓制陸式專用詞(視頻/博客/實時) | 0.9640 |
88
+ | `aggressive` | 只靠字典硬過濾把關 | 0.9631 |
89
+
90
+ ```python
91
+ conv = twlat.Converter(preset="taiwanize")
92
+ r = conv.explain("这个视频的信息量很大")
93
+ for d in r.decisions:
94
+ print(d) # Decision('視頻'→'影片' @[2,4) cross_strait u=2.75)
95
+ ```
96
+
97
+ ## 熱更新
98
+
99
+ 新增字典條目只需重新編譯 `data/dict/lattice_lexicon.json`,**模型權重不動**。
100
+ 實測:訓練時完全沒見過的 50 條規則,zero-shot change accuracy **0.71**
101
+ (前代架構同一量測為 0.12)。
102
+
103
+ ## 檔案
104
+
105
+ | 檔案 | 用途 |
106
+ | --- | --- |
107
+ | `twinity-1.pt` | 模型權重(8.86M 參數) |
108
+ | `data/dict/lattice_lexicon.json` | 編譯後的字典(1,780 confusion group/3,977 詞形)——熱更新入口 |
109
+ | `data/dict/char_vocab_v3.json` | 字元表(4,096),OOV 走 hash bucket |
110
+ | `data/dict/rules/` | 簡繁字表、臺標變體表、必轉字表 |
111
+ | `data/model/tau.json` | 部署操作點的決策門檻 |
112
+ | `twlat/` | 推論程式碼(純 Python,相依:torch、numpy、regex、pyahocorasick、opencc) |
113
+
114
+ ## 使用
115
+
116
+ ```bash
117
+ pip install torch numpy regex pyahocorasick opencc-python-reimplemented
118
+ ```
119
+
120
+ ```python
121
+ from huggingface_hub import snapshot_download
122
+ import os, sys
123
+
124
+ path = snapshot_download("JacobLinCool/Twinity-1")
125
+ os.environ["TWLAT_HOME"] = f"{path}/data"
126
+ sys.path.insert(0, path)
127
+
128
+ import twlat
129
+ conv = twlat.Converter(ckpt=f"{path}/twinity-1.pt", device="cpu")
130
+ print(conv.convert("这个程序有bug,请在服务器上部署"))
131
+ ```
132
+
133
+ CPU 單執行緒最快(`torch.set_num_threads(1)`):11,300 字/秒、p95 23 ms。
134
+ 執行緒開多反而慢 3–24 倍(小矩陣的執行緒同步成本壓倒運算)。
135
+
136
+ ## 已知限制
137
+
138
+ 1. **陸式專用詞的漏轉**:`服務器→伺服器`、`搜索→搜尋` 等在訓練語料中缺少
139
+ change 方向訊號(網爬語料原生大量出現且被標為保留),模型高信心保留。
140
+ 約佔殘餘 change 錯誤的 25%。修正路徑明確但需重訓。
141
+ 2. **INT8 量化未達標**(−1.33pp),交付 FP32。
142
+ 3. **台/臺 由語境決定**而非固定政策——多數語境正確,但官方機關名語域仍有殘餘錯誤。
143
+ 若你的場景要求一律「臺」,請在後處理強制。
144
+ 4. 訓練語料含 CC-100 網爬文本,可能帶有其偏誤。
145
+ 5. 輸入超過 512 字會以滑動視窗處理(stride 384),跨窗的一致性未特別最佳化。
146
+
147
+ ## 授權與致謝
148
+
149
+ 模型權重 MIT。字典衍生自 [zhtw-mcp](https://github.com/sysprog21/zhtw-mcp)(MIT)
150
+ 與 [OpenCC](https://github.com/BYVoid/OpenCC)(Apache-2.0)——本專案的核心主張之一
151
+ 正是「這些字典裡的語意資訊被嚴重低估」。訓練語料:維基百科 zh-tw(CC BY-SA 4.0)、
152
+ 臺灣立法院法律研究資料(OGDL-1.0)、CC-100 繁體。
data/dict/char_vocab_v3.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"式": 3, "程": 4, "動": 5, "行": 6, "機": 7, "數": 8, "電": 9, "分": 10, "器": 11, "子": 12, "體": 13, "理": 14, "網": 15, "函": 16, "用": 17, "件": 18, "類": 19, "位": 20, "算": 21, "碼": 22, "核": 23, "斯": 24, "元": 25, "序": 26, "化": 27, "存": 28, "多": 29, "文": 30, "亞": 31, "內": 32, "資": 33, "別": 34, "檔": 35, "大": 36, "列": 37, "標": 38, "庫": 39, "作": 40, "型": 41, "性": 42, "運": 43, "字": 44, "實": 45, "模": 46, "置": 47, "生": 48, "心": 49, "管": 50, "配": 51, "系": 52, "空": 53, "聯": 54, "流": 55, "卡": 56, "訊": 57, "的": 58, "代": 59, "計": 60, "地": 61, "面": 62, "合": 63, "單": 64, "線": 65, "圖": 66, "接": 67, "視": 68, "移": 69, "基": 70, "話": 71, "轉": 72, " ": 73, "人": 74, "時": 75, "特": 76, "路": 77, "量": 78, "態": 79, "車": 80, "統": 81, "記": 82, "取": 83, "符": 84, "發": 85, "表": 86, "物": 87, "比": 88, "回": 89, "導": 90, "布": 91, "集": 92, "率": 93, "構": 94, "間": 95, "全": 96, "進": 97, "務": 98, "尼": 99, "中": 100, "開": 101, "定": 102, "高": 103, "加": 104, "點": 105, "通": 106, "保": 107, "結": 108, "服": 109, "語": 110, "片": 111, "號": 112, "板": 113, "端": 114, "操": 115, "能": 116, "成": 117, "主": 118, "重": 119, "址": 120, "可": 121, "業": 122, "工": 123, "員": 124, "設": 125, "爾": 126, "影": 127, "二": 128, "解": 129, "索": 130, "手": 131, "安": 132, "信": 133, "拉": 134, "裝": 135, "值": 136, "頁": 137, "載": 138, "一": 139, "不": 140, "國": 141, "下": 142, "本": 143, "利": 144, "料": 145, "排": 146, "息": 147, "錄": 148, "戶": 149, "象": 150, "域": 151, "盤": 152, "上": 153, "自": 154, "無": 155, "克": 156, "格": 157, "馬": 158, "向": 159, "包": 160, "交": 161, "調": 162, "巴": 163, "編": 164, "碟": 165, "對": 166, "學": 167, "區": 168, "入": 169, "選": 170, "處": 171, "里": 172, "告": 173, "引": 174, "e": 175, "過": 176, "新": 177, "原": 178, "音": 179, "組": 180, "局": 181, "言": 182, "識": 183, "縮": 184, "方": 185, "法": 186, "台": 187, "相": 188, "應": 189, "達": 190, "案": 191, "腦": 192, "鍵": 193, "複": 194, "憶": 195, "o": 196, "出": 197, "外": 198, "常": 199, "客": 200, "據": 201, "準": 202, "源": 203, "架": 204, "範": 205, "框": 206, "和": 207, "公": 208, "部": 209, "道": 210, "場": 211, "平": 212, "頭": 213, "制": 214, "光": 215, "快": 216, "優": 217, "層": 218, "執": 219, "絡": 220, "儲": 221, "串": 222, "屏": 223, "前": 224, "名": 225, "目": 226, "活": 227, "口": 228, "像": 229, "術": 230, "壓": 231, "測": 232, "納": 233, "異": 234, "頻": 235, "擬": 236, "r": 237, "關": 238, "正": 239, "先": 240, "站": 241, "價": 242, "級": 243, "質": 244, "控": 245, "哥": 246, "智": 247, "輯": 248, "幕": 249, "塞": 250, "啟": 251, "硬": 252, "繫": 253, "磁": 254, "邏": 255, "小": 256, "現": 257, "長": 258, "者": 259, "c": 260, "品": 261, "金": 262, "士": 263, "形": 264, "節": 265, "維": 266, "廣": 267, "校": 268, "預": 269, "括": 270, "銷": 271, "軟": 272, "互": 273, "擴": 274, "虛": 275, "有": 276, "個": 277, "a": 278, "n": 279, "天": 280, "度": 281, "三": 282, "期": 283, "西": 284, "產": 285, "氣": 286, "指": 287, "反": 288, "條": 289, "超": 290, "義": 291, "阿": 292, "規": 293, "半": 294, "印": 295, "菜": 296, "套": 297, "塊": 298, "貼": 299, "窗": 300, "螢": 301, "堆": 302, "棧": 303, "在": 304, "了": 305, "t": 306, "市": 307, "意": 308, "情": 309, "身": 310, "P": 311, "裡": 312, "水": 313, "展": 314, "示": 315, "風": 316, "傳": 317, "容": 318, "連": 319, "功": 320, "限": 321, "底": 322, "協": 323, "錯": 324, "波": 325, "聖": 326, "登": 327, "按": 328, "吉": 329, "樹": 330, "析": 331, "坦": 332, "譯": 333, "映": 334, "欄": 335, "以": 336, "i": 337, "後": 338, "最": 339, "事": 340, "S": 341, "等": 342, "那": 343, "次": 344, "使": 345, "感": 346, "真": 347, "參": 348, "建": 349, "太": 350, "變": 351, "帶": 352, "共": 353, "門": 354, "整": 355, "羅": 356, "具": 357, "製": 358, "親": 359, "試": 360, "效": 361, "證": 362, "查": 363, "隨": 364, "護": 365, "修": 366, "令": 367, "讀": 368, "極": 369, "適": 370, "切": 371, "介": 372, "臺": 373, "密": 374, "雲": 375, "筆": 376, "搜": 377, "驅": 378, "鈕": 379, "為": 380, "會": 381, "要": 382, "好": 383, "說": 384, "並": 385, "民": 386, "樣": 387, "提": 388, "色": 389, "科": 390, "院": 391, "備": 392, "首": 393, "論": 394, "食": 395, "續": 396, "畫": 397, "林": 398, "聲": 399, "兒": 400, "支": 401, "研": 402, "權": 403, "項": 404, "步": 405, "究": 406, "死": 407, "素": 408, "土": 409, "換": 410, "微": 411, "父": 412, "派": 413, "塔": 414, "貝": 415, "伯": 416, "固": 417, "箱": 418, "覆": 419, "泡": 420, "緒": 421, "掛": 422, "閒": 423, "遞": 424, "疊": 425, "埠": 426, "得": 427, "s": 428, "l": 429, "及": 430, "同": 431, "海": 432, "g": 433, "直": 434, "打": 435, "放": 436, "報": 437, "持": 438, "議": 439, "遊": 440, "幾": 441, "花": 442, "除": 443, "例": 444, "版": 445, "蘭": 446, "命": 447, "助": 448, "環": 449, "境": 450, "病": 451, "玩": 452, "紅": 453, "狀": 454, "終": 455, "黑": 456, "飛": 457, "注": 458, "負": 459, "積": 460, "航": 461, "充": 462, "席": 463, "批": 464, "尋": 465, "洛": 466, "腳": 467, "詞": 468, "毛": 469, "倒": 470, "階": 471, "呼": 472, "瓦": 473, "陣": 474, "跳": 475, "歸": 476, "迴": 477, "盒": 478, "割": 479, "家": 480, "當": 481, "力": 482, "由": 483, "明": 484, "教": 485, "問": 486, "南": 487, "老": 488, "德": 489, "始": 490, "商": 491, "強": 492, "萬": 493, "便": 494, "房": 495, "眼": 496, "清": 497, "技": 498, "投": 499, "易": 500, "增": 501, "消": 502, "驗": 503, "景": 504, "藝": 505, "停": 506, "繼": 507, "魚": 508, "檢": 509, "宣": 510, "健": 511, "博": 512, "射": 513, "沙": 514, "補": 515, "述": 516, "監": 517, "森": 518, "略": 519, "症": 520, "洗": 521, "觸": 522, "托": 523, "飾": 524, "隆": 525, "默": 526, "桌": 527, "誌": 528, "郵": 529, "抽": 530, "茲": 531, "截": 532, "匯": 533, "滾": 534, "拖": 535, "鏈": 536, "閘": 537, "弧": 538, "年": 539, "我": 540, "來": 541, "日": 542, "們": 543, "而": 544, "因": 545, "沒": 546, "美": 547, "第": 548, "C": 549, "m": 550, "知": 551, "東": 552, "立": 553, "總": 554, "球": 555, "題": 556, "L": 557, "專": 558, "推": 559, "住": 560, "角": 561, "熱": 562, "滿": 563, "速": 564, "根": 565, "營": 566, "史": 567, "習": 568, "擊": 569, "失": 570, "米": 571, "希": 572, "U": 573, "顯": 574, "寫": 575, "旅": 576, "劇": 577, "夫": 578, "哈": 579, "斷": 580, "企": 581, "千": 582, "險": 583, "背": 584, "復": 585, "雷": 586, "含": 587, "承": 588, "叫": 589, "佛": 590, "攝": 591, "訪": 592, "諾": 593, "追": 594, "酸": 595, "激": 596, "雜": 597, "藍": 598, "童": 599, "佈": 600, "散": 601, "督": 602, "私": 603, "Q": 604, "圓": 605, "丁": 606, "慧": 607, "覽": 608, "簽": 609, "隱": 610, "寬": 611, "緩": 612, "淨": 613, "晶": 614, "捷": 615, "併": 616, "返": 617, "盧": 618, "刷": 619, "玻": 620, "璃": 621, "梨": 622, "捲": 623, "衍": 624, "茨": 625, "饋": 626, "鑰": 627, "溢": 628, "2": 629, "這": 630, "到": 631, "就": 632, "3": 633, "4": 634, "6": 635, "然": 636, "去": 637, "起": 638, "更": 639, "果": 640, "政": 641, "從": 642, "p": 643, "受": 644, "任": 645, "再": 646, "樂": 647, "N": 648, "界": 649, "G": 650, "際": 651, "演": 652, "山": 653, "四": 654, "跟": 655, "白": 656, "邊": 657, "創": 658, "w": 659, "舉": 660, "育": 661, "官": 662, "落": 663, "雙": 664, "福": 665, "陸": 666, "簡": 667, "職": 668, "依": 669, "獎": 670, "防": 671, "古": 672, "鐵": 673, "班": 674, "母": 675, "石": 676, "劃": 677, "播": 678, "陽": 679, "八": 680, "圍": 681, "伊": 682, "彈": 683, "假": 684, "蘇": 685, "唱": 686, "策": 687, "吸": 688, "麗": 689, "額": 690, "農": 691, "鐘": 692, "順": 693, "葉": 694, "談": 695, "付": 696, "萊": 697, "概": 698, "休": 699, "志": 700, "毒": 701, "延": 702, "靜": 703, "彩": 704, "宮": 705, "鏡": 706, "冰": 707, "勞": 708, "餘": 709, "句": 710, "頂": 711, "巨": 712, "誤": 713, "魯": 714, "莫": 715, "尾": 716, "封": 717, "姆": 718, "麵": 719, "奶": 720, "烏": 721, "蒙": 722, "圈": 723, "滑": 724, "髮": 725, "拜": 726, "註": 727, "堡": 728, "帳": 729, "暫": 730, "儀": 731, "描": 732, "刀": 733, "乳": 734, "賴": 735, "瓜": 736, "託": 737, "吹": 738, "夾": 739, "宏": 740, "偵": 741, "蹤": 742, "攜": 743, "剪": 744, "籤": 745, "帽": 746, "綁": 747, "叉": 748, "厄": 749, "彙": 750, "矩": 751, "嵌": 752, "酪": 753, "於": 754, "都": 755, "所": 756, "經": 757, "很": 758, "u": 759, "此": 760, "d": 761, "M": 762, "司": 763, "y": 764, "英": 765, "認": 766, "師": 767, "約": 768, "造": 769, "什": 770, "神": 771, "書": 772, "則": 773, "收": 774, "許": 775, "友": 776, "份": 777, "請": 778, "觀": 779, "決": 780, "求": 781, "店": 782, "候": 783, "治": 784, "即": 785, "照": 786, "難": 787, "離": 788, "款": 789, "獲": 790, "早": 791, "段": 792, "找": 793, "聽": 794, "歷": 795, "低": 796, "歌": 797, "龍": 798, "味": 799, "響": 800, "普": 801, "火": 802, "留": 803, "念": 804, "升": 805, "牌": 806, "免": 807, "溫": 808, "青": 809, "養": 810, "警": 811, "族": 812, "係": 813, "課": 814, "久": 815, "採": 816, "衛": 817, "靈": 818, "均": 819, "殺": 820, "刻": 821, "典": 822, "衣": 823, "廠": 824, "牙": 825, "攻": 826, "益": 827, "魔": 828, "永": 829, "薩": 830, "牛": 831, "釋": 832, "救": 833, "盟": 834, "臨": 835, "畢": 836, "瑞": 837, "缺": 838, "迪": 839, "怪": 840, "衝": 841, "骨": 842, "摩": 843, "蓋": 844, "探": 845, "逐": 846, "穩": 847, "脫": 848, "招": 849, "危": 850, "損": 851, "唯": 852, "紙": 853, "咖": 854, "零": 855, "混": 856, "偏": 857, "燒": 858, "折": 859, "埃": 860, "純": 861, "奈": 862, "礎": 863, "池": 864, "插": 865, "豆": 866, "潛": 867, "睛": 868, "殊": 869, "抓": 870, "氏": 871, "杯": 872, "喬": 873, "輔": 874, "冊": 875, "券": 876, "繪": 877, "殘": 878, "洞": 879, "杜": 880, "恢": 881, "泛": 882, "敦": 883, "帕": 884, "寄": 885, "卷": 886, "裂": 887, "鍋": 888, "塑": 889, "櫃": 890, "桑": 891, "鄰": 892, "采": 893, "汁": 894, "擎": 895, "倉": 896, "贊": 897, "窮": 898, "屍": 899, "仿": 900, "塵": 901, "泥": 902, "攤": 903, "辨": 904, "挖": 905, "賦": 906, "伺": 907, "傅": 908, "菸": 909, "偽": 910, "鬱": 911, "腺": 912, "筒": 913, "湊": 914, "漿": 915, "賬": 916, "喇": 917, "鉤": 918, "叭": 919, "芯": 920, "駭": 921, "繃": 922, "殭": 923, "幀": 924, "是": 925, "(": 926, ")": 927, "也": 928, "與": 929, "著": 930, "看": 931, "如": 932, "A": 933, "被": 934, "麼": 935, "只": 936, ")": 937, "(": 938, "h": 939, "女": 940, "E": 941, "I": 942, "十": 943, "戰": 944, "北": 945, "少": 946, "O": 947, "給": 948, "才": 949, "覺": 950, "愛": 951, "見": 952, "非": 953, "隊": 954, "灣": 955, "需": 956, "改": 957, "b": 958, "且": 959, "吃": 960, "稱": 961, "屬": 962, "供": 963, "費": 964, "走": 965, "省": 966, "確": 967, "必": 968, "精": 969, "另": 970, "深": 971, "紀": 972, "委": 973, "思": 974, "購": 975, "園": 976, "周": 977, "歐": 978, "遠": 979, "票": 980, "享": 981, "晚": 982, "奇": 983, "X": 984, "座": 985, "威": 986, "送": 987, "居": 988, "勢": 989, "康": 990, "待": 991, "突": 992, "差": 993, "七": 994, "木": 995, "飯": 996, "察": 997, "破": 998, "臉": 999, "聞": 1000, "獻": 1001, "附": 1002, "減": 1003, "財": 1004, "短": 1005, "賣": 1006, "慢": 1007, "婚": 1008, "退": 1009, "願": 1010, "訂": 1011, "街": 1012, "洋": 1013, "融": 1014, "勝": 1015, "絲": 1016, "屋": 1017, "庭": 1018, "倫": 1019, "媒": 1020, "副": 1021, "疑": 1022, "粉": 1023, "革": 1024, "弟": 1025, "束": 1026, "訓": 1027, "審": 1028, "尚": 1029, "援": 1030, "守": 1031, "雪": 1032, "競": 1033, "授": 1034, "曼": 1035, "避": 1036, "染": 1037, "茶": 1038, "忙": 1039, "亂": 1040, "培": 1041, "鬆": 1042, "橋": 1043, "榮": 1044, "予": 1045, "禁": 1046, "揮": 1047, "棒": 1048, "隔": 1049, "借": 1050, "肯": 1051, "游": 1052, "梅": 1053, "雞": 1054, "寧": 1055, "陰": 1056, "紐": 1057, "菲": 1058, "潮": 1059, "抵": 1060, "忍": 1061, "占": 1062, "握": 1063, "藉": 1064, "婦": 1065, "榜": 1066, "綜": 1067, "皆": 1068, "旋": 1069, "跨": 1070, "珠": 1071, "兼": 1072, "仔": 1073, "兄": 1074, "黎": 1075, "暖": 1076, "桃": 1077, "佔": 1078, "鎖": 1079, "氧": 1080, "娘": 1081, "衡": 1082, "鞋": 1083, "閃": 1084, "赫": 1085, "悉": 1086, "毀": 1087, "牆": 1088, "剩": 1089, "橫": 1090, "灰": 1091, "撞": 1092, "讚": 1093, "凌": 1094, "憑": 1095, "扣": 1096, "綱": 1097, "柯": 1098, "番": 1099, "餅": 1100, "臟": 1101, "壯": 1102, "輩": 1103, "欲": 1104, "摸": 1105, "鼠": 1106, "械": 1107, "薪": 1108, "掃": 1109, "褲": 1110, "壁": 1111, "遲": 1112, "涼": 1113, "梯": 1114, "循": 1115, "浮": 1116, "醬": 1117, "翰": 1118, "丟": 1119, "瀏": 1120, "涵": 1121, "芳": 1122, "娃": 1123, "孤": 1124, "乙": 1125, "匹": 1126, "銅": 1127, "販": 1128, "譜": 1129, "撥": 1130, "浦": 1131, "扶": 1132, "霧": 1133, "鑑": 1134, "螺": 1135, "凍": 1136, "孟": 1137, "拋": 1138, "桿": 1139, "貪": 1140, "棋": 1141, "丸": 1142, "垃": 1143, "圾": 1144, "遮": 1145, "肢": 1146, "劫": 1147, "兆": 1148, "餓": 1149, "桶": 1150, "昇": 1151, "匙": 1152, "掘": 1153, "罐": 1154, "慌": 1155, "砂": 1156, "喘": 1157, "巢": 1158, "銜": 1159, "顛": 1160, "亭": 1161, "厘": 1162, "襯": 1163, "踩": 1164, "髒": 1165, "紮": 1166, "簿": 1167, "橙": 1168, "盪": 1169, "檯": 1170, "煎": 1171, "樸": 1172, "札": 1173, "瓊": 1174, "溯": 1175, "刮": 1176, "噪": 1177, "沫": 1178, "帖": 1179, "毯": 1180, "薛": 1181, "媳": 1182, "稽": 1183, "蒲": 1184, "蔽": 1185, "摺": 1186, "綴": 1187, "笛": 1188, "飢": 1189, "鬍": 1190, "嚮": 1191, "拐": 1192, "鬚": 1193, "胰": 1194, "鴿": 1195, "筷": 1196, "迭": 1197, "渲": 1198, "輾": 1199, "婿": 1200, "拷": 1201, "佇": 1202, "冪": 1203, "箔": 1204, "燬": 1205, ",": 1206, "之": 1207, "你": 1208, "其": 1209, "還": 1210, "-": 1211, "想": 1212, "種": 1213, "B": 1214, "又": 1215, "團": 1216, "/": 1217, "華": 1218, "香": 1219, "k": 1220, "它": 1221, "張": 1222, "辦": 1223, "城": 1224, "f": 1225, "V": 1226, "越": 1227, "曲": 1228, "W": 1229, "K": 1230, "眾": 1231, "吧": 1232, "況": 1233, "黨": 1234, "故": 1235, "細": 1236, "拍": 1237, "評": 1238, "致": 1239, "拿": 1240, "初": 1241, "幫": 1242, "濟": 1243, "爭": 1244, "透": 1245, "寶": 1246, "若": 1247, "施": 1248, "錢": 1249, "興": 1250, "黃": 1251, "僅": 1252, "奧": 1253, "股": 1254, "傷": 1255, "擇": 1256, "須": 1257, "絕": 1258, "止": 1259, "油": 1260, "害": 1261, "血": 1262, "肉": 1263, "章": 1264, "皮": 1265, "藥": 1266, "講": 1267, "售": 1268, "律": 1269, "陳": 1270, "善": 1271, "樓": 1272, "練": 1273, "夜": 1274, "佳": 1275, "訴": 1276, "輸": 1277, "織": 1278, "顧": 1279, "討": 1280, "午": 1281, "貨": 1282, "草": 1283, "勒": 1284, "輪": 1285, "冷": 1286, "夏": 1287, "趣": 1288, "坐": 1289, "露": 1290, "兵": 1291, "堂": 1292, "盡": 1293, "億": 1294, "亮": 1295, "頓": 1296, "漢": 1297, "邦": 1298, "敗": 1299, "貴": 1300, "答": 1301, "週": 1302, "甲": 1303, "幸": 1304, "暴": 1305, "針": 1306, "紹": 1307, "舞": 1308, "急": 1309, "築": 1310, "幣": 1311, "雅": 1312, "惡": 1313, "翻": 1314, "豐": 1315, "綠": 1316, "槍": 1317, "乾": 1318, "隻": 1319, "妹": 1320, "鬥": 1321, "秀": 1322, "障": 1323, "俄": 1324, "恐": 1325, "誰": 1326, "尤": 1327, "薦": 1328, "岸": 1329, "努": 1330, "燈": 1331, "乘": 1332, "艾": 1333, "困": 1334, "暗": 1335, "于": 1336, "詢": 1337, "犯": 1338, "宿": 1339, "丹": 1340, "醒": 1341, "徵": 1342, "賞": 1343, "瞭": 1344, "松": 1345, "棄": 1346, "浪": 1347, "傑": 1348, "湯": 1349, "糖": 1350, "后": 1351, "鋼": 1352, "累": 1353, "掌": 1354, "敵": 1355, "幹": 1356, "租": 1357, "炸": 1358, "末": 1359, "貿": 1360, "緣": 1361, "徒": 1362, "賓": 1363, "谷": 1364, "鬼": 1365, "妻": 1366, "胞": 1367, "偶": 1368, "促": 1369, "宇": 1370, "戀": 1371, "辛": 1372, "毫": 1373, "祖": 1374, "阻": 1375, "軌": 1376, "干": 1377, "袋": 1378, "冬": 1379, "儘": 1380, "徑": 1381, "幼": 1382, "裁": 1383, "胡": 1384, "秋": 1385, "擺": 1386, "遍": 1387, "揚": 1388, "幻": 1389, "焦": 1390, "珍": 1391, "蟲": 1392, "秒": 1393, "拒": 1394, "沿": 1395, "爺": 1396, "孫": 1397, "·": 1398, "偉": 1399, "礙": 1400, "弗": 1401, "奏": 1402, "膠": 1403, "嘗": 1404, "冒": 1405, "捕": 1406, "墨": 1407, "宅": 1408, "娛": 1409, "甘": 1410, "尖": 1411, "蓮": 1412, "津": 1413, "鼻": 1414, "煙": 1415, "沖": 1416, "仙": 1417, "愈": 1418, "潤": 1419, "鳳": 1420, "闆": 1421, "朱": 1422, "准": 1423, "悲": 1424, "燃": 1425, "姊": 1426, "廚": 1427, "脈": 1428, "牠": 1429, "旦": 1430, "蘋": 1431, "盃": 1432, "孕": 1433, "碎": 1434, "踏": 1435, "怒": 1436, "梁": 1437, "譽": 1438, "跡": 1439, "鬧": 1440, "洪": 1441, "壇": 1442, "羊": 1443, "芬": 1444, "添": 1445, "岩": 1446, "傾": 1447, "傢": 1448, "夥": 1449, "撤": 1450, "慈": 1451, "舍": 1452, "軸": 1453, "憂": 1454, "磨": 1455, "腰": 1456, "辣": 1457, "俊": 1458, "契": 1459, "輝": 1460, "籃": 1461, "勁": 1462, "敘": 1463, "殼": 1464, "浴": 1465, "韋": 1466, "q": 1467, "沈": 1468, "恆": 1469, "旺": 1470, "柴": 1471, "拼": 1472, "枚": 1473, "昂": 1474, "淋": 1475, "吐": 1476, "撒": 1477, "箭": 1478, "岡": 1479, "鋒": 1480, "葛": 1481, "疼": 1482, "斑": 1483, "伏": 1484, "扎": 1485, "叔": 1486, "臘": 1487, "范": 1488, "緻": 1489, "稿": 1490, "斤": 1491, "塗": 1492, "撐": 1493, "眉": 1494, "抹": 1495, "鑽": 1496, "枝": 1497, "諮": 1498, "寵": 1499, "征": 1500, "煉": 1501, "爛": 1502, "糊": 1503, "慘": 1504, "柳": 1505, "彎": 1506, "悅": 1507, "賠": 1508, "鈴": 1509, "獅": 1510, "抑": 1511, "纖": 1512, "錶": 1513, "伙": 1514, "懸": 1515, "抬": 1516, "雕": 1517, "酷": 1518, "曆": 1519, "昆": 1520, "舌": 1521, "卓": 1522, "爐": 1523, "奔": 1524, "屁": 1525, "颱": 1526, "彌": 1527, "垂": 1528, "堪": 1529, "嘆": 1530, "闊": 1531, "罩": 1532, "疆": 1533, "盈": 1534, "懶": 1535, "痕": 1536, "釐": 1537, "慾": 1538, "蘿": 1539, "彷": 1540, "哩": 1541, "糾": 1542, "仇": 1543, "捨": 1544, "逾": 1545, "聘": 1546, "灌": 1547, "愉": 1548, "醉": 1549, "癒": 1550, "斗": 1551, "彭": 1552, "彿": 1553, "飄": 1554, "繩": 1555, "賈": 1556, "侶": 1557, "誇": 1558, "勾": 1559, "濾": 1560, "傲": 1561, "吊": 1562, "棉": 1563, "廂": 1564, "鷹": 1565, "籲": 1566, "叢": 1567, "蹟": 1568, "掩": 1569, "胺": 1570, "駁": 1571, "縫": 1572, "酬": 1573, "鍾": 1574, "禦": 1575, "募": 1576, "嚐": 1577, "蕩": 1578, "虹": 1579, "抖": 1580, "黏": 1581, "曝": 1582, "巾": 1583, "御": 1584, "余": 1585, "槽": 1586, "兇": 1587, "逸": 1588, "湧": 1589, "茄": 1590, "韻": 1591, "杭": 1592, "鍊": 1593, "芽": 1594, "沾": 1595, "拘": 1596, "萌": 1597, "脹": 1598, "蛛": 1599, "潑": 1600, "卸": 1601, "卜": 1602, "芭": 1603, "云": 1604, "蓄": 1605, "蓬": 1606, "栗": 1607, "郁": 1608, "弦": 1609, "勳": 1610, "艷": 1611, "塘": 1612, "鹹": 1613, "勿": 1614, "衫": 1615, "餵": 1616, "划": 1617, "醜": 1618, "酵": 1619, "岳": 1620, "盲": 1621, "汀": 1622, "猴": 1623, "捧": 1624, "膝": 1625, "唸": 1626, "琉": 1627, "篩": 1628, "薯": 1629, "謠": 1630, "渠": 1631, "淇": 1632, "杰": 1633, "豔": 1634, "柄": 1635, "朴": 1636, "梭": 1637, "迦": 1638, "寮": 1639, "蒐": 1640, "謎": 1641, "僵": 1642, "碌": 1643, "馳": 1644, "鋁": 1645, "姜": 1646, "茅": 1647, "堤": 1648, "匣": 1649, "僕": 1650, "歎": 1651, "喂": 1652, "鱷": 1653, "塢": 1654, "戚": 1655, "圭": 1656, "凶": 1657, "氨": 1658, "鑒": 1659, "澱": 1660, "膨": 1661, "蔔": 1662, "榴": 1663, "穀": 1664, "棍": 1665, "剖": 1666, "庇": 1667, "檻": 1668, "蠟": 1669, "宵": 1670, "穫": 1671, "倖": 1672, "簾": 1673, "韌": 1674, "勘": 1675, "挽": 1676, "矢": 1677, "咨": 1678, "渣": 1679, "姦": 1680, "傭": 1681, "壩": 1682, "攪": 1683, "瑕": 1684, "蜘": 1685, "筑": 1686, "薑": 1687, "閑": 1688, "睹": 1689, "蔭": 1690, "沸": 1691, "擱": 1692, "粘": 1693, "杆": 1694, "咽": 1695, "蕊": 1696, "瀋": 1697, "矚": 1698, "杖": 1699, "挨": 1700, "窺": 1701, "崙": 1702, "闢": 1703, "咸": 1704, "樑": 1705, "擲": 1706, "涌": 1707, "淩": 1708, "愿": 1709, "甦": 1710, "瞻": 1711, "哄": 1712, "噹": 1713, "苔": 1714, "恤": 1715, "芸": 1716, "噁": 1717, "証": 1718, "汶": 1719, "癥": 1720, "惰": 1721, "乍": 1722, "槓": 1723, "鉅": 1724, "疵": 1725, "滷": 1726, "乞": 1727, "蹦": 1728, "蠍": 1729, "屎": 1730, "奸": 1731, "嘩": 1732, "祇": 1733, "剋": 1734, "驢": 1735, "駝": 1736, "侷": 1737, "齣": 1738, "霄": 1739, "侖": 1740, "柿": 1741, "丑": 1742, "瓏": 1743, "鮭": 1744, "饑": 1745, "醃": 1746, "崑": 1747, "酋": 1748, "擷": 1749, "痠": 1750, "嶽": 1751, "鐮": 1752, "嚥": 1753, "婁": 1754, "噌": 1755, "巖": 1756, "夸": 1757, "菠": 1758, "唾": 1759, "曳": 1760, "勛": 1761, "瑙": 1762, "煲": 1763, "涂": 1764, "氓": 1765, "燻": 1766, "哮": 1767, "淒": 1768, "糰": 1769, "揹": 1770, "瀰": 1771, "据": 1772, "濛": 1773, "墻": 1774, "鹵": 1775, "蹭": 1776, "婪": 1777, "甯": 1778, "吁": 1779, "摳": 1780, "漓": 1781, "蠔": 1782, "闇": 1783, "炊": 1784, "慄": 1785, "鐳": 1786, "辟": 1787, "氾": 1788, "霓": 1789, "葯": 1790, "几": 1791, "柜": 1792, "鏟": 1793, "剃": 1794, "蠣": 1795, "彆": 1796, "鮪": 1797, "弔": 1798, "噠": 1799, "拽": 1800, "佣": 1801, "尸": 1802, "璇": 1803, "庵": 1804, "蔑": 1805, "淀": 1806, "蚵": 1807, "麴": 1808, "帛": 1809, "唧": 1810, "朮": 1811, "猝": 1812, "仆": 1813, "杠": 1814, "綑": 1815, "薹": 1816, "熏": 1817, "箇": 1818, "釦": 1819, "鎌": 1820, "獼": 1821, "宕": 1822, "絃": 1823, "諡": 1824, "睏": 1825, "捩": 1826, "矇": 1827, "种": 1828, "鵰": 1829, "丰": 1830, "颳": 1831, "伕": 1832, "俬": 1833, "譁": 1834, "牴": 1835, "綵": 1836, "鉆": 1837, "鞦": 1838, "韆": 1839, "鬨": 1840, "亙": 1841, "剷": 1842, "捱": 1843, "喱": 1844, "孃": 1845, "閾": 1846, "衕": 1847, "璿": 1848, "衊": 1849, "鈽": 1850, "汎": 1851, "衚": 1852, "荐": 1853, "襬": 1854, "胜": 1855, "齧": 1856, "囌": 1857, "挂": 1858, "痿": 1859, "脩": 1860, "虫": 1861, "嚙": 1862, "万": 1863, "譟": 1864, "卹": 1865, "撾": 1866, "悽": 1867, "罈": 1868, "冑": 1869, "垻": 1870, "蕓": 1871, "裊": 1872, "․": 1873, "錼": 1874, "霑": 1875, "蹠": 1876, "慼": 1877, "帘": 1878, "腊": 1879, "蝎": 1880, "腌": 1881, "鉳": 1882, "鍅": 1883, "鎝": 1884, "亘": 1885, "菴": 1886, "跖": 1887, "胄": 1888, "灩": 1889, "确": 1890, "膻": 1891, "蓆": 1892, "蜡": 1893, "贗": 1894, "輓": 1895, "适": 1896, "壎": 1897, "广": 1898, "縴": 1899, "羶": 1900, "叶": 1901, "諤": 1902, "謚": 1903, "鋂": 1904, "鑀": 1905, "閤": 1906, "鷴": 1907, "党": 1908, "价": 1909, "厂": 1910, "懞": 1911, "柺": 1912, "硃": 1913, "綳": 1914, "蚝": 1915, "嫋": 1916, "譭": 1917, "鏇": 1918, "塤": 1919, "榘": 1920, "灕": 1921, "灧": 1922, "翫": 1923, "苹": 1924, "鈁": 1925, "鎦": 1926, "㐹": 1927, "㑶": 1928, "儁": 1929, "群": 1930, "秘": 1931, "寀": 1932, "廕": 1933, "彔": 1934, "床": 1935, "曏": 1936, "极": 1937, "灶": 1938, "緔": 1939, "鞝": 1940, "襉": 1941, "襇": 1942, "讎": 1943, "賙": 1944, "贋": 1945, "鈅": 1946, "鈡": 1947, "鈈": 1948, "錇": 1949, "鎇": 1950, "鎿": 1951, "鍀": 1952, "鑥": 1953, "鎲": 1954, "钂": 1955, "钁": 1956, "鐝": 1957, "鎄": 1958, "鷳": 1959, "鼕": 1960, "。": 1961, "1": 1962, "、": 1963, "0": 1964, ".": 1965, "他": 1966, "「": 1967, "」": 1968, "9": 1969, ":": 1970, "5": 1971, "月": 1972, "8": 1973, ",": 1974, "7": 1975, "但": 1976, "!": 1977, "將": 1978, "或": 1979, "》": 1980, "《": 1981, "她": 1982, "讓": 1983, "些": 1984, "己": 1985, "兩": 1986, "?": 1987, "至": 1988, "已": 1989, "T": 1990, "D": 1991, ":": 1992, "世": 1993, "…": 1994, "該": 1995, ";": 1996, "・": 1997, "軍": 1998, "賽": 1999, "完": 2000, "做": 2001, "每": 2002, "R": 2003, "”": 2004, "各": 2005, "“": 2006, "把": 2007, "_": 2008, "考": 2009, "今": 2010, "近": 2011, "星": 2012, "何": 2013, "F": 2014, "較": 2015, "!": 2016, "社": 2017, "港": 2018, "未": 2019, "H": 2020, "往": 2021, "卻": 2022, "望": 2023, "府": 2024, "\"": 2025, "五": 2026, "男": 2027, "王": 2028, "買": 2029, "醫": 2030, "領": 2031, "館": 2032, "孩": 2033, "喜": 2034, "—": 2035, "戲": 2036, "v": 2037, "雖": 2038, "~": 2039, "歡": 2040, "輕": 2041, "您": 2042, "曾": 2043, "足": 2044, "州": 2045, "洲": 2046, "百": 2047, "餐": 2048, "夠": 2049, "歲": 2050, "媽": 2051, "?": 2052, "嗎": 2053, "%": 2054, "京": 2055, "笑": 2056, "六": 2057, "怎": 2058, "獨": 2059, "甚": 2060, "室": 2061, "朋": 2062, "般": 2063, "似": 2064, "呢": 2065, "剛": 2066, "J": 2067, "啊": 2068, "季": 2069, "李": 2070, "縣": 2071, "責": 2072, "【": 2073, "】": 2074, "酒": 2075, "銀": 2076, "擔": 2077, "乎": 2078, "鎮": 2079, "否": 2080, "河": 2081, "仍": 2082, "x": 2083, "武": 2084, "亦": 2085, "島": 2086, "富": 2087, "謝": 2088, "九": 2089, "禮": 2090, "村": 2091, "緊": 2092, "嚴": 2093, "韓": 2094, "療": 2095, "[": 2096, "]": 2097, "江": 2098, "降": 2099, "央": 2100, "田": 2101, "Y": 2102, "哪": 2103, "材": 2104, "擁": 2105, "篇": 2106, "穿": 2107, "搭": 2108, "~": 2109, "遇": 2110, "朝": 2111, "恩": 2112, "竟": 2113, "左": 2114, "野": 2115, "某": 2116, "冠": 2117, "右": 2118, "抗": 2119, "貸": 2120, "廳": 2121, "夢": 2122, "帝": 2123, "怕": 2124, "蛋": 2125, "雄": 2126, "屆": 2127, "跑": 2128, "-": 2129, "川": 2130, "良": 2131, "『": 2132, "痛": 2133, "』": 2134, "苦": 2135, "宜": 2136, "藏": 2137, "閱": 2138, "懷": 2139, "舊": 2140, "驚": 2141, "判": 2142, "泰": 2143, "植": 2144, "申": 2145, "迷": 2146, "鮮": 2147, "宗": 2148, "z": 2149, "春": 2150, "澳": 2151, "姐": 2152, "掉": 2153, "耶": 2154, "漸": 2155, "鄉": 2156, "啦": 2157, "靠": 2158, "烈": 2159, "湖": 2160, "雨": 2161, "爆": 2162, "挑": 2163, "皇": 2164, "熟": 2165, "+": 2166, "堅": 2167, "爸": 2168, "亡": 2169, "罪": 2170, "船": 2171, "妳": 2172, "麻": 2173, "惠": 2174, "遭": 2175, "旁": 2176, "喝": 2177, "距": 2178, "耳": 2179, "壞": 2180, "飲": 2181, "楚": 2182, "喔": 2183, "伴": 2184, "漫": 2185, "麥": 2186, "迎": 2187, "朗": 2188, "─": 2189, "睡": 2190, " ": 2191, "顆": 2192, "巧": 2193, "甜": 2194, "刺": 2195, "慶": 2196, "績": 2197, "稅": 2198, "劉": 2199, "遺": 2200, "尺": 2201, "聚": 2202, "署": 2203, "艦": 2204, "淡": 2205, "震": 2206, "抱": 2207, "汽": 2208, "患": 2209, "慮": 2210, "輛": 2211, "盛": 2212, "舒": 2213, "忘": 2214, "診": 2215, "膚": 2216, "估": 2217, "側": 2218, ".": 2219, "'": 2220, "澤": 2221, "液": 2222, "嘴": 2223, "途": 2224, "替": 2225, "啡": 2226, "鼓": 2227, "旗": 2228, "吳": 2229, "既": 2230, "沉": 2231, "狗": 2232, "莉": 2233, "瑪": 2234, "呈": 2235, "楊": 2236, "顏": 2237, "詳": 2238, "慣": 2239, "弱": 2240, "Z": 2241, "嘉": 2242, "蒂": 2243, "懂": 2244, "敢": 2245, "玉": 2246, "趕": 2247, "勵": 2248, "貓": 2249, "鳥": 2250, "閉": 2251, "幅": 2252, "疫": 2253, "勇": 2254, "炎": 2255, "肌": 2256, "繁": 2257, "敏": 2258, "籍": 2259, "涉": 2260, "/": 2261, "災": 2262, "騎": 2263, "凱": 2264, "違": 2265, "倍": 2266, "搖": 2267, "@": 2268, "娜": 2269, "豪": 2270, "戴": 2271, "誠": 2272, "詩": 2273, "$": 2274, "尊": 2275, "仁": 2276, "謂": 2277, "邀": 2278, "坡": 2279, "伸": 2280, "劍": 2281, "駕": 2282, "迫": 2283, "齊": 2284, "濃": 2285, "奪": 2286, "柔": 2287, "荷": 2288, "狂": 2289, "竹": 2290, "j": 2291, "凡": 2292, "厚": 2293, "溝": 2294, "煩": 2295, "婆": 2296, "駛": 2297, "昨": 2298, "裏": 2299, "君": 2300, "紛": 2301, "劑": 2302, "役": 2303, "潔": 2304, "召": 2305, "唐": 2306, "聊": 2307, "菌": 2308, "疾": 2309, "彼": 2310, "齡": 2311, "逃": 2312, "侵": 2313, "\b": 2314, "–": 2315, "駐": 2316, "刑": 2317, "搞": 2318, "腿": 2319, "胎": 2320, "孔": 2321, "廢": 2322, "搶": 2323, "虎": 2324, "董": 2325, "偷": 2326, "獸": 2327, "&": 2328, "繞": 2329, "惜": 2330, "弄": 2331, "債": 2332, "巡": 2333, "贏": 2334, "耐": 2335, "脂": 2336, "措": 2337, "擾": 2338, "滅": 2339, "襲": 2340, "鄭": 2341, "癌": 2342, "泉": 2343, "^": 2344, "欣": 2345, "羽": 2346, "〉": 2347, "豬": 2348, "胸": 2349, ">": 2350, "拔": 2351, "莊": 2352, "忽": 2353, "稍": 2354, "哲": 2355, "陪": 2356, "齒": 2357, "刊": 2358, "〈": 2359, "痞": 2360, "陷": 2361, "佩": 2362, "呀": 2363, "井": 2364, "徐": 2365, "濕": 2366, "蔡": 2367, "敬": 2368, "晨": 2369, "錦": 2370, "妙": 2371, "​": 2372, "誕": 2373, "紫": 2374, "妝": 2375, "挺": 2376, "琴": 2377, "柏": 2378, "碰": 2379, "紋": 2380, "諸": 2381, "姓": 2382, "魂": 2383, "壽": 2384, "\u0007": 2385, "郎": 2386, "肥": 2387, "遷": 2388, "猶": 2389, "祝": 2390, "伍": 2391, "哭": 2392, "罰": 2393, "莎": 2394, "炮": 2395, "糕": 2396, "允": 2397, "烤": 2398, "葡": 2399, "俗": 2400, "翼": 2401, "°": 2402, "氛": 2403, "沃": 2404, "忠": 2405, "寺": 2406, "貌": 2407, "蜜": 2408, "牽": 2409, "*": 2410, "蠻": 2411, "耗": 2412, "藤": 2413, "奮": 2414, "憲": 2415, "謀": 2416, "霍": 2417, "渡": 2418, "瓶": 2419, "熊": 2420, "囉": 2421, "飽": 2422, "薄": 2423, "漂": 2424, "乏": 2425, "俱": 2426, "趨": 2427, "戒": 2428, "漲": 2429, "萄": 2430, "寸": 2431, "嫌": 2432, "淚": 2433, "迅": 2434, "尿": 2435, "逛": 2436, "填": 2437, "棲": 2438, "搬": 2439, "妮": 2440, "宋": 2441, "振": 2442, "寒": 2443, "乃": 2444, "曉": 2445, "鰭": 2446, "徹": 2447, "跌": 2448, "殖": 2449, "\u0006": 2450, "扮": 2451, "晉": 2452, "仰": 2453, "嚇": 2454, ";": 2455, "淺": 2456, "趙": 2457, "ー": 2458, "腹": 2459, "爽": 2460, "拆": 2461, "膽": 2462, "汗": 2463, "穆": 2464, "苗": 2465, "縱": 2466, "=": 2467, "溪": 2468, "膜": 2469, "償": 2470, "躍": 2471, "賺": 2472, "頒": 2473, "污": 2474, "擦": 2475, "鹽": 2476, "濱": 2477, "勤": 2478, "\\": 2479, "廷": 2480, "肩": 2481, "昌": 2482, "廉": 2483, "暢": 2484, "邁": 2485, "贈": 2486, "\u0005": 2487, "轄": 2488, "瘋": 2489, "粗": 2490, "唇": 2491, "逝": 2492, "祭": 2493, "煮": 2494, "奉": 2495, "噴": 2496, "獵": 2497, "耀": 2498, "貢": 2499, "籌": 2500, "厲": 2501, "%": 2502, "嘛": 2503, "獄": 2504, "哦": 2505, "琳": 2506, "佐": 2507, "臣": 2508, "櫻": 2509, "朵": 2510, "厭": 2511, "礦": 2512, "騙": 2513, "滋": 2514, "蛇": 2515, "壤": 2516, "霸": 2517, "脆": 2518, "泳": 2519, "爵": 2520, "廈": 2521, "騰": 2522, "怨": 2523, " ": 2524, "腐": 2525, "辭": 2526, "爲": 2527, "殿": 2528, "猛": 2529, "瞬": 2530, "秦": 2531, "眠": 2532, "捐": 2533, "肺": 2534, "姿": 2535, "爬": 2536, "ン": 2537, "悠": 2538, "柱": 2539, "碩": 2540, "喪": 2541, "碳": 2542, "帥": 2543, "椅": 2544, "郭": 2545, "拓": 2546, "姻": 2547, "脅": 2548, "腸": 2549, "袖": 2550, "‧": 2551, "逼": 2552, "逆": 2553, "赤": 2554, "瑟": 2555, "鋪": 2556, "浩": 2557, "貫": 2558, "→": 2559, "怖": 2560, "牧": 2561, "閣": 2562, "涯": 2563, "恨": 2564, "賀": 2565, "貧": 2566, "遜": 2567, "遵": 2568, "陶": 2569, "肝": 2570, "呂": 2571, "擠": 2572, "猜": 2573, "罵": 2574, "賢": 2575, "丈": 2576, "崗": 2577, "宙": 2578, "盜": 2579, "廟": 2580, "揭": 2581, "肚": 2582, "艇": 2583, "惑": 2584, "慕": 2585, "龐": 2586, "轟": 2587, "扭": 2588, "蔣": 2589, "喊": 2590, "胃": 2591, "咬": 2592, "崇": 2593, "拳": 2594, "滴": 2595, "狼": 2596, "胖": 2597, "凝": 2598, "頗": 2599, "嫩": 2600, "遙": 2601, "碗": 2602, "鳴": 2603, "繳": 2604, "灘": 2605, "蕭": 2606, "呵": 2607, "鹿": 2608, "吻": 2609, "荒": 2610, "衰": 2611, "穌": 2612, "咪": 2613, "の": 2614, "#": 2615, "邪": 2616, "彰": 2617, "燕": 2618, "蝶": 2619, "聰": 2620, "漏": 2621, "逢": 2622, "芝": 2623, "錫": 2624, "盾": 2625, "擋": 2626, "慰": 2627, "嬰": 2628, "炒": 2629, "祥": 2630, "吞": 2631, "醇": 2632, "姑": 2633, "粒": 2634, "蕾": 2635, "丘": 2636, "惱": 2637, "艘": 2638, "坊": 2639, "狠": 2640, "罕": 2641, "傻": 2642, "杉": 2643, "腫": 2644, "妖": 2645, "淘": 2646, "嗯": 2647, "頸": 2648, "刪": 2649, "郡": 2650, "蜂": 2651, "栽": 2652, "棟": 2653, "溶": 2654, "蝦": 2655, "披": 2656, "驟": 2657, "悔": 2658, "懼": 2659, "歉": 2660, "虧": 2661, "疏": 2662, "撫": 2663, "戈": 2664, "妨": 2665, "潘": 2666, "圳": 2667, "宴": 2668, "籠": 2669, "魅": 2670, "噸": 2671, "唷": 2672, "慎": 2673, "臂": 2674, "喚": 2675, "稀": 2676, "膩": 2677, "畔": 2678, "辯": 2679, "欺": 2680, "恰": 2681, "趁": 2682, "憤": 2683, "孝": 2684, "砲": 2685, "崎": 2686, "奴": 2687, "罷": 2688, "幽": 2689, "鴨": 2690, "吵": 2691, "芒": 2692, "鄧": 2693, "夕": 2694, "裔": 2695, """: 2696, "埋": 2697, "瘦": 2698, "躲": 2699, "粹": 2700, "穴": 2701, "玲": 2702, "誘": 2703, "着": 2704, "乖": 2705, "昏": 2706, "A": 2707, "勃": 2708, "浙": 2709, "埔": 2710, "兔": 2711, "悟": 2712, "斜": 2713, "伐": 2714, "踐": 2715, "叛": 2716, "旨": 2717, "赴": 2718, "詹": 2719, "羞": 2720, "敲": 2721, "仲": 2722, "紗": 2723, "亨": 2724, "妥": 2725, "峽": 2726, "龜": 2727, "晴": 2728, "賭": 2729, "晃": 2730, "悶": 2731, "町": 2732, "漁": 2733, "隸": 2734, "○": 2735, "嬌": 2736, "裕": 2737, "肪": 2738, "催": 2739, "’": 2740, "犬": 2741, "屈": 2742, "▲": 2743, "廊": 2744, "臭": 2745, "昭": 2746, "巷": 2747, "疲": 2748, "雀": 2749, "氫": 2750, "陵": 2751, "呆": 2752, "淫": 2753, "颶": 2754, "蒸": 2755, "蔬": 2756, "鴻": 2757, "祂": 2758, "玄": 2759, "菊": 2760, "肅": 2761, "涅": 2762, "撲": 2763, "倆": 2764, "銘": 2765, "魏": 2766, "腔": 2767, "綿": 2768, "ル": 2769, "<": 2770, "押": 2771, "暨": 2772, "囊": 2773, "膀": 2774, "寓": 2775, "嫁": 2776, "1": 2777, "趟": 2778, "壘": 2779, "摘": 2780, "斥": 2781, "桂": 2782, "銳": 2783, "陀": 2784, "忌": 2785, "謹": 2786, "吋": 2787, "腎": 2788, "筋": 2789, "薇": 2790, "翔": 2791, "ス": 2792, "坪": 2793, "曬": 2794, "扁": 2795, "徽": 2796, "卵": 2797, "遣": 2798, "禍": 2799, "悄": 2800, "甸": 2801, "遼": 2802, "阪": 2803, "碑": 2804, "曹": 2805, "勸": 2806, "糟": 2807, "暑": 2808, "﹐": 2809, "訥": 2810, "矛": 2811, "渴": 2812, "禱": 2813, "艙": 2814, "酥": 2815, "緬": 2816, "泊": 2817, "哀": 2818, "祈": 2819, "訝": 2820, "霜": 2821, "�": 2822, "漠": 2823, "崩": 2824, "謙": 2825, "欠": 2826, "苯": 2827, "碧": 2828, "蹈": 2829, "椎": 2830, "裙": 2831, "玫": 2832, "諧": 2833, "俠": 2834, "珊": 2835, "騷": 2836, "脊": 2837, "墓": 2838, "糧": 2839, "N": 2840, "氯": 2841, "翠": 2842, "陌": 2843, "翁": 2844, "★": 2845, "卑": 2846, "裸": 2847, "汰": 2848, "耕": 2849, "é": 2850, "憐": 2851, "»": 2852, "咒": 2853, "坑": 2854, "擅": 2855, "履": 2856, "寂": 2857, "捉": 2858, "瘤": 2859, "イ": 2860, "浸": 2861, "馮": 2862, "溜": 2863, "窩": 2864, "巫": 2865, "磚": 2866, "翅": 2867, "賜": 2868, "▼": 2869, "撰": 2870, "牲": 2871, "盆": 2872, "穎": 2873, "郊": 2874, "皺": 2875, "廁": 2876, "歧": 2877, "狄": 2878, "琪": 2879, "墊": 2880, "扇": 2881, "隧": 2882, "諒": 2883, "坎": 2884, "熙": 2885, "瑰": 2886, "旬": 2887, "毅": 2888, "姬": 2889, "灑": 2890, "菩": 2891, "晰": 2892, "姨": 2893, "惟": 2894, "弘": 2895, "賊": 2896, "摔": 2897, "肖": 2898, "•": 2899, "燥": 2900, "瞄": 2901, "馨": 2902, "椒": 2903, "磯": 2904, "墜": 2905, "豫": 2906, "軒": 2907, "ラ": 2908, "×": 2909, "瑜": 2910, "葬": 2911, "詐": 2912, "侯": 2913, "禪": 2914, "楓": 2915, "牢": 2916, "誓": 2917, "喉": 2918, "挪": 2919, "訟": 2920, "纏": 2921, "躺": 2922, "鯉": 2923, "嶼": 2924, "拾": 2925, "蟹": 2926, "嘿": 2927, "蔥": 2928, "掙": 2929, "啤": 2930, "稻": 2931, "惹": 2932, "盼": 2933, "蒼": 2934, "株": 2935, "嶺": 2936, "潰": 2937, "腕": 2938, "奢": 2939, "踢": 2940, "莓": 2941, "梵": 2942, "扯": 2943, "い": 2944, "削": 2945, "臥": 2946, "澡": 2947, "艱": 2948, "盯": 2949, "ト": 2950, "鮑": 2951, "暈": 2952, "哇": 2953, "釣": 2954, "祕": 2955, "{": 2956, "粵": 2957, "舟": 2958, "捏": 2959, "●": 2960, "ア": 2961, "匈": 2962, "漆": 2963, "瞧": 2964, "帆": 2965, "鵝": 2966, "淑": 2967, "傘": 2968, "趴": 2969, "誼": 2970, "奎": 2971, "兌": 2972, "劣": 2973, "橘": 2974, "喻": 2975, "雌": 2976, "顫": 2977, "恭": 2978, "膏": 2979, "襪": 2980, "ク": 2981, "攀": 2982, "憾": 2983, "渾": 2984, "汪": 2985, "夷": 2986, "邱": 2987, "倡": 2988, "洩": 2989, "犧": 2990, "硫": 2991, "狐": 2992, "泌": 2993, "勉": 2994, "茂": 2995, "卿": 2996, "笨": 2997, "辱": 2998, "屠": 2999, "歇": 3000, "茵": 3001, "綫": 3002, "僱": 3003, "彥": 3004, "酶": 3005, "吾": 3006, "芙": 3007, "闖": 3008, "狹": 3009, "妃": 3010, "}": 3011, "剝": 3012, "衷": 3013, "リ": 3014, "莖": 3015, "畏": 3016, "臀": 3017, "ʁ": 3018, "崔": 3019, "怡": 3020, "濫": 3021, "褐": 3022, "菇": 3023, "釀": 3024, "0": 3025, "烯": 3026, "う": 3027, "瓣": 3028, "喀": 3029, "爪": 3030, "鼎": 3031, "逮": 3032, "貞": 3033, "飼": 3034, "樞": 3035, "ん": 3036, "ɛ": 3037, "妍": 3038, "廖": 3039, "烹": 3040, "棘": 3041, "蛙": 3042, "鹼": 3043, "窄": 3044, "僑": 3045, "袁": 3046, "煤": 3047, "挫": 3048, "儒": 3049, "秩": 3050, "潭": 3051, "塌": 3052, "冥": 3053, "哼": 3054, "舖": 3055, "咱": 3056, "啥": 3057, "鯨": 3058, "丙": 3059, "矮": 3060, "欽": 3061, "澎": 3062, "し": 3063, "棕": 3064, "︰": 3065, "欖": 3066, "洽": 3067, "謊": 3068, "虐": 3069, "癮": 3070, "缸": 3071, "罹": 3072, "聆": 3073, "侍": 3074, "矽": 3075, "澄": 3076, "宰": 3077, "懲": 3078, "ッ": 3079, "竊": 3080, "澀": 3081, "癢": 3082, "E": 3083, "磷": 3084, "陝": 3085, "竭": 3086, "烘": 3087, "か": 3088, "橡": 3089, "辰": 3090, "秉": 3091, "屯": 3092, "P": 3093, "⋯": 3094, "遂": 3095, "蝴": 3096, "尬": 3097, "燦": 3098, "婷": 3099, "輻": 3100, "凸": 3101, "‘": 3102, "砍": 3103, "み": 3104, "蠢": 3105, "揉": 3106, "愣": 3107, "髓": 3108, "饒": 3109, "杏": 3110, "摧": 3111, "檸": 3112, "宛": 3113, "撼": 3114, "潢": 3115, "稚": 3116, "濤": 3117, "燙": 3118, "匆": 3119, "鴉": 3120, "2": 3121, "鱗": 3122, "逗": 3123, "寨": 3124, "鶴": 3125, "瞪": 3126, "蚊": 3127, "斬": 3128, "佑": 3129, "藻": 3130, "掀": 3131, "脾": 3132, "耍": 3133, "坂": 3134, "熬": 3135, "諷": 3136, "檬": 3137, "壹": 3138, "豹": 3139, "尷": 3140, "伽": 3141, "睜": 3142, "愧": 3143, "瀨": 3144, "蘆": 3145, "嗚": 3146, "鈣": 3147, "驕": 3148, "剎": 3149, "黛": 3150, "裹": 3151, "\u0004": 3152, "シ": 3153, "吟": 3154, "砸": 3155, "僧": 3156, "橄": 3157, "淵": 3158, "咳": 3159, "き": 3160, "а": 3161, "さ": 3162, "歪": 3163, "吼": 3164, "◎": 3165, "烷": 3166, "媚": 3167, "ド": 3168, "茫": 3169, "頌": 3170, "瓷": 3171, "な": 3172, "詭": 3173, "姚": 3174, "蝕": 3175, "鍛": 3176, "※": 3177, "ロ": 3178, "蝠": 3179, "匪": 3180, "敞": 3181, "湘": 3182, "弓": 3183, "炫": 3184, "絨": 3185, "恥": 3186, "肆": 3187, "躁": 3188, "氟": 3189, "嘻": 3190, "磅": 3191, "焰": 3192, "枕": 3193, "嘲": 3194, "о": 3195, "纜": 3196, "爹": 3197, "恕": 3198, "旭": 3199, "撕": 3200, "羨": 3201, "甩": 3202, "鯊": 3203, "攔": 3204, "詮": 3205, "醋": 3206, "桐": 3207, "": 3208, "タ": 3209, "滲": 3210, "堵": 3211, "煞": 3212, "寞": 3213, "汙": 3214, "滯": 3215, "蕉": 3216, "辜": 3217, "梗": 3218, "哺": 3219, "棚": 3220, "奠": 3221, "ま": 3222, "魁": 3223, "炭": 3224, "敷": 3225, "睫": 3226, "靖": 3227, "飆": 3228, "り": 3229, "斐": 3230, "滬": 3231, "〕": 3232, "頰": 3233, "撿": 3234, "祿": 3235, "と": 3236, "掠": 3237, "諜": 3238, "譚": 3239, "坤": 3240, "葵": 3241, "寡": 3242, "た": 3243, "禽": 3244, "卦": 3245, "妄": 3246, "傍": 3247, "〔": 3248, "賃": 3249, "緯": 3250, "渦": 3251, "跪": 3252, "苑": 3253, "霞": 3254, "凜": 3255, "凰": 3256, "礁": 3257, "唉": 3258, "凹": 3259, "̃": 3260, "〞": 3261, "脖": 3262, "舅": 3263, "庸": 3264, "袍": 3265, "鵬": 3266, "紡": 3267, "昔": 3268, "贖": 3269, "軀": 3270, "愁": 3271, "酮": 3272, "煌": 3273, "愚": 3274, "穗": 3275, "釘": 3276, "墾": 3277, "蔓": 3278, "霖": 3279, "婉": 3280, "鈔": 3281, "皂": 3282, "叮": 3283, "蟻": 3284, "拌": 3285, "蕨": 3286, "麟": 3287, "拯": 3288, "菁": 3289, "抄": 3290, "*": 3291, "カ": 3292, "菱": 3293, "ㄧ": 3294, "締": 3295, "蘊": 3296, "る": 3297, "眨": 3298, "尹": 3299, "℃": 3300, "3": 3301, "淹": 3302, "匠": 3303, "薰": 3304, "奕": 3305, "娶": 3306, "芋": 3307, "仗": 3308, "墮": 3309, "珀": 3310, "屢": 3311, "丫": 3312, "呎": 3313, "嘯": 3314, "頃": 3315, "墅": 3316, "レ": 3317, "勻": 3318, "淪": 3319, "掏": 3320, "翌": 3321, "泄": 3322, "豈": 3323, "壺": 3324, "昧": 3325, "豚": 3326, "頑": 3327, "枯": 3328, "貶": 3329, "慨": 3330, "輿": 3331, "酯": 3332, "瞞": 3333, "檳": 3334, "瑤": 3335, "こ": 3336, "冕": 3337, "瑩": 3338, "フ": 3339, "扔": 3340, "ジ": 3341, "蜥": 3342, "嵐": 3343, "お": 3344, "椰": 3345, "焚": 3346, "刃": 3347, "屑": 3348, "冤": 3349, "蒜": 3350, "氮": 3351, "鑄": 3352, "齋": 3353, "廿": 3354, "蓉": 3355, "眸": 3356, "犀": 3357, "〝": 3358, "肋": 3359, "拚": 3360, "沼": 3361, "囚": 3362, "鉛": 3363, "あ": 3364, "甄": 3365, "舔": 3366, "迄": 3367, "蝙": 3368, "く": 3369, "畜": 3370, "マ": 3371, "牡": 3372, "腥": 3373, "聳": 3374, "嚼": 3375, "閩": 3376, "梳": 3377, "蹲": 3378, "α": 3379, "弊": 3380, "沐": 3381, "匿": 3382, "矯": 3383, "殷": 3384, "淮": 3385, "崛": 3386, "撇": 3387, "鱸": 3388, "鈉": 3389, "詠": 3390, "粥": 3391, "|": 3392, "拱": 3393, "賤": 3394, "瀑": 3395, "鈞": 3396, "鎊": 3397, "ら": 3398, "硝": 3399, "撈": 3400, "俯": 3401, "譴": 3402, "瀕": 3403, "澈": 3404, "醯": 3405, "繡": 3406, "晟": 3407, "棵": 3408, "侈": 3409, "癡": 3410, "狸": 3411, "O": 3412, "轎": 3413, "甫": 3414, "哉": 3415, "睿": 3416, "譬": 3417, "ち": 3418, "俘": 3419, "禾": 3420, "沛": 3421, "и": 3422, "萃": 3423, "俏": 3424, "噗": 3425, "霆": 3426, "崖": 3427, "餃": 3428, "雯": 3429, "禧": 3430, "魄": 3431, "闡": 3432, "鋰": 3433, "峻": 3434, "燉": 3435, "産": 3436, "泣": 3437, "キ": 3438, "尉": 3439, "痘": 3440, "覓": 3441, "咀": 3442, "誦": 3443, "漾": 3444, "繽": 3445, "酌": 3446, "+": 3447, "篷": 3448, "彗": 3449, "肇": 3450, "旱": 3451, "柬": 3452, "鯰": 3453, "燭": 3454, "е": 3455, "塚": 3456, "コ": 3457, "ィ": 3458, "嫂": 3459, ">": 3460, "搏": 3461, "綽": 3462, "倘": 3463, "賄": 3464, "鞭": 3465, "搓": 3466, "頜": 3467, "咧": 3468, "茹": 3469, "醛": 3470, "娥": 3471, "妒": 3472, "鉀": 3473, "鞏": 3474, "翹": 3475, "疹": 3476, "蹄": 3477, "餡": 3478, "冀": 3479, "僚": 3480, "癱": 3481, "荊": 3482, "邵": 3483, "オ": 3484, "妞": 3485, "☆": 3486, "裴": 3487, "瀾": 3488, "倚": 3489, "骸": 3490, "趾": 3491, "翡": 3492, "嬤": 3493, "ナ": 3494, "ɔ": 3495, "哎": 3496, "閻": 3497, "β": 3498, "瑣": 3499, "溺": 3500, "鰻": 3501, "嘟": 3502, "糙": 3503, "錐": 3504, "倦": 3505, "萍": 3506, "媛": 3507, "骼": 3508, "エ": 3509, "虞": 3510, "筍": 3511, "嘔": 3512, "説": 3513, "悍": 3514, "竄": 3515, "剔": 3516, "秤": 3517, "楠": 3518, "н": 3519, "靴": 3520, "摯": 3521, "噬": 3522, "壟": 3523, "蔚": 3524, "鑼": 3525, "р": 3526, "煥": 3527, "縛": 3528, "繹": 3529, "鑲": 3530, "膳": 3531, "嚨": 3532, "綻": 3533, "啪": 3534, "晤": 3535, "顱": 3536, "テ": 3537, "仕": 3538, "殲": 3539, "婭": 3540, "膛": 3541, "碘": 3542, "攬": 3543, "夯": 3544, "恍": 3545, "〜": 3546, "曰": 3547, "咐": 3548, "猩": 3549, "ウ": 3550, "喃": 3551, "隙": 3552, "阱": 3553, "廓": 3554, "暮": 3555, "喵": 3556, "吶": 3557, "5": 3558, "焙": 3559, "嘖": 3560, "狙": 3561, "鶯": 3562, "畝": 3563, "歹": 3564, "鸚": 3565, "萎": 3566, "閥": 3567, "懇": 3568, "眷": 3569, "樁": 3570, "咕": 3571, "蕃": 3572, "紳": 3573, "謬": 3574, "囑": 3575, "憩": 3576, "嶄": 3577, "炳": 3578, "庚": 3579, "鄂": 3580, "駿": 3581, "簧": 3582, "悼": 3583, "「": 3584, "啞": 3585, "耿": 3586, "祀": 3587, "è": 3588, "狩": 3589, "湛": 3590, "櫥": 3591, "豎": 3592, "飪": 3593, "幟": 3594, "瞳": 3595, "サ": 3596, "緝": 3597, "淳": 3598, "ミ": 3599, "ニ": 3600, "墳": 3601, "詛": 3602, "戳": 3603, "倩": 3604, "瞎": 3605, "瑚": 3606, "娟": 3607, "兜": 3608, "堯": 3609, "窯": 3610, "丞": 3611, "斌": 3612, "梓": 3613, "茜": 3614, "ə": 3615, "扛": 3616, "蘚": 3617, "」": 3618, "劈": 3619, "曠": 3620, "螞": 3621, "噢": 3622, "ㄟ": 3623, "│": 3624, "瀉": 3625, "囂": 3626, "綾": 3627, "酚": 3628, "鏽": 3629, "柚": 3630, "鋅": 3631, "疇": 3632, "暱": 3633, "も": 3634, "喧": 3635, "訣": 3636, "嗜": 3637, "摟": 3638, "寇": 3639, "濁": 3640, "赦": 3641, "熔": 3642, "侏": 3643, "扳": 3644, "疤": 3645, "拭": 3646, "蛤": 3647, "◆": 3648, "襄": 3649, "悚": 3650, "哆": 3651, "♥": 3652, "ム": 3653, "萱": 3654, "棠": 3655, "曦": 3656, "渝": 3657, "嗅": 3658, "с": 3659, "祐": 3660, "ゆ": 3661, "莞": 3662, "嚷": 3663, "鯛": 3664, "嗓": 3665, "彬": 3666, "陋": 3667, "鎂": 3668, "爍": 3669, "閔": 3670, "雁": 3671, "4": 3672, "曖": 3673, "絞": 3674, "捍": 3675, "バ": 3676, "蠅": 3677, "綢": 3678, "つ": 3679, "└": 3680, "蟬": 3681, "窟": 3682, "斃": 3683, "俐": 3684, "鋸": 3685, "蛾": 3686, "哨": 3687, "冉": 3688, "嫉": 3689, "茱": 3690, "↓": 3691, "猿": 3692, "幌": 3693, "醣": 3694, "豁": 3695, "郝": 3696, "嚕": 3697, "∼": 3698, "戊": 3699, "鞍": 3700, "プ": 3701, "滄": 3702, "®": 3703, "D": 3704, "凈": 3705, "к": 3706, "篤": 3707, "睞": 3708, "垮": 3709, "壢": 3710, "攏": 3711, "肛": 3712, "寢": 3713, "琦": 3714, "邨": 3715, "芥": 3716, "餚": 3717, "■": 3718, "喲": 3719, "咦": 3720, "は": 3721, "綺": 3722, "羥": 3723, "メ": 3724, "懈": 3725, "揪": 3726, "絮": 3727, "デ": 3728, "ャ": 3729, "垣": 3730, "厥": 3731, "釁": 3732, "橢": 3733, "岐": 3734, "麒": 3735, "汐": 3736, "ブ": 3737, "呻": 3738, "毋": 3739, "阮": 3740, "亥": 3741, "に": 3742, "棗": 3743, "グ": 3744, "﹕": 3745, "釜": 3746, "C": 3747, "[": 3748, "ュ": 3749, "暇": 3750, "盎": 3751, "藩": 3752, "黴": 3753, "鈍": 3754, "斧": 3755, "鑫": 3756, "в": 3757, "紓": 3758, "]": 3759, "漬": 3760, "霹": 3761, "妓": 3762, "柑": 3763, "瑋": 3764, "吩": 3765, "憊": 3766, "曜": 3767, "牟": 3768, "枉": 3769, "嬸": 3770, "す": 3771, "冶": 3772, "蜀": 3773, "栓": 3774, "沁": 3775, "惶": 3776, "虔": 3777, "踴": 3778, "↑": 3779, "が": 3780, "聶": 3781, "−": 3782, "苛": 3783, "毆": 3784, "懺": 3785, "搗": 3786, "嗽": 3787, "雛": 3788, "泵": 3789, "淆": 3790, "荃": 3791, "咯": 3792, "眶": 3793, "卒": 3794, "呃": 3795, "靂": 3796, "茉": 3797, "溴": 3798, "絆": 3799, "え": 3800, "ا": 3801, "8": 3802, "樺": 3803, "顎": 3804, "て": 3805, "や": 3806, "昊": 3807, "瀟": 3808, "咲": 3809, "竿": 3810, "岑": 3811, "抒": 3812, "熄": 3813, "ダ": 3814, "沮": 3815, "芹": 3816, "じ": 3817, "ハ": 3818, "誡": 3819, "竣": 3820, "挾": 3821, "鵡": 3822, "姥": 3823, "<": 3824, "虜": 3825, "盞": 3826, "暉": 3827, "幢": 3828, "逕": 3829, "眺": 3830, "褚": 3831, "灼": 3832, "煽": 3833, "卉": 3834, "噓": 3835, "チ": 3836, "禿": 3837, "6": 3838, "芮": 3839, "S": 3840, "焊": 3841, "稠": 3842, "伶": 3843, "撓": 3844, "炙": 3845, "瘡": 3846, "凳": 3847, "諱": 3848, "硼": 3849, "ろ": 3850, "氰": 3851, "邸": 3852, "苷": 3853, "荔": 3854, "韶": 3855, "毓": 3856, "肘": 3857, "瘓": 3858, "л": 3859, "鰓": 3860, "黯": 3861, "嘎": 3862, "裘": 3863, "遏": 3864, "9": 3865, "拙": 3866, "惕": 3867, "胚": 3868, "撩": 3869, "蠶": 3870, "パ": 3871, "舶": 3872, "俞": 3873, "汝": 3874, "晝": 3875, "á": 3876, "墟": 3877, "兮": 3878, "鵑": 3879, "馴": 3880, "ノ": 3881, "珈": 3882, "稜": 3883, "嗣": 3884, "陛": 3885, "7": 3886, "嗆": 3887, "竅": 3888, "鷗": 3889, "溼": 3890, "棺": 3891, "っ": 3892, "鍍": 3893, "錘": 3894, "樟": 3895, "抉": 3896, "―": 3897, "靚": 3898, "侮": 3899, "籽": 3900, "狡": 3901, "孵": 3902, "モ": 3903, "斂": 3904, "熾": 3905, "よ": 3906, "胱": 3907, "&": 3908, "懊": 3909, "т": 3910, "噶": 3911, "拂": 3912, "遴": 3913, "佬": 3914, "柵": 3915, "喙": 3916, "陡": 3917, "祠": 3918, "叨": 3919, "孜": 3920, "檀": 3921, "ワ": 3922, "滕": 3923, "隅": 3924, "澆": 3925, "隋": 3926, "糞": 3927, "羚": 3928, "憫": 3929, "怯": 3930, "祺": 3931, "鈾": 3932, "ó": 3933, "鈦": 3934, "咎": 3935, "邑": 3936, "擄": 3937, "鞘": 3938, "ˈ": 3939, "嗨": 3940, "迺": 3941, "雍": 3942, "捆": 3943, "ɑ": 3944, "靡": 3945, "ㄚ": 3946, "啶": 3947, "阜": 3948, "疚": 3949, "盔": 3950, "彪": 3951, "峙": 3952, "樊": 3953, "B": 3954, "堊": 3955, "侃": 3956, "呦": 3957, "熒": 3958, "漱": 3959, "磺": 3960, "儉": 3961, "寅": 3962, "繆": 3963, "|": 3964, "倪": 3965, "徙": 3966, "窘": 3967, "毗": 3968, "砌": 3969, "鏢": 3970, "瘍": 3971, "`": 3972, "瞇": 3973, "咩": 3974, "兢": 3975, "皓": 3976, "鉻": 3977, "鎧": 3978, "ビ": 3979, "耽": 3980, "竇": 3981, "峇": 3982, "憎": 3983, "鄙": 3984, "愜": 3985, "敖": 3986, "ü": 3987, "朔": 3988, "禹": 3989, "褻": 3990, "栩": 3991, "葫": 3992, "揀": 3993, "岔": 3994, "鱂": 3995, "緋": 3996, "饅": 3997, "垢": 3998, "眩": 3999, "饗": 4000, "ガ": 4001, "楷": 4002, "炬": 4003, "綏": 4004, "朧": 4005, "啃": 4006, "烴": 4007, "磊": 4008, "靶": 4009, "羈": 4010, "啓": 4011, "琵": 4012, "怠": 4013, "け": 4014, "躬": 4015, "滔": 4016, "噩": 4017, "慷": 4018, "弛": 4019, "堀": 4020, "隕": 4021, "蘑": 4022, "汞": 4023, "衞": 4024, "縷": 4025, "ズ": 4026, "螂": 4027, "蝸": 4028, "寥": 4029, "欸": 4030, "瀚": 4031, "蕪": 4032, "腓": 4033, "庶": 4034, "吡": 4035, "=": 4036, "祁": 4037, "梧": 4038, "錚": 4039, "霾": 4040, "孢": 4041, "薔": 4042, "忱": 4043, "れ": 4044, "掰": 4045, "渺": 4046, "™": 4047, "瞰": 4048, "←": 4049, "T": 4050, "芷": 4051, "詔": 4052, "夭": 4053, "宸": 4054, "滇": 4055, "戟": 4056, "榕": 4057, "曙": 4058, "謗": 4059, "蚤": 4060, "僻": 4061, "兀": 4062, "沌": 4063, "朽": 4064, "揍": 4065, "瞥": 4066, "涮": 4067, "閨": 4068, "鷺": 4069, "鐸": 4070, "癲": 4071, "鄒": 4072, "吮": 4073, "滌": 4074, "駱": 4075, "烙": 4076, "わ": 4077, "孽": 4078, "桔": 4079, "彤": 4080, "禎": 4081, "笠": 4082, "睦": 4083, "戮": 4084, "鑿": 4085, "胳": 4086, "榻": 4087, "‎": 4088, "懾": 4089, "鞠": 4090, "榨": 4091, "臼": 4092, "苞": 4093, "焉": 4094, "轍": 4095}
data/dict/lattice_lexicon.json ADDED
The diff for this file is too large to render. See raw diff
 
data/dict/rules/must_convert.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ 㐷㐽㑇㑈㑔㑩㓆㓥㓰㔉㖊㖞㘎㚯㛀㛟㛠㛣㛤㛿㟆㟜㟥㡎㤘㤽㥪㧏㧐㧑㧟㧰㨫㭎㭏㭣㭤㭴㱩㱮㲿㳔㳕㳠㳡㳢㳽㴋㶉㶶㶽㺍㻅㻏㻘䀥䁖䂵䃅䅉䅟䅪䇲䉤䌶䌷䌸䌹䌺䌻䌼䌽䌾䌿䍀䍁䍠䎬䏝䑽䓓䓕䓖䓨䗖䘛䘞䙊䙌䙓䜣䜤䜥䜧䜩䝙䞌䞍䞎䞐䟢䢀䢁䢂䥺䥽䥾䥿䦀䦁䦂䦃䦅䦆䦶䦷䩄䭪䯃䯄䯅䲝䲞䲟䲠䲡䲢䲣䴓䴔䴕䴖䴗䴘䴙䶮与专业丛东丝丢两严丧个临为丽举么义乌乐乔习乡书买乱争亏亚产亩亲亵亸亿仅从仑仓仪们众优会伛伞伟传伡伣伤伥伦伧伪伫体佥侠侣侥侦侧侨侩侪侬侭俣俦俨俩俪俫俭债倾偬偻偾偿傤傥傧储傩儿兑兖兰关兴兹养兽冁内冈册写军农冯冲决况冻净凄凉减凑凛凤凫凭凯击凿刍刘则刚创删别刬刭刹刽刾刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勚匀匦匮区医华协单卖卢卤卧卫却卺厅历厉压厌厍厐厕厢厣厦厨厩厮县叁参叆叇双发变叙叠号叹叽吓吕吗吨听启吴呐呒呓呕呖呗员呙呛呜咏咙咛咝咤响哑哒哓哔哕哗哙哜哝哟唛唝唠唡唢唤啧啬啭啮啯啰啴啸喷喽喾嗫嗳嘘嘤嘱噜嚣团园囱围囵国图圆圣圹场坏块坚坛坜坝坞坟坠垄垅垆垒垦垩垫垭垯垱垲垴埘埙埚堑堕塆墙壮声壳壶壸处备复够头夹夺奁奂奋奖奥妆妇妈妩妪妫姗姹娄娅娆娇娈娱娲娴婳婴婵婶媪媭嫒嫔嫱嬷孙学孪宁宝实宠审宪宫宽宾寝对寻导寿将尔尘尝尧尴尽层屃屉届属屡屦屿岁岂岖岗岘岚岛岭岽岿峃峄峡峣峤峥峦峰崂崃崄崭嵘嵚嵝巅巩巯币帅师帏帐帜带帧帮帱帻帼幂并庄庆床庐庑库应庙庞废庼廪开异弃弑张弥弪弯弹强归当录彟彦彨彻径徕忆忏忧忾怀态怂怃怄怅怆怜总怼怿恋恒恳恶恸恹恺恻恼恽悦悫悬悭悮悯惊惧惨惩惫惬惭惮惯愠愤愦慑慭懑懒懔戆戋戏戗战戬戯户扑执扩扪扫扬扰抚抛抟抠抡抢护报担拟拢拣拥拦拧拨择挚挛挜挝挞挟挠挡挢挣挤挥挦捝捞损捡换捣掳掴掷掸掺掼揽揾揿搀搁搂搄搅携摄摅摆摇摈摊撄撑撵撷撸撺擜擞攒敌敚敛敩数斋斓斩断无旧时旷旸昙昵昼昽显晋晒晓晔晕晖暂暅暧术机杀杂权条来杨杩构枞枢枣枥枧枨枪枫枭柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桠桡桢档桤桥桦桧桨桩桪梦梼梾梿检棁棂椁椝椟椠椢椤椫椭椮楼榄榅榇榈榉榝槚槛槟槠横樯樱橥橱橹橼檩欢欤欧歼殁殇残殒殓殚殡殴毁毂毕毙毡毵毶氇气氢氩氲汇汉汤汹沄沟没沣沤沥沦沧沨沩沪泞泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涚涛涝涞涟涠涡涢涣涤润涧涨涩渊渌渍渎渐渑渔渖渗温湾湿溁溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪潆潇潋潍潜潴澛澜濑濒灏灭灯灵灶灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烦烧烨烩烫烬热焕焖焘煴爱爷牍牦牵牺犊状犷犸犹狈狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珐珑珰珲琎琏琐琼瑶瑷瑸璎瓒瓮瓯电画畅畴疖疗疟疠疡疬疭疮疯疱疴痈痉痒痖痨痪痫痴瘅瘆瘗瘘瘪瘫瘾瘿癞癣癫皑皱皲盏盐监盖盗盘眍眦眬睁睐睑瞆瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硕硖硗硙硚硵硷碍碛碜碱礼祃祎祢祯祷祸禀禄禅离秃秆秘积称秽秾稆税稣稳穑穞穷窃窍窎窑窜窝窥窦窭竖竞笃笋笔笕笺笼笾筚筛筜筝筹筼签筿简箓箦箧箨箩箪箫篑篓篮篯篱簖籁籴类籼粜粝粤粪粮粽糁糇糍紧絷緼縆纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡群翘翙翚耢耧耸耻聂聋职聍联聩聪肃肠肤肮肴肾肿胀胁胆胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腘腭腻腼腽腾膑臜舆舣舰舱舻艰艳艺节芈芗芜芦苁苇苈苋苌苍苎苏茎茏茑茔茕茧荆荙荚荛荜荝荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒀蒇蒉蒋蒌蒏蓝蓟蓠蓣蓥蓦蔂蔷蔹蔺蔼蕰蕲蕴薮藓藴蘖虏虑虚虬虮虱虽虾虿蚀蚁蚂蚃蚕蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蝇蝈蝉蝼蝾螀螨蟏衅衔补衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯訚詟誉誊讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯��谱谲谳谴谵谶豮贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赪赵赶趋趱趸跃跄跞践跶跷跸跹跻踌踪踬踯蹑蹒蹰蹿躏躜躯輼车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辩辫边辽达迁过迈运还这进远违连迟迩迳迹选逊递逦逻遗遥邓邝邬邮邹邺邻郏郐郑郓郦郧郸酂酝酦酱酽酾酿醖释鉴銮錾钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶长门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陦陧陨险随隐隶隽难雇雏雠雳雾霁霉霡霭靓靔静靥鞑鞒鞯鞲韦韧韨韩韪韫韬韵页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓鬶魇魉鱼鱽鱾鱿鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳚鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹴鹾麦麸麹麺麽黄黉黡黩黪黾鼋鼌鼍鼹齐齑齿龀龁龂龃龄龅龆龇龈龉龊龋龌龙龚龛龟鿎鿏鿒鿔𠀾𠆲𠆿𠇹𠉂𠉗𠋆𠚳𠛅𠛆𠛾𠡠𠮶𠯟𠯠𠰱𠰷𠱞𠲥𠴛𠴢𠵸𠵾𡋀𡋗𡋤𡍣𡒄𡝠𡞋𡞱𡠟𡥧𡭜𡭬𡳃𡳒𡶴𡸃𡺃𡺄𢋈𢗓𢘙𢘝𢘞𢙏𢙐𢙑𢙒𢙓𢛯𢠁𢢐𢧐𢫊𢫞𢫬𢬍𢬦𢭏𢽾𣃁𣆐𣈣𣍨𣍯𣍰𣎑𣏢𣐕𣐤𣑶𣒌𣓿𣔌𣗊𣗋𣗙𣘐𣘓𣘴𣘷𣚚𣞎𣨼𣭤𣯣𣱝𣲗𣲘𣳆𣶩𣶫𣶭𣷷𣸣𣺼𣺽𣽷𤆡𤆢𤇃𤇄𤇭𤇹𤈶𤈷𤊀𤊰𤋏𤎺𤎻𤙯𤝢𤞃𤞤𤠋𤦀𤩽𤳄𤶊𤶧𤻊𤽯𤾀𤿲𥁢𥅘𥅴𥅿𥆧𥇢𥎝𥐟𥐯𥐰𥐻𥞦𥧂𥩟𥩺𥫣𥬀𥬞𥬠𥭉𥮋𥮜𥮾𥱔𥹥𥺅𥺇𦈈𦈉𦈋𦈌𦈎𦈏𦈐𦈑𦈒𦈓𦈔𦈕𦈖𦈗𦈘𦈙𦈚𦈛𦈜𦈝𦈞𦈟𦈠𦈡𦍠𦛨𦝼𦟗𦨩𦰏𦰴𦶟𦶻𦻕𧉐𧉞𧌥𧏖𧏗𧑏𧒭𧜭𧝝𧝧𧮪𧳕𧹑𧹒𧹓𧹔𧹕𧹖𧹗𧿈𨀁𨀱𨁴𨂺𨄄𨅛𨅫𨅬𨉗𨐅𨐆𨐇𨐈𨐉𨐊𨑹𨟳𨠨𨡙𨡺𨤰𨰾𨰿𨱀𨱁𨱂𨱃𨱄𨱅𨱆𨱇𨱈𨱉𨱊𨱋𨱌𨱍𨱎𨱏𨱐𨱑𨱒𨱓𨱔𨱕𨱖𨷿𨸀𨸁𨸂𨸃𨸄𨸅𨸆𨸇𨸉𨸊𨸋𨸌𨸎𨸘𨸟𩏼𩏽𩏾𩏿𩐀𩓋𩖕𩖖𩖗𩙥𩙦𩙧𩙨𩙩𩙪𩙫𩙬𩙭𩙮𩙯𩙰𩟿𩠀𩠁𩠂𩠃𩠅𩠆𩠇𩠈𩠉𩠊𩠋𩠌𩠎𩠏𩠠𩡖𩧦𩧨𩧩𩧪𩧫𩧬𩧭𩧮𩧯𩧰𩧱𩧲𩧳𩧴𩧵𩧶𩧸𩧺𩧻𩧼𩧿𩨀𩨁𩨂𩨃𩨄𩨅𩨆𩨇𩨈𩨉𩨊𩨋𩨌𩨍𩨎𩨏𩨐𩩈𩬣𩬤𩭹𩯒𩰰𩲒𩴌𩽹𩽺𩽻𩽼𩽽𩽾𩽿𩾁𩾂𩾃𩾄𩾅𩾆𩾇𩾈𩾊𩾋𩾌𩾎𪉂𪉃𪉄𪉅𪉆𪉈𪉉𪉊𪉋𪉌𪉍𪉎𪉏𪉐𪉑𪉒𪉔𪉕𪎈𪎉𪎊𪎋𪎌𪑅𪔭𪚏𪚐𪜎𪞝𪟎𪟝𪠀𪠟𪠡𪠳𪠵𪠸𪠺𪠽𪡀𪡃𪡋𪡏𪡛𪡞𪡺𪢌𪢐𪢒𪢕𪢖𪢠𪢮𪢸𪣆𪣒𪣻𪤄𪤚𪥠𪥫𪥰𪥿𪧀𪧘𪨊𪨗𪨧𪨩𪨶𪨷𪨹𪩇𪩎𪩘𪩛𪩷𪩸𪪏𪪑𪪞𪪴𪪼𪫌𪫡𪫷𪫺𪬚𪬯𪭝𪭢𪭧𪭯𪭵𪭾𪮃𪮋𪮖𪮳𪮶𪯋𪰶𪱥𪱷𪲎𪲔𪲛𪲮𪳍𪳗𪴙𪵑𪵣𪵱𪶄𪶒𪶮𪷍𪷽𪸕𪸩𪹀𪹠𪹳𪹹𪺣𪺪𪺭𪺷𪺸𪺻𪺽𪻐𪻨𪻲𪻺𪼋𪼴𪽈𪽝𪽪𪽭𪽮𪽴𪽷𪾔𪾢𪾣𪾦𪾸𪿊𪿞𪿫𪿵𫀌𫀓𫀨𫀬𫀮𫁂𫁟𫁡𫁱𫁲𫁳𫁷𫁺𫂃𫂆𫂈𫂖𫂿𫃗𫄙𫄚𫄛𫄜𫄝𫄞𫄟𫄠���𫄢𫄣𫄤𫄥𫄦𫄧𫄨𫄩𫄪𫄫𫄬𫄭𫄮𫄯𫄰𫄱𫄲𫄳𫄴𫄵𫄶𫄷𫄸𫄹𫅅𫅗𫅥𫅭𫅼𫆏𫆝𫆫𫇘𫇛𫇪𫇭𫇴𫇽𫈉𫈎𫈟𫈵𫉁𫉄𫊪𫊮𫊸𫊹𫊻𫋇𫋌𫋲𫋷𫋹𫋻𫌀𫌇𫌋𫌨𫌪𫌫𫌬𫌭𫌯𫍐𫍙𫍚𫍛𫍜𫍝𫍞𫍟𫍠𫍡𫍢𫍣𫍤𫍥𫍦𫍧𫍨𫍩𫍪𫍫𫍬𫍭𫍮𫍯𫍰𫍱𫍲𫍳𫍴𫍵𫍶𫍷𫍸𫍹𫍺𫍻𫍼𫍽𫍾𫍿𫎆𫎌𫎦𫎧𫎨𫎩𫎪𫎫𫎬𫎭𫎱𫎳𫎸𫎺𫏃𫏆𫏋𫏌𫏐𫏑𫏕𫏞𫏨𫐄𫐅𫐆𫐇𫐈𫐉𫐊𫐋𫐌𫐍𫐎𫐏𫐐𫐑𫐒𫐓𫐔𫐕𫐖𫐗𫐘𫐙𫐷𫑘𫑡𫑷𫓥𫓦𫓧𫓨𫓩𫓪𫓫𫓬𫓭𫓮𫓯𫓰𫓱𫓲𫓳𫓴𫓵𫓶𫓷𫓸𫓹𫓺𫓻𫓼𫓽𫓾𫓿𫔀𫔁𫔂𫔃𫔄𫔅𫔆𫔇𫔈𫔉𫔊𫔋𫔌𫔍𫔎𫔏𫔐𫔑𫔒𫔓𫔔𫔕𫔖𫔭𫔮𫔯𫔰𫔲𫔴𫔵𫔶𫔽𫕚𫕥𫕨𫖃𫖅𫖇𫖑𫖒𫖓𫖔𫖕𫖖𫖪𫖫𫖬𫖭𫖮𫖯𫖰𫖱𫖲𫖳𫖴𫖵𫖶𫖷𫖸𫖹𫖺𫗇𫗈𫗉𫗊𫗋𫗚𫗞𫗟𫗠𫗡𫗢𫗣𫗤𫗥𫗦𫗧𫗨𫗩𫗪𫗫𫗬𫗭𫗮𫗯𫗰𫗱𫗳𫗴𫗵𫘛𫘜𫘝𫘞𫘟𫘠𫘡𫘣𫘤𫘥𫘦𫘧𫘨𫘩𫘪𫘫𫘬𫘭𫘮𫘯𫘰𫘱𫘽𫙂𫚈𫚉𫚊𫚋𫚌𫚍𫚎𫚏𫚐𫚑𫚒𫚓𫚔𫚕𫚖𫚗𫚘𫚙𫚚𫚛𫚜𫚝𫚞𫚟𫚠𫚡𫚢𫚣𫚤𫚥𫚦𫚧𫚨𫚩𫚪𫚫𫚬𫚭𫛚𫛛𫛜𫛝𫛞𫛟𫛠𫛡𫛢𫛣𫛤𫛥𫛦𫛧𫛨𫛩𫛪𫛫𫛬𫛭𫛮𫛯𫛰𫛱𫛲𫛳𫛴𫛵𫛶𫛷𫛸𫛹𫛺𫛻𫛼𫛽𫛾𫜀𫜁𫜂𫜃𫜄𫜅𫜊𫜑𫜒𫜓𫜔𫜕𫜙𫜟𫜨𫜩𫜪𫜫𫜬𫜭𫜮𫜯𫜰𫜲𫜳𫝈𫝋𫝦𫝧𫝨𫝩𫝪𫝫𫝬𫝭𫝮𫝵𫞅𫞗𫞚𫞛𫞝𫞠𫞡𫞢𫞣𫞥𫞦𫞧𫞨𫞩𫞷𫟃𫟄𫟅𫟆𫟇𫟑𫟕𫟞𫟟𫟠𫟡𫟢𫟤𫟥𫟦𫟫𫟬𫟲𫟳𫟴𫟵𫟶𫟷𫟸𫟹𫟺𫟻𫟼𫟽𫟾𫟿𫠀𫠁𫠂𫠅𫠆𫠇𫠈𫠊𫠋𫠌𫠏𫠐𫠑𫠒𫠖𫠜𫢸𫧃𫧮𫫇𫬐𫭟𫭢𫭼𫮃𫰛𫵷𫶇𫷷𫸩𬀩𬀪𬂩𬃊𬇕𬇙𬇹𬉼𬊈𬊤𬍛𬍡𬍤𬒈𬒗𬕂𬘓𬘘𬘡𬘩𬘫𬘬𬘭𬘯𬙂𬙊𬙋𬜬𬜯𬞟𬟁𬟽𬣙𬣞𬣡𬣳𬤇𬤊𬤝𬨂𬨎𬩽𬪩𬬩𬬭𬬮𬬱𬬸𬬹𬬻𬬿𬭁𬭊𬭎𬭚𬭛𬭤𬭩𬭬𬭭𬭯𬭳𬭶𬭸𬭼𬮱𬮿𬯀𬯎𬱖𬱟𬳵𬳶𬳽𬳿𬴂𬴃𬴊𬶋𬶍𬶏𬶐𬶟𬶠𬶨𬶭𬶮𬷕𬸘𬸚𬸣𬸦𬸪𬸯𬹼𬺈𬺓𰬸𰰨𰶎𰾄𰾭𱊜
data/dict/rules/st_characters.tsv ADDED
@@ -0,0 +1,3980 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 㐷 傌
2
+ 㐹 㑶 㐹
3
+ 㐽 偑
4
+ 㑇 㑳
5
+ 㑈 倲
6
+ 㑔 㑯
7
+ 㑩 儸
8
+ 㓆 𠗣
9
+ 㓥 劏
10
+ 㓰 劃
11
+ 㔉 劚
12
+ 㖊 噚
13
+ 㖞 喎
14
+ 㘎 㘚
15
+ 㚯 㜄
16
+ 㛀 媰
17
+ 㛟 𡞵
18
+ 㛠 𡢃
19
+ 㛣 㜏
20
+ 㛤 孋
21
+ 㛿 𡠹
22
+ 㟆 㠏
23
+ 㟜 𡾱
24
+ 㟥 嵾
25
+ 㡎 幓
26
+ 㤘 㥮
27
+ 㤽 懤
28
+ 㥪 慺
29
+ 㧏 掆
30
+ 㧐 㩳
31
+ 㧑 撝
32
+ 㧟 擓
33
+ 㧰 擽
34
+ 㨫 㩜
35
+ 㭎 棡
36
+ 㭏 椲
37
+ 㭣 𣙎
38
+ 㭤 樢
39
+ 㭴 樫
40
+ 㱩 殰
41
+ 㱮 殨
42
+ 㲿 瀇
43
+ 㳔 濧
44
+ 㳕 灡
45
+ 㳠 澾
46
+ 㳡 濄
47
+ 㳢 𣾷
48
+ 㳽 瀰
49
+ 㴋 潚
50
+ 㶉 鸂
51
+ 㶶 燶
52
+ 㶽 煱
53
+ 㺍 獱
54
+ 㻅 璯
55
+ 㻏 𤫩
56
+ 㻘 𤪺
57
+ 䀥 䁻
58
+ 䁖 瞜
59
+ 䂵 碽
60
+ 䃅 磾
61
+ 䅉 稏
62
+ 䅟 穇
63
+ 䅪 𥢢
64
+ 䇲 筴
65
+ 䉤 籔
66
+ 䌶 䊷
67
+ 䌷 紬
68
+ 䌸 縳
69
+ 䌹 絅
70
+ 䌺 䋙
71
+ 䌻 䋚
72
+ 䌼 綐
73
+ 䌽 綵
74
+ 䌾 䋻
75
+ 䌿 䋹
76
+ 䍀 繿
77
+ 䍁 繸
78
+ 䍠 䍦
79
+ 䎬 䎱
80
+ 䏝 膞
81
+ 䑽 𦪙
82
+ 䓓 薵
83
+ 䓕 薳
84
+ 䓖 藭
85
+ 䓨 罃
86
+ 䗖 螮
87
+ 䘛 𧝞
88
+ 䘞 𧜗
89
+ 䙊 𧜵
90
+ 䙌 䙡
91
+ 䙓 襬
92
+ 䜣 訢
93
+ 䜤 鿁
94
+ 䜥 𧩙
95
+ 䜧 䜀
96
+ 䜩 讌
97
+ 䝙 貙
98
+ 䞌 𧵳
99
+ 䞍 䝼
100
+ 䞎 𧶧
101
+ 䞐 賰
102
+ 䟢 躎
103
+ 䢀 𨊰
104
+ 䢁 𨊸
105
+ 䢂 𨋢
106
+ 䥺 釾
107
+ 䥽 鏺
108
+ 䥾 䥱
109
+ 䥿 𨯅
110
+ 䦀 𨦫
111
+ 䦁 𨧜
112
+ 䦂 䥇
113
+ 䦃 鐯
114
+ 䦅 鐥
115
+ 䦆 钁
116
+ 䦶 䦛
117
+ 䦷 䦟
118
+ 䩄 靦
119
+ 䭪 𩞯
120
+ 䯃 𩣑
121
+ 䯄 騧
122
+ 䯅 䯀
123
+ 䲝 䱽
124
+ 䲞 𩶘
125
+ 䲟 鮣
126
+ 䲠 鰆
127
+ 䲡 鰌
128
+ 䲢 鰧
129
+ 䲣 䱷
130
+ 䴓 鳾
131
+ 䴔 鵁
132
+ 䴕 鴷
133
+ 䴖 鶄
134
+ 䴗 鶪
135
+ 䴘 鷉
136
+ 䴙 鸊
137
+ 䶮 龑
138
+ 万 萬 万
139
+ 与 與
140
+ 丑 醜 丑
141
+ 专 專
142
+ 业 業
143
+ 丛 叢
144
+ 东 東
145
+ 丝 絲
146
+ 丢 丟
147
+ 两 兩
148
+ 严 嚴
149
+ 丧 喪
150
+ 个 個 箇
151
+ 丰 豐 丰
152
+ 临 臨
153
+ 为 爲
154
+ 丽 麗
155
+ 举 舉
156
+ 么 麼
157
+ 义 義
158
+ 乌 烏
159
+ 乐 樂
160
+ 乔 喬
161
+ 习 習
162
+ 乡 鄉
163
+ 书 書
164
+ 买 買
165
+ 乱 亂
166
+ 了 了 瞭
167
+ 争 爭
168
+ 于 於 于
169
+ 亏 虧
170
+ 云 雲 云
171
+ 亘 亙 亘
172
+ 亚 亞
173
+ 产 產
174
+ 亩 畝
175
+ 亲 親
176
+ 亵 褻
177
+ 亸 嚲
178
+ 亿 億
179
+ 仅 僅
180
+ 仆 僕 仆
181
+ 仇 仇 讎
182
+ 从 從
183
+ 仑 侖 崙
184
+ 仓 倉
185
+ 仪 儀
186
+ 们 們
187
+ 价 價 价
188
+ 仿 仿 彷
189
+ 众 衆
190
+ 优 優
191
+ 伙 夥 伙
192
+ 会 會
193
+ 伛 傴
194
+ 伞 傘
195
+ 伟 偉
196
+ 传 傳
197
+ 伡 俥
198
+ 伣 俔
199
+ 伤 傷
200
+ 伥 倀
201
+ 伦 倫
202
+ 伧 傖
203
+ 伪 僞
204
+ 伫 佇
205
+ 体 體
206
+ 余 餘 余
207
+ 佛 佛 彿
208
+ 佣 傭 佣
209
+ 佥 僉
210
+ 侠 俠
211
+ 侣 侶
212
+ 侥 僥
213
+ 侦 偵
214
+ 侧 側
215
+ 侨 僑
216
+ 侩 儈
217
+ 侪 儕
218
+ 侬 儂
219
+ 侭 儘
220
+ 俊 俊 儁
221
+ 俣 俁
222
+ 俦 儔
223
+ 俨 儼
224
+ 俩 倆
225
+ 俪 儷
226
+ 俫 倈
227
+ 俭 儉
228
+ 修 修 脩
229
+ 借 借 藉
230
+ 债 債
231
+ 倾 傾
232
+ 偬 傯
233
+ 偻 僂
234
+ 偾 僨
235
+ 偿 償
236
+ 傤 儎
237
+ 傥 儻
238
+ 傧 儐
239
+ 储 儲
240
+ 傩 儺
241
+ 僵 僵 殭
242
+ 儿 兒
243
+ 克 克 剋
244
+ 兑 兌
245
+ 兖 兗
246
+ 党 黨 党
247
+ 兰 蘭
248
+ 关 關
249
+ 兴 興
250
+ 兹 茲
251
+ 养 養
252
+ 兽 獸
253
+ 冁 囅
254
+ 内 內
255
+ 冈 岡
256
+ 册 冊
257
+ 写 寫
258
+ 军 軍
259
+ 农 農
260
+ 冬 冬 鼕
261
+ 冯 馮
262
+ 冲 衝 沖
263
+ 决 決
264
+ 况 況
265
+ 冻 凍
266
+ 净 淨
267
+ 凄 悽 淒
268
+ 准 準 准
269
+ 凉 涼
270
+ 凌 凌 淩
271
+ 减 減
272
+ 凑 湊
273
+ 凛 凜
274
+ 几 幾 几
275
+ 凤 鳳
276
+ 凫 鳧
277
+ 凭 憑
278
+ 凯 凱
279
+ 凶 兇 凶
280
+ 出 出 齣
281
+ 击 擊
282
+ 凿 鑿
283
+ 刍 芻
284
+ 划 劃 划
285
+ 刘 劉
286
+ 则 則
287
+ 刚 剛
288
+ 创 創
289
+ 删 刪
290
+ 别 別 彆
291
+ 刬 剗
292
+ 刭 剄
293
+ 刮 刮 颳
294
+ 制 制 製
295
+ 刹 剎
296
+ 刽 劊
297
+ 刾 㓨
298
+ 刿 劌
299
+ 剀 剴
300
+ 剂 劑
301
+ 剐 剮
302
+ 剑 劍
303
+ 剥 剝
304
+ 剧 劇
305
+ 劝 勸
306
+ 办 辦
307
+ 务 務
308
+ 劢 勱
309
+ 动 動
310
+ 励 勵
311
+ 劲 勁
312
+ 劳 勞
313
+ 势 勢
314
+ 勋 勳 勛
315
+ 勚 勩
316
+ 匀 勻
317
+ 匦 匭
318
+ 匮 匱
319
+ 区 區
320
+ 医 醫
321
+ 千 千 韆
322
+ 升 升 昇
323
+ 华 華
324
+ 协 協
325
+ 单 單
326
+ 卖 賣
327
+ 卜 卜 蔔
328
+ 占 佔 占
329
+ 卢 盧
330
+ 卤 滷 鹵
331
+ 卧 臥
332
+ 卫 衛
333
+ 却 卻
334
+ 卷 卷 捲
335
+ 卺 巹
336
+ 厂 廠 厂
337
+ 厅 廳
338
+ 历 歷 曆
339
+ 厉 厲
340
+ 压 壓
341
+ 厌 厭
342
+ 厍 厙
343
+ 厐 龎
344
+ 厕 廁
345
+ 厘 釐 厘
346
+ 厢 廂
347
+ 厣 厴
348
+ 厦 廈
349
+ 厨 廚
350
+ 厩 廄
351
+ 厮 廝
352
+ 县 縣
353
+ 叁 叄
354
+ 参 參 蔘
355
+ 叆 靉
356
+ 叇 靆
357
+ 双 雙
358
+ 发 發 髮
359
+ 变 變
360
+ 叙 敘
361
+ 叠 疊
362
+ 只 只 隻 祇
363
+ 台 臺 檯 颱 台
364
+ 叶 葉 叶
365
+ 号 號
366
+ 叹 嘆 歎
367
+ 叽 嘰
368
+ 吁 籲 吁
369
+ 吃 喫 吃
370
+ 合 合 閤
371
+ 吊 吊 弔
372
+ 同 同 衕
373
+ 后 後 后
374
+ 向 向 嚮 曏
375
+ 吓 嚇
376
+ 吕 呂
377
+ 吗 嗎
378
+ 吨 噸
379
+ 听 聽
380
+ 启 啓
381
+ 吴 吳
382
+ 呐 吶
383
+ 呒 嘸
384
+ 呓 囈
385
+ 呕 嘔
386
+ 呖 嚦
387
+ 呗 唄
388
+ 员 員
389
+ 呙 咼
390
+ 呛 嗆
391
+ 呜 嗚
392
+ 周 周 週 賙
393
+ 咏 詠
394
+ 咙 嚨
395
+ 咛 嚀
396
+ 咝 噝
397
+ 咤 吒
398
+ 咨 諮 咨
399
+ 咸 鹹 咸
400
+ 咽 咽 嚥
401
+ 哄 哄 鬨
402
+ 响 響
403
+ 哑 啞
404
+ 哒 噠
405
+ 哓 嘵
406
+ 哔 嗶
407
+ 哕 噦
408
+ 哗 譁 嘩
409
+ 哙 噲
410
+ 哜 嚌
411
+ 哝 噥
412
+ 哟 喲
413
+ 唇 脣 唇
414
+ 唛 嘜
415
+ 唝 嗊
416
+ 唠 嘮
417
+ 唡 啢
418
+ 唢 嗩
419
+ 唤 喚
420
+ 啧 嘖
421
+ 啬 嗇
422
+ 啭 囀
423
+ 啮 齧 嚙
424
+ 啯 嘓
425
+ 啰 囉
426
+ 啴 嘽
427
+ 啸 嘯
428
+ 喂 喂 餵
429
+ 喷 噴
430
+ 喽 嘍
431
+ 喾 嚳
432
+ 嗫 囁
433
+ 嗳 噯
434
+ 嘘 噓
435
+ 嘤 嚶
436
+ 嘱 囑
437
+ 噜 嚕
438
+ 噪 噪 譟
439
+ 嚣 囂
440
+ 回 回 迴
441
+ 团 團 糰
442
+ 园 園
443
+ 困 困 睏
444
+ 囱 囪
445
+ 围 圍
446
+ 囵 圇
447
+ 国 國
448
+ 图 圖
449
+ 圆 圓
450
+ 圣 聖
451
+ 圹 壙
452
+ 场 場
453
+ 坏 壞
454
+ 块 塊
455
+ 坚 堅
456
+ 坛 壇 罈
457
+ 坜 壢
458
+ 坝 壩 垻
459
+ 坞 塢
460
+ 坟 墳
461
+ 坠 墜
462
+ 垄 壟
463
+ 垅 壠
464
+ 垆 壚
465
+ 垒 壘
466
+ 垦 墾
467
+ 垩 堊
468
+ 垫 墊
469
+ 垭 埡
470
+ 垯 墶
471
+ 垱 壋
472
+ 垲 塏
473
+ 垴 堖
474
+ 埘 塒
475
+ 埙 壎 塤
476
+ 埚 堝
477
+ 堑 塹
478
+ 堕 墮
479
+ 塆 壪
480
+ 墙 牆
481
+ 壮 壯
482
+ 声 聲
483
+ 壳 殼
484
+ 壶 壺
485
+ 壸 壼
486
+ 处 處
487
+ 备 備
488
+ 复 復 複 覆
489
+ 够 夠
490
+ 夫 夫 伕
491
+ 头 頭
492
+ 夸 誇 夸
493
+ 夹 夾
494
+ 夺 奪
495
+ 奁 奩
496
+ 奂 奐
497
+ 奋 奮
498
+ 奖 獎
499
+ 奥 奧
500
+ 奸 奸 姦
501
+ 妆 妝
502
+ 妇 婦
503
+ 妈 媽
504
+ 妩 嫵
505
+ 妪 嫗
506
+ 妫 嬀
507
+ 姗 姍
508
+ 姜 姜 薑
509
+ 姹 奼
510
+ 娄 婁
511
+ 娅 婭
512
+ 娆 嬈
513
+ 娇 嬌
514
+ 娈 孌
515
+ 娘 娘 孃
516
+ 娱 娛
517
+ 娲 媧
518
+ 娴 嫺 嫻
519
+ 婳 嫿
520
+ 婴 嬰
521
+ 婵 嬋
522
+ 婶 嬸
523
+ 媪 媼
524
+ 媭 嬃
525
+ 嫒 ��
526
+ 嫔 嬪
527
+ 嫱 嬙
528
+ 嬷 嬤
529
+ 孙 孫
530
+ 学 學
531
+ 孪 孿
532
+ 宁 寧 甯
533
+ 它 它 牠
534
+ 宝 寶
535
+ 实 實
536
+ 宠 寵
537
+ 审 審
538
+ 宪 憲
539
+ 宫 宮
540
+ 家 家 傢
541
+ 宽 寬
542
+ 宾 賓
543
+ 寝 寢
544
+ 对 對
545
+ 寻 尋
546
+ 导 導
547
+ 寿 壽
548
+ 将 將
549
+ 尔 爾
550
+ 尘 塵
551
+ 尝 嘗 嚐
552
+ 尧 堯
553
+ 尴 尷
554
+ 尸 屍 尸
555
+ 尽 盡 儘
556
+ 局 局 侷
557
+ 层 層
558
+ 屃 屓
559
+ 屉 屜
560
+ 届 屆
561
+ 属 屬
562
+ 屡 屢
563
+ 屦 屨
564
+ 屿 嶼
565
+ 岁 歲
566
+ 岂 豈
567
+ 岖 嶇
568
+ 岗 崗
569
+ 岘 峴
570
+ 岚 嵐
571
+ 岛 島
572
+ 岩 巖 岩
573
+ 岭 嶺
574
+ 岳 嶽 岳
575
+ 岽 崬
576
+ 岿 巋
577
+ 峃 嶨
578
+ 峄 嶧
579
+ 峡 峽
580
+ 峣 嶢
581
+ 峤 嶠
582
+ 峥 崢
583
+ 峦 巒
584
+ 峰 峯
585
+ 崂 嶗
586
+ 崃 崍
587
+ 崄 嶮
588
+ 崭 嶄
589
+ 嵘 嶸
590
+ 嵚 嶔
591
+ 嵝 嶁
592
+ 巅 巔
593
+ 巨 巨 鉅
594
+ 巩 鞏
595
+ 巯 巰
596
+ 币 幣
597
+ 布 布 佈
598
+ 帅 帥
599
+ 师 師
600
+ 帏 幃
601
+ 帐 帳
602
+ 帘 簾 帘
603
+ 帜 幟
604
+ 带 帶
605
+ 帧 幀
606
+ 席 席 蓆
607
+ 帮 幫
608
+ 帱 幬
609
+ 帻 幘
610
+ 帼 幗
611
+ 幂 冪
612
+ 干 幹 乾 干
613
+ 并 並 併
614
+ 幸 幸 倖
615
+ 广 廣 广
616
+ 庄 莊
617
+ 庆 慶
618
+ 床 牀
619
+ 庐 廬
620
+ 庑 廡
621
+ 库 庫
622
+ 应 應
623
+ 庙 廟
624
+ 庞 龐
625
+ 废 廢
626
+ 庵 庵 菴
627
+ 庼 廎
628
+ 廪 廩
629
+ 开 開
630
+ 异 異
631
+ 弃 棄
632
+ 弑 弒
633
+ 张 張
634
+ 弥 彌 瀰
635
+ 弦 弦 絃
636
+ 弪 弳
637
+ 弯 彎
638
+ 弹 彈
639
+ 强 強
640
+ 归 歸
641
+ 当 當 噹
642
+ 录 錄 彔
643
+ 彟 彠
644
+ 彦 彥
645
+ 彨 彲
646
+ 彩 彩 綵
647
+ 彻 徹
648
+ 征 徵 征
649
+ 径 徑
650
+ 徕 徠
651
+ 御 御 禦
652
+ 忆 憶
653
+ 忏 懺
654
+ 志 志 誌
655
+ 忧 憂
656
+ 念 念 唸
657
+ 忾 愾
658
+ 怀 懷
659
+ 态 態
660
+ 怂 慫
661
+ 怃 憮
662
+ 怄 慪
663
+ 怅 悵
664
+ 怆 愴
665
+ 怜 憐
666
+ 总 總
667
+ 怼 懟
668
+ 怿 懌
669
+ 恋 戀
670
+ 恒 恆
671
+ 恤 恤 卹
672
+ 恳 懇
673
+ 恶 惡 噁
674
+ 恸 慟
675
+ 恹 懨
676
+ 恺 愷
677
+ 恻 惻
678
+ 恼 惱
679
+ 恽 惲
680
+ 悦 悅
681
+ 悫 愨
682
+ 悬 懸
683
+ 悭 慳
684
+ 悮 悞
685
+ 悯 憫
686
+ 惊 驚
687
+ 惧 懼
688
+ 惨 慘
689
+ 惩 懲
690
+ 惫 憊
691
+ 惬 愜
692
+ 惭 慚
693
+ 惮 憚
694
+ 惯 慣
695
+ 愈 愈 癒
696
+ 愠 慍
697
+ 愤 憤
698
+ 愦 憒
699
+ 愿 願 愿
700
+ 慑 懾
701
+ 慭 憖
702
+ 懑 懣
703
+ 懒 懶
704
+ 懔 懍
705
+ 戆 戇
706
+ 戋 戔
707
+ 戏 戲
708
+ 戗 戧
709
+ 战 戰
710
+ 戚 戚 慼
711
+ 戬 戩
712
+ 戯 戱
713
+ 户 戶
714
+ 才 才 纔
715
+ 扎 扎 紮
716
+ 扑 撲
717
+ 托 託 托
718
+ 扣 扣 釦
719
+ 执 執
720
+ 扩 擴
721
+ 扪 捫
722
+ 扫 掃
723
+ 扬 揚
724
+ 扰 擾
725
+ 折 折 摺
726
+ 抚 撫
727
+ 抛 拋
728
+ 抟 摶
729
+ 抠 摳
730
+ 抡 掄
731
+ 抢 搶
732
+ 护 護
733
+ 报 報
734
+ 抵 抵 牴
735
+ 担 擔
736
+ 拐 拐 柺
737
+ 拟 擬
738
+ 拢 攏
739
+ 拣 揀
740
+ 拥 擁
741
+ 拦 攔
742
+ 拧 擰
743
+ 拨 撥
744
+ 择 擇
745
+ 挂 掛 挂
746
+ 挚 摯
747
+ 挛 攣
748
+ 挜 掗
749
+ 挝 撾
750
+ 挞 撻
751
+ 挟 挾
752
+ 挠 撓
753
+ 挡 擋
754
+ 挢 撟
755
+ 挣 掙
756
+ 挤 擠
757
+ 挥 揮
758
+ 挦 撏
759
+ 挨 挨 捱
760
+ 挽 挽 輓
761
+ 捝 挩
762
+ 捞 撈
763
+ 损 損
764
+ 捡 撿
765
+ 换 換
766
+ 捣 搗
767
+ 据 據 据
768
+ 掳 擄
769
+ 掴 摑
770
+ 掷 擲
771
+ 掸 撣
772
+ 掺 摻
773
+ 掼 摜
774
+ 揽 攬
775
+ 揾 搵
776
+ 揿 撳
777
+ 搀 攙
778
+ 搁 擱
779
+ 搂 摟
780
+ 搄 揯
781
+ 搅 攪
782
+ 搜 搜 蒐
783
+ 携 攜
784
+ 摄 攝
785
+ 摅 攄
786
+ 摆 擺 襬
787
+ 摇 搖
788
+ 摈 擯
789
+ 摊 攤
790
+ 撄 攖
791
+ 撑 撐
792
+ 撵 攆
793
+ 撷 擷
794
+ 撸 擼
795
+ 撺 攛
796
+ 擜 㩵
797
+ 擞 擻
798
+ 攒 攢
799
+ 敌 敵
800
+ 敚 敓
801
+ 敛 斂
802
+ 敩 斆
803
+ 数 數
804
+ 斋 齋
805
+ 斓 斕
806
+ 斗 鬥 斗
807
+ 斩 斬
808
+ 断 斷
809
+ 旋 旋 鏇
810
+ 无 無
811
+ 旧 舊
812
+ 时 時
813
+ 旷 曠
814
+ 旸 暘
815
+ 昆 昆 崑
816
+ 昙 曇
817
+ 昵 暱
818
+ 昼 晝
819
+ 昽 曨
820
+ 显 顯
821
+ 晋 晉
822
+ 晒 曬
823
+ 晓 曉
824
+ 晔 曄
825
+ 晕 暈
826
+ 晖 暉
827
+ 暂 暫
828
+ 暅 𣈶
829
+ 暗 暗 闇
830
+ 暧 曖
831
+ 曲 曲 麴
832
+ 术 術 朮
833
+ 朱 朱 硃
834
+ 朴 樸 朴
835
+ 机 機
836
+ 杀 殺
837
+ 杂 雜
838
+ 权 權
839
+ 杆 杆 桿
840
+ 杠 槓 杠
841
+ 条 條
842
+ 来 來
843
+ 杨 楊
844
+ 杩 榪
845
+ 杯 杯 盃
846
+ 杰 傑 杰
847
+ 松 松 鬆
848
+ 板 板 闆
849
+ 极 極 极
850
+ 构 構
851
+ 枞 樅
852
+ 枢 樞
853
+ 枣 棗
854
+ 枥 櫪
855
+ 枧 梘
856
+ 枨 棖
857
+ 枪 槍
858
+ 枫 楓
859
+ 枭 梟
860
+ 柜 櫃 柜
861
+ 柠 檸
862
+ 柽 檉
863
+ 栀 梔
864
+ 栅 柵
865
+ 标 標
866
+ 栈 棧
867
+ 栉 櫛
868
+ 栊 櫳
869
+ 栋 棟
870
+ 栌 櫨
871
+ 栎 櫟
872
+ 栏 欄
873
+ 树 樹
874
+ 栖 棲
875
+ 栗 慄 栗
876
+ 样 樣
877
+ 核 核 覈
878
+ 栾 欒
879
+ 桠 椏
880
+ 桡 橈
881
+ 桢 楨
882
+ 档 檔
883
+ 桤 榿
884
+ 桥 橋
885
+ 桦 樺
886
+ 桧 檜
887
+ 桨 槳
888
+ 桩 樁
889
+ 桪 樳
890
+ 梁 梁 樑
891
+ 梦 夢
892
+ 梼 檮
893
+ 梾 棶
894
+ 梿 槤
895
+ 检 檢
896
+ 棁 梲
897
+ 棂 欞
898
+ 椁 槨
899
+ 椝 槼
900
+ 椟 櫝
901
+ 椠 槧
902
+ 椢 槶
903
+ 椤 欏
904
+ 椫 樿
905
+ 椭 橢
906
+ 椮 槮
907
+ 楼 樓
908
+ 榄 欖
909
+ 榅 榲
910
+ 榇 櫬
911
+ 榈 櫚
912
+ 榉 櫸
913
+ 榝 樧
914
+ 槚 檟
915
+ 槛 檻
916
+ 槟 檳
917
+ 槠 櫧
918
+ 横 橫
919
+ 樯 檣
920
+ 樱 櫻
921
+ 橥 櫫
922
+ 橱 櫥
923
+ 橹 櫓
924
+ 橼 櫞
925
+ 檩 檁
926
+ 欢 歡
927
+ 欤 歟
928
+ 欧 歐
929
+ 欲 欲 慾
930
+ 歼 殲
931
+ 殁 歿
932
+ 殇 殤
933
+ 残 殘
934
+ 殒 殞
935
+ 殓 殮
936
+ 殚 殫
937
+ 殡 殯
938
+ 殴 毆
939
+ 毁 毀 燬 譭
940
+ 毂 轂
941
+ 毕 畢
942
+ 毙 斃
943
+ 毡 氈
944
+ 毵 毿
945
+ 毶 𣯶
946
+ 氇 氌
947
+ 气 氣
948
+ 氢 氫
949
+ 氩 氬
950
+ 氲 氳
951
+ 汇 匯 彙
952
+ 汉 漢
953
+ 汤 湯
954
+ 汹 洶
955
+ 沄 澐
956
+ 沈 沈 瀋
957
+ 沟 溝
958
+ 没 沒
959
+ 沣 灃
960
+ 沤 漚
961
+ 沥 瀝
962
+ 沦 淪
963
+ 沧 滄
964
+ 沨 渢
965
+ 沩 潙
966
+ 沪 滬
967
+ 沾 沾 霑
968
+ 泛 泛 氾 汎
969
+ 泞 濘
970
+ 注 注 註
971
+ 泪 淚
972
+ 泶 澩
973
+ 泷 瀧
974
+ 泸 瀘
975
+ 泺 濼
976
+ 泻 瀉
977
+ 泼 潑
978
+ 泽 澤
979
+ 泾 涇
980
+ 洁 潔
981
+ 洒 灑
982
+ 洼 窪
983
+ 浃 浹
984
+ 浅 淺
985
+ 浆 漿
986
+ 浇 澆
987
+ 浈 湞
988
+ 浉 溮
989
+ 浊 濁
990
+ 测 測
991
+ 浍 澮
992
+ 济 濟
993
+ 浏 瀏
994
+ 浐 滻
995
+ 浑 渾
996
+ 浒 滸
997
+ 浓 濃
998
+ 浔 潯
999
+ 浕 濜
1000
+ 涂 塗 涂
1001
+ 涌 湧 涌
1002
+ 涚 涗
1003
+ 涛 濤
1004
+ 涝 澇
1005
+ 涞 淶
1006
+ 涟 漣
1007
+ 涠 潿
1008
+ 涡 渦
1009
+ 涢 溳
1010
+ 涣 渙
1011
+ 涤 滌
1012
+ 润 潤
1013
+ 涧 澗
1014
+ 涨 漲
1015
+ 涩 澀
1016
+ 淀 澱 淀
1017
+ 渊 淵
1018
+ 渌 淥
1019
+ 渍 漬
1020
+ 渎 瀆
1021
+ 渐 漸
1022
+ 渑 澠
1023
+ 渔 漁
1024
+ 渖 瀋
1025
+ 渗 滲
1026
+ 温 溫
1027
+ 游 遊 游
1028
+ 湾 灣
1029
+ 湿 溼
1030
+ 溁 濚
1031
+ 溃 潰
1032
+ 溅 濺
1033
+ 溆 漵
1034
+ 溇 漊
1035
+ 滗 潷
1036
+ 滚 滾
1037
+ 滞 滯
1038
+ 滟 灩 灧
1039
+ 滠 灄
1040
+ 满 滿
1041
+ 滢 瀅
1042
+ 滤 濾
1043
+ 滥 濫
1044
+ 滦 灤
1045
+ 滨 濱
1046
+ 滩 灘
1047
+ 滪 澦
1048
+ 漓 漓 灕
1049
+ 潆 瀠
1050
+ 潇 瀟
1051
+ 潋 瀲
1052
+ 潍 濰
1053
+ 潜 潛
1054
+ 潴 瀦
1055
+ 澛 瀂
1056
+ 澜 瀾
1057
+ 濑 瀨
1058
+ 濒 瀕
1059
+ 灏 灝
1060
+ 灭 滅
1061
+ 灯 燈
1062
+ 灵 靈
1063
+ 灶 竈
1064
+ 灾 災
1065
+ 灿 燦
1066
+ 炀 煬
1067
+ 炉 爐
1068
+ 炖 燉
1069
+ 炜 煒
1070
+ 炝 熗
1071
+ 点 點
1072
+ 炼 煉 鍊
1073
+ 炽 熾
1074
+ 烁 爍
1075
+ 烂 爛
1076
+ 烃 烴
1077
+ 烛 燭
1078
+ 烟 煙 菸
1079
+ 烦 煩
1080
+ 烧 燒
1081
+ 烨 燁
1082
+ 烩 燴
1083
+ 烫 燙
1084
+ 烬 燼
1085
+ 热 熱
1086
+ 焕 煥
1087
+ 焖 燜
1088
+ 焘 燾
1089
+ 煴 熅
1090
+ 熏 燻 熏
1091
+ 爱 愛
1092
+ 爷 爺
1093
+ 牍 牘
1094
+ 牦 犛
1095
+ 牵 牽
1096
+ 牺 犧
1097
+ 犊 犢
1098
+ 状 狀
1099
+ 犷 獷
1100
+ 犸 獁
1101
+ 犹 猶
1102
+ 狈 狽
1103
+ 狝 獮
1104
+ 狞 獰
1105
+ 独 獨
1106
+ 狭 狹
1107
+ 狮 獅
1108
+ 狯 獪
1109
+ 狰 猙
1110
+ 狱 獄
1111
+ 狲 猻
1112
+ 猃 獫
1113
+ 猎 獵
1114
+ 猕 獼
1115
+ 猡 玀
1116
+ 猪 豬
1117
+ 猫 貓
1118
+ 猬 蝟
1119
+ 献 獻
1120
+ 獭 獺
1121
+ 玑 璣
1122
+ 玙 璵
1123
+ 玚 瑒
1124
+ 玛 瑪
1125
+ 玩 玩 翫
1126
+ 玮 瑋
1127
+ 环 環
1128
+ 现 現
1129
+ 玱 瑲
1130
+ 玺 璽
1131
+ 珐 琺
1132
+ 珑 瓏
1133
+ 珰 璫
1134
+ 珲 琿
1135
+ 琎 璡
1136
+ 琏 璉
1137
+ 琐 瑣
1138
+ 琼 瓊
1139
+ 瑶 瑤
1140
+ 瑷 璦
1141
+ 瑸 璸
1142
+ 璇 璇 璿
1143
+ 璎 瓔
1144
+ 瓒 瓚
1145
+ 瓮 甕
1146
+ 瓯 甌
1147
+ 电 電
1148
+ 画 畫
1149
+ 畅 暢
1150
+ 畴 疇
1151
+ 疖 癤
1152
+ 疗 療
1153
+ 疟 瘧
1154
+ 疠 癘
1155
+ 疡 瘍
1156
+ 疬 癧
1157
+ 疭 瘲
1158
+ 疮 瘡
1159
+ 疯 瘋
1160
+ 疱 皰
1161
+ 疴 痾
1162
+ 症 症 癥
1163
+ 痈 癰
1164
+ 痉 痙
1165
+ 痒 癢
1166
+ 痖 瘂
1167
+ 痨 癆
1168
+ 痪 瘓
1169
+ 痫 癇
1170
+ 痴 癡
1171
+ 瘅 癉
1172
+ 瘆 瘮
1173
+ 瘗 瘞
1174
+ 瘘 瘻
1175
+ 瘪 癟
1176
+ 瘫 癱
1177
+ 瘾 癮
1178
+ 瘿 癭
1179
+ 癞 癩
1180
+ 癣 癬
1181
+ 癫 癲
1182
+ 皂 皁 皂
1183
+ 皑 皚
1184
+ 皱 皺
1185
+ 皲 皸
1186
+ 盏 盞
1187
+ 盐 鹽
1188
+ 监 監
1189
+ 盖 蓋
1190
+ 盗 盜
1191
+ 盘 盤
1192
+ 眍 瞘
1193
+ 眦 眥
1194
+ 眬 矓
1195
+ 睁 睜
1196
+ 睐 睞
1197
+ 睑 瞼
1198
+ 瞆 瞶
1199
+ 瞒 瞞
1200
+ 瞩 矚
1201
+ 矩 矩 榘
1202
+ 矫 矯
1203
+ 矶 磯
1204
+ 矾 礬
1205
+ 矿 礦
1206
+ 砀 碭
1207
+ 码 碼
1208
+ 砖 磚
1209
+ 砗 硨
1210
+ 砚 硯
1211
+ 砜 碸
1212
+ 砺 礪
1213
+ 砻 礱
1214
+ 砾 礫
1215
+ 础 礎
1216
+ 硁 硜
1217
+ 硕 碩
1218
+ 硖 硤
1219
+ 硗 磽
1220
+ 硙 磑
1221
+ 硚 礄
1222
+ 确 確 确
1223
+ 硵 磠
1224
+ 硷 礆
1225
+ 碍 礙
1226
+ 碛 磧
1227
+ 碜 磣
1228
+ 碱 鹼
1229
+ 礼 禮
1230
+ 祃 禡
1231
+ 祎 禕
1232
+ 祢 禰
1233
+ 祯 禎
1234
+ 祷 禱
1235
+ 祸 禍
1236
+ 禀 稟
1237
+ 禄 祿
1238
+ 禅 禪
1239
+ 离 離
1240
+ 私 私 俬
1241
+ 秃 禿
1242
+ 秆 稈
1243
+ 秋 秋 鞦
1244
+ 种 種 种
1245
+ 秘 祕
1246
+ 积 積
1247
+ 称 稱
1248
+ 秽 穢
1249
+ 秾 穠
1250
+ 稆 穭
1251
+ 税 稅
1252
+ 稣 穌
1253
+ 稳 穩
1254
+ 穑 穡
1255
+ 穞 穭
1256
+ 穷 窮
1257
+ 窃 竊
1258
+ 窍 竅
1259
+ 窎 窵
1260
+ 窑 窯
1261
+ 窜 竄
1262
+ 窝 窩
1263
+ 窥 窺
1264
+ 窦 竇
1265
+ 窭 窶
1266
+ 竖 豎
1267
+ 竞 競
1268
+ 笃 篤
1269
+ 笋 筍
1270
+ 笔 筆
1271
+ 笕 筧
1272
+ 笺 箋
1273
+ 笼 籠
1274
+ 笾 籩
1275
+ 筑 築 筑
1276
+ 筚 篳
1277
+ 筛 篩
1278
+ 筜 簹
1279
+ 筝 箏
1280
+ 筹 籌
1281
+ 筼 篔
1282
+ 签 籤 簽
1283
+ 筿 篠
1284
+ 简 簡
1285
+ 箓 籙
1286
+ 箦 簀
1287
+ 箧 篋
1288
+ 箨 籜
1289
+ 箩 籮
1290
+ 箪 簞
1291
+ 箫 簫
1292
+ 篑 簣
1293
+ 篓 簍
1294
+ 篮 籃
1295
+ 篯 籛
1296
+ 篱 籬
1297
+ 簖 籪
1298
+ 籁 籟
1299
+ 籴 糴
1300
+ 类 類
1301
+ 籼 秈
1302
+ 粜 糶
1303
+ 粝 糲
1304
+ 粤 粵
1305
+ 粪 糞
1306
+ 粮 糧
1307
+ 粽 糉
1308
+ 糁 糝
1309
+ 糇 餱
1310
+ 糍 餈
1311
+ 系 系 係 繫
1312
+ 紧 緊
1313
+ 絷 縶
1314
+ 緼 縕
1315
+ 縆 緪
1316
+ 纟 糹
1317
+ 纠 糾
1318
+ 纡 紆
1319
+ 红 紅
1320
+ 纣 紂
1321
+ 纤 纖 縴
1322
+ 纥 紇
1323
+ 约 約
1324
+ 级 級
1325
+ 纨 紈
1326
+ 纩 纊
1327
+ 纪 紀
1328
+ 纫 紉
1329
+ 纬 緯
1330
+ 纭 紜
1331
+ 纮 紘
1332
+ 纯 純
1333
+ 纰 紕
1334
+ 纱 紗
1335
+ 纲 綱
1336
+ 纳 納
1337
+ 纴 紝
1338
+ 纵 縱
1339
+ 纶 綸
1340
+ 纷 紛
1341
+ 纸 紙
1342
+ 纹 紋
1343
+ 纺 紡
1344
+ 纻 紵
1345
+ 纼 紖
1346
+ 纽 紐
1347
+ 纾 紓
1348
+ 线 線
1349
+ 绀 紺
1350
+ 绁 紲
1351
+ 绂 紱
1352
+ 练 練
1353
+ 组 組
1354
+ 绅 紳
1355
+ 细 細
1356
+ 织 織
1357
+ 终 終
1358
+ 绉 縐
1359
+ 绊 絆
1360
+ 绋 紼
1361
+ 绌 絀
1362
+ 绍 紹
1363
+ 绎 繹
1364
+ 经 經
1365
+ 绐 紿
1366
+ 绑 綁
1367
+ 绒 絨
1368
+ 结 結
1369
+ 绔 絝
1370
+ 绕 繞
1371
+ 绖 絰
1372
+ 绗 絎
1373
+ 绘 繪
1374
+ 给 給
1375
+ 绚 絢
1376
+ 绛 絳
1377
+ 络 絡
1378
+ 绝 絕
1379
+ 绞 絞
1380
+ 统 統
1381
+ 绠 綆
1382
+ 绡 綃
1383
+ 绢 絹
1384
+ 绣 繡
1385
+ 绤 綌
1386
+ 绥 綏
1387
+ 绦 絛
1388
+ 继 繼
1389
+ 绨 綈
1390
+ 绩 績
1391
+ 绪 緒
1392
+ 绫 綾
1393
+ 绬 緓
1394
+ 续 續
1395
+ 绮 綺
1396
+ 绯 緋
1397
+ 绰 綽
1398
+ 绱 鞝 緔
1399
+ 绲 緄
1400
+ 绳 繩
1401
+ 维 維
1402
+ 绵 綿
1403
+ 绶 綬
1404
+ 绷 繃 綳
1405
+ 绸 綢
1406
+ 绹 綯
1407
+ 绺 綹
1408
+ 绻 綣
1409
+ 综 綜
1410
+ 绽 綻
1411
+ 绾 綰
1412
+ 绿 綠
1413
+ 缀 綴
1414
+ 缁 緇
1415
+ 缂 緙
1416
+ 缃 緗
1417
+ 缄 緘
1418
+ 缅 緬
1419
+ 缆 纜
1420
+ 缇 緹
1421
+ 缈 緲
1422
+ 缉 緝
1423
+ 缊 縕
1424
+ 缋 繢
1425
+ 缌 緦
1426
+ 缍 綞
1427
+ 缎 緞
1428
+ 缏 緶
1429
+ 缐 線
1430
+ 缑 緱
1431
+ 缒 縋
1432
+ 缓 緩
1433
+ 缔 締
1434
+ 缕 縷
1435
+ 编 編
1436
+ 缗 緡
1437
+ 缘 緣
1438
+ 缙 縉
1439
+ 缚 縛
1440
+ 缛 縟
1441
+ 缜 縝
1442
+ 缝 縫
1443
+ 缞 縗
1444
+ 缟 縞
1445
+ 缠 纏
1446
+ 缡 縭
1447
+ 缢 縊
1448
+ 缣 縑
1449
+ 缤 繽
1450
+ 缥 縹
1451
+ 缦 縵
1452
+ 缧 縲
1453
+ 缨 纓
1454
+ 缩 縮
1455
+ 缪 繆
1456
+ 缫 繅
1457
+ 缬 纈
1458
+ 缭 繚
1459
+ 缮 繕
1460
+ 缯 繒
1461
+ 缰 繮
1462
+ 缱 繾
1463
+ 缲 繰
1464
+ 缳 繯
1465
+ 缴 繳
1466
+ 缵 纘
1467
+ 罂 罌
1468
+ 网 網
1469
+ 罗 羅
1470
+ 罚 罰
1471
+ 罢 罷
1472
+ 罴 羆
1473
+ 羁 羈
1474
+ 羟 羥
1475
+ 羡 羨
1476
+ 群 羣
1477
+ 翘 翹
1478
+ 翙 翽
1479
+ 翚 翬
1480
+ 耢 耮
1481
+ 耧 耬
1482
+ 耸 聳
1483
+ 耻 恥
1484
+ 聂 聶
1485
+ 聋 聾
1486
+ 职 職
1487
+ 聍 聹
1488
+ 联 聯
1489
+ 聩 聵
1490
+ 聪 聰
1491
+ 肃 肅
1492
+ 肠 腸
1493
+ 肤 膚
1494
+ 肮 骯
1495
+ 肴 餚
1496
+ 肾 腎
1497
+ 肿 腫
1498
+ 胀 脹
1499
+ 胁 脅
1500
+ 胄 胄 冑
1501
+ 胆 膽
1502
+ 背 背 揹
1503
+ 胜 勝 胜
1504
+ 胡 胡 鬍 衚
1505
+ 胧 朧
1506
+ 胨 腖
1507
+ 胪 臚
1508
+ 胫 脛
1509
+ 胶 膠
1510
+ 脉 脈
1511
+ 脍 膾
1512
+ 脏 髒 臟
1513
+ 脐 臍
1514
+ 脑 腦
1515
+ 脓 膿
1516
+ 脔 臠
1517
+ 脚 腳
1518
+ 脱 脫
1519
+ 脶 腡
1520
+ 脸 臉
1521
+ 腊 臘 腊
1522
+ 腌 醃 腌
1523
+ 腘 膕
1524
+ 腭 齶
1525
+ 腻 膩
1526
+ 腼 靦
1527
+ 腽 膃
1528
+ 腾 騰
1529
+ 膑 臏
1530
+ 膻 羶 膻
1531
+ 臜 臢
1532
+ 致 致 緻
1533
+ 舆 輿
1534
+ 舍 舍 捨
1535
+ 舣 艤
1536
+ 舰 艦
1537
+ 舱 艙
1538
+ 舻 艫
1539
+ 艰 艱
1540
+ 艳 豔 艷
1541
+ 艺 藝
1542
+ 节 節
1543
+ 芈 羋
1544
+ 芗 薌
1545
+ 芜 蕪
1546
+ 芦 蘆
1547
+ 芸 芸 蕓
1548
+ 苁 蓯
1549
+ 苇 葦
1550
+ 苈 藶
1551
+ 苋 莧
1552
+ 苌 萇
1553
+ 苍 蒼
1554
+ 苎 苧
1555
+ 苏 蘇 甦 囌
1556
+ 苔 苔 薹
1557
+ 苧 薴
1558
+ 苹 蘋 苹
1559
+ 范 範 范
1560
+ 茎 莖
1561
+ 茏 蘢
1562
+ 茑 蔦
1563
+ 茔 塋
1564
+ 茕 煢
1565
+ 茧 繭
1566
+ 荆 荊
1567
+ 荐 薦 荐
1568
+ 荙 薘
1569
+ 荚 莢
1570
+ 荛 蕘
1571
+ 荜 蓽
1572
+ 荝 萴
1573
+ 荞 蕎
1574
+ 荟 薈
1575
+ 荠 薺
1576
+ 荡 蕩 盪
1577
+ 荣 榮
1578
+ 荤 葷
1579
+ 荥 滎
1580
+ 荦 犖
1581
+ 荧 熒
1582
+ 荨 蕁
1583
+ 荩 藎
1584
+ 荪 蓀
1585
+ 荫 蔭 廕
1586
+ 荬 蕒
1587
+ 荭 葒
1588
+ 荮 葤
1589
+ 药 藥 葯
1590
+ 莅 蒞
1591
+ 莱 萊
1592
+ 莲 蓮
1593
+ 莳 蒔
1594
+ 莴 萵
1595
+ 莶 薟
1596
+ 获 獲 穫
1597
+ 莸 蕕
1598
+ 莹 瑩
1599
+ 莺 鶯
1600
+ 莼 蓴
1601
+ 萚 蘀
1602
+ 萝 蘿
1603
+ 萤 螢
1604
+ 营 營
1605
+ 萦 縈
1606
+ 萧 蕭
1607
+ 萨 薩
1608
+ 葱 蔥
1609
+ 蒀 蒕
1610
+ 蒇 蕆
1611
+ 蒉 蕢
1612
+ 蒋 蔣
1613
+ 蒌 蔞
1614
+ 蒏 醟
1615
+ 蒙 蒙 矇 濛 懞
1616
+ 蓝 藍
1617
+ 蓟 薊
1618
+ 蓠 蘺
1619
+ 蓣 蕷
1620
+ 蓥 鎣
1621
+ 蓦 驀
1622
+ 蔂 虆
1623
+ 蔑 蔑 衊
1624
+ 蔷 薔
1625
+ 蔹 蘞
1626
+ 蔺 藺
1627
+ 蔼 藹
1628
+ 蕰 薀
1629
+ 蕲 蘄
1630
+ 蕴 蘊
1631
+ 薮 藪
1632
+ 藓 蘚
1633
+ 藴 蘊
1634
+ 蘖 櫱
1635
+ 虏 虜
1636
+ 虑 慮
1637
+ 虚 虛
1638
+ 虫 蟲 虫
1639
+ 虬 虯
1640
+ 虮 蟣
1641
+ 虱 蝨
1642
+ 虽 雖
1643
+ 虾 蝦
1644
+ 虿 蠆
1645
+ 蚀 蝕
1646
+ 蚁 蟻
1647
+ 蚂 螞
1648
+ 蚃 蠁
1649
+ 蚕 蠶
1650
+ 蚝 蠔 蚝
1651
+ 蚬 蜆
1652
+ 蛊 蠱
1653
+ 蛎 蠣
1654
+ 蛏 蟶
1655
+ 蛮 蠻
1656
+ 蛰 蟄
1657
+ 蛱 蛺
1658
+ 蛲 蟯
1659
+ 蛳 螄
1660
+ 蛴 蠐
1661
+ 蜕 蛻
1662
+ 蜗 蝸
1663
+ 蜡 蠟 蜡
1664
+ 蝇 蠅
1665
+ 蝈 蟈
1666
+ 蝉 蟬
1667
+ 蝎 蠍 蝎
1668
+ 蝼 螻
1669
+ 蝾 蠑
1670
+ 螀 螿
1671
+ 螨 蟎
1672
+ 蟏 蠨
1673
+ 衅 釁
1674
+ 衔 銜
1675
+ 补 補
1676
+ 表 表 錶
1677
+ 衬 襯
1678
+ 衮 袞
1679
+ 袄 襖
1680
+ 袅 嫋 裊
1681
+ 袆 褘
1682
+ 袜 襪
1683
+ 袭 襲
1684
+ 袯 襏
1685
+ 装 裝
1686
+ 裆 襠
1687
+ 裈 褌
1688
+ 裢 褳
1689
+ 裣 襝
1690
+ 裤 褲
1691
+ 裥 襉 襇
1692
+ 褛 褸
1693
+ 褴 襤
1694
+ 襕 襴
1695
+ 见 見
1696
+ 观 觀
1697
+ 觃 覎
1698
+ 规 規
1699
+ 觅 覓
1700
+ 视 視
1701
+ 觇 覘
1702
+ 览 覽
1703
+ 觉 覺
1704
+ 觊 覬
1705
+ 觋 覡
1706
+ 觌 覿
1707
+ 觍 覥
1708
+ 觎 覦
1709
+ 觏 覯
1710
+ 觐 覲
1711
+ 觑 覷
1712
+ 觞 觴
1713
+ 触 觸
1714
+ 觯 觶
1715
+ 訚 誾
1716
+ 詟 讋
1717
+ 誉 譽
1718
+ 誊 謄
1719
+ 讠 訁
1720
+ 计 計
1721
+ 订 訂
1722
+ 讣 訃
1723
+ 认 認
1724
+ 讥 譏
1725
+ 讦 訐
1726
+ 讧 訌
1727
+ 讨 討
1728
+ 让 讓
1729
+ 讪 訕
1730
+ 讫 訖
1731
+ 讬 託
1732
+ 训 訓
1733
+ 议 議
1734
+ 讯 訊
1735
+ 记 記
1736
+ 讱 訒
1737
+ 讲 講
1738
+ 讳 諱
1739
+ 讴 謳
1740
+ 讵 詎
1741
+ 讶 訝
1742
+ 讷 訥
1743
+ 许 許
1744
+ 讹 訛
1745
+ 论 論
1746
+ 讻 訩
1747
+ 讼 訟
1748
+ 讽 諷
1749
+ 设 設
1750
+ 访 訪
1751
+ 诀 訣
1752
+ 证 證 証
1753
+ 诂 詁
1754
+ 诃 訶
1755
+ 评 評
1756
+ 诅 詛
1757
+ 识 識
1758
+ 诇 詗
1759
+ 诈 詐
1760
+ 诉 訴
1761
+ 诊 診
1762
+ 诋 詆
1763
+ 诌 謅
1764
+ 词 詞
1765
+ 诎 詘
1766
+ 诏 詔
1767
+ 诐 詖
1768
+ 译 譯
1769
+ 诒 詒
1770
+ 诓 誆
1771
+ 诔 誄
1772
+ 试 試
1773
+ 诖 詿
1774
+ 诗 詩
1775
+ 诘 詰
1776
+ 诙 詼
1777
+ 诚 誠
1778
+ 诛 誅
1779
+ 诜 詵
1780
+ 话 話
1781
+ 诞 誕
1782
+ 诟 詬
1783
+ 诠 詮
1784
+ 诡 詭
1785
+ 询 詢
1786
+ 诣 詣
1787
+ 诤 諍
1788
+ 该 該
1789
+ 详 詳
1790
+ 诧 詫
1791
+ 诨 諢
1792
+ 诩 詡
1793
+ 诪 譸
1794
+ 诫 誡
1795
+ 诬 誣
1796
+ 语 語
1797
+ 诮 誚
1798
+ 误 誤
1799
+ 诰 誥
1800
+ 诱 誘
1801
+ 诲 誨
1802
+ 诳 誑
1803
+ 说 說
1804
+ 诵 誦
1805
+ 诶 誒
1806
+ 请 請
1807
+ 诸 諸
1808
+ 诹 諏
1809
+ 诺 諾
1810
+ 读 讀
1811
+ 诼 諑
1812
+ 诽 誹
1813
+ 课 課
1814
+ 诿 諉
1815
+ 谀 諛
1816
+ 谁 誰
1817
+ 谂 諗
1818
+ 调 調
1819
+ 谄 諂
1820
+ 谅 諒
1821
+ 谆 諄
1822
+ 谇 誶
1823
+ 谈 談
1824
+ 谉 讅
1825
+ 谊 誼
1826
+ 谋 謀
1827
+ 谌 諶
1828
+ 谍 諜
1829
+ 谎 謊
1830
+ 谏 諫
1831
+ 谐 諧
1832
+ 谑 謔
1833
+ 谒 謁
1834
+ 谓 謂
1835
+ 谔 諤
1836
+ 谕 諭
1837
+ 谖 諼
1838
+ 谗 讒
1839
+ 谘 諮
1840
+ 谙 諳
1841
+ 谚 諺
1842
+ 谛 諦
1843
+ 谜 謎
1844
+ 谝 諞
1845
+ 谞 諝
1846
+ 谟 謨
1847
+ 谠 讜
1848
+ 谡 謖
1849
+ 谢 謝
1850
+ 谣 謠
1851
+ 谤 謗
1852
+ 谥 諡 謚
1853
+ 谦 謙
1854
+ 谧 謐
1855
+ 谨 謹
1856
+ 谩 謾
1857
+ 谪 謫
1858
+ 谫 譾
1859
+ 谬 謬
1860
+ 谭 譚
1861
+ 谮 譖
1862
+ 谯 譙
1863
+ 谰 讕
1864
+ 谱 譜
1865
+ 谲 譎
1866
+ 谳 讞
1867
+ 谴 譴
1868
+ 谵 譫
1869
+ 谶 讖
1870
+ 谷 谷 穀
1871
+ 豮 豶
1872
+ 贝 貝
1873
+ 贞 貞
1874
+ 负 負
1875
+ 贠 貟
1876
+ 贡 貢
1877
+ 财 財
1878
+ 责 責
1879
+ 贤 賢
1880
+ 败 敗
1881
+ 账 賬
1882
+ 货 貨
1883
+ 质 質
1884
+ 贩 販
1885
+ 贪 貪
1886
+ 贫 貧
1887
+ 贬 貶
1888
+ 购 購
1889
+ 贮 貯
1890
+ 贯 貫
1891
+ 贰 貳
1892
+ 贱 賤
1893
+ 贲 賁
1894
+ 贳 貰
1895
+ 贴 貼
1896
+ 贵 貴
1897
+ 贶 貺
1898
+ 贷 貸
1899
+ 贸 貿
1900
+ 费 費
1901
+ 贺 賀
1902
+ 贻 貽
1903
+ 贼 賊
1904
+ 贽 贄
1905
+ 贾 賈
1906
+ 贿 賄
1907
+ 赀 貲
1908
+ 赁 賃
1909
+ 赂 賂
1910
+ 赃 贓
1911
+ 资 資
1912
+ 赅 賅
1913
+ 赆 贐
1914
+ 赇 賕
1915
+ 赈 賑
1916
+ 赉 賚
1917
+ 赊 賒
1918
+ 赋 賦
1919
+ 赌 賭
1920
+ 赍 齎
1921
+ 赎 贖
1922
+ 赏 賞
1923
+ 赐 賜
1924
+ 赑 贔
1925
+ 赒 賙
1926
+ 赓 賡
1927
+ 赔 賠
1928
+ 赕 賧
1929
+ 赖 賴
1930
+ 赗 賵
1931
+ 赘 贅
1932
+ 赙 賻
1933
+ 赚 賺
1934
+ 赛 賽
1935
+ 赜 賾
1936
+ 赝 贗 贋
1937
+ 赞 贊 讚
1938
+ 赟 贇
1939
+ 赠 贈
1940
+ 赡 贍
1941
+ 赢 贏
1942
+ 赣 贛
1943
+ 赪 赬
1944
+ 赵 趙
1945
+ 赶 趕
1946
+ 趋 趨
1947
+ 趱 趲
1948
+ 趸 躉
1949
+ 跃 躍
1950
+ 跄 蹌
1951
+ 跖 蹠 跖
1952
+ 跞 躒
1953
+ 践 踐
1954
+ 跶 躂
1955
+ 跷 蹺
1956
+ 跸 蹕
1957
+ 跹 躚
1958
+ 跻 躋
1959
+ 踌 躊
1960
+ 踪 蹤
1961
+ 踬 躓
1962
+ 踯 躑
1963
+ 蹑 躡
1964
+ 蹒 蹣
1965
+ 蹰 躕
1966
+ 蹿 躥
1967
+ 躏 躪
1968
+ 躜 躦
1969
+ 躯 軀
1970
+ 輼 轀
1971
+ 车 車
1972
+ 轧 軋
1973
+ 轨 軌
1974
+ 轩 軒
1975
+ 轪 軑
1976
+ 轫 軔
1977
+ 转 轉
1978
+ 轭 軛
1979
+ 轮 輪
1980
+ 软 軟
1981
+ 轰 轟
1982
+ 轱 軲
1983
+ 轲 軻
1984
+ 轳 轤
1985
+ 轴 軸
1986
+ 轵 軹
1987
+ 轶 軼
1988
+ 轷 軤
1989
+ 轸 軫
1990
+ 轹 轢
1991
+ 轺 軺
1992
+ 轻 輕
1993
+ 轼 軾
1994
+ 载 載
1995
+ 轾 輊
1996
+ 轿 轎
1997
+ 辀 輈
1998
+ 辁 輇
1999
+ 辂 輅
2000
+ 较 較
2001
+ 辄 輒
2002
+ 辅 輔
2003
+ 辆 輛
2004
+ 辇 輦
2005
+ 辈 輩
2006
+ 辉 輝
2007
+ 辊 輥
2008
+ 辋 輞
2009
+ 辌 輬
2010
+ 辍 輟
2011
+ 辎 輜
2012
+ 辏 輳
2013
+ 辐 輻
2014
+ 辑 輯
2015
+ 辒 轀
2016
+ 输 輸
2017
+ 辔 轡
2018
+ 辕 轅
2019
+ 辖 轄
2020
+ 辗 輾
2021
+ 辘 轆
2022
+ 辙 轍
2023
+ 辚 轔
2024
+ 辞 辭
2025
+ 辟 闢 辟
2026
+ 辩 辯
2027
+ 辫 辮
2028
+ 边 邊
2029
+ 辽 遼
2030
+ 达 達
2031
+ 迁 遷
2032
+ 过 過
2033
+ 迈 邁
2034
+ 运 運
2035
+ 还 還
2036
+ 这 這
2037
+ 进 進
2038
+ 远 遠
2039
+ 违 違
2040
+ 连 連
2041
+ 迟 遲
2042
+ 迩 邇
2043
+ 迳 逕
2044
+ 迹 跡 蹟
2045
+ 适 適 适
2046
+ 选 選
2047
+ 逊 遜
2048
+ 递 遞
2049
+ 逦 邐
2050
+ 逻 邏
2051
+ 遗 遺
2052
+ 遥 遙
2053
+ 邓 鄧
2054
+ 邝 鄺
2055
+ 邬 鄔
2056
+ 邮 郵
2057
+ 邹 鄒
2058
+ 邺 鄴
2059
+ 邻 鄰
2060
+ 郁 鬱 郁
2061
+ 郏 郟
2062
+ 郐 鄶
2063
+ 郑 鄭
2064
+ 郓 鄆
2065
+ 郦 酈
2066
+ 郧 鄖
2067
+ 郸 鄲
2068
+ 酂 酇
2069
+ 酝 醞
2070
+ 酦 醱
2071
+ 酱 醬
2072
+ 酸 酸 痠
2073
+ 酽 釅
2074
+ 酾 釃
2075
+ 酿 釀
2076
+ 醖 醞
2077
+ 采 採 采 寀
2078
+ 释 釋
2079
+ 里 裏 里
2080
+ 鉴 鑑 鑒
2081
+ 銮 鑾
2082
+ 錾 鏨
2083
+ 钅 釒
2084
+ 钆 釓
2085
+ 钇 釔
2086
+ 针 針 鍼
2087
+ 钉 釘
2088
+ 钊 釗
2089
+ 钋 釙
2090
+ 钌 釕
2091
+ 钍 釷
2092
+ 钎 釺
2093
+ 钏 釧
2094
+ 钐 釤
2095
+ 钑 鈒
2096
+ 钒 釩
2097
+ 钓 釣
2098
+ 钔 鍆
2099
+ 钕 釹
2100
+ 钖 鍚
2101
+ 钗 釵
2102
+ 钘 鈃
2103
+ 钙 鈣
2104
+ 钚 鈈
2105
+ 钛 鈦
2106
+ 钜 鉅
2107
+ 钝 鈍
2108
+ 钞 鈔
2109
+ 钟 鍾 鐘 鈡
2110
+ 钠 鈉
2111
+ 钡 鋇
2112
+ 钢 鋼
2113
+ 钣 鈑
2114
+ 钤 鈐
2115
+ 钥 鑰 鈅
2116
+ 钦 欽
2117
+ 钧 鈞
2118
+ 钨 鎢
2119
+ 钩 鉤
2120
+ 钪 鈧
2121
+ 钫 鈁 鍅
2122
+ 钬 鈥
2123
+ 钭 鈄
2124
+ 钮 鈕
2125
+ 钯 鈀
2126
+ 钰 鈺
2127
+ 钱 錢
2128
+ 钲 鉦
2129
+ 钳 鉗
2130
+ 钴 鈷
2131
+ 钵 鉢
2132
+ 钶 鈳
2133
+ 钷 鉕
2134
+ 钸 鈽
2135
+ 钹 鈸
2136
+ 钺 鉞
2137
+ 钻 鑽 鉆
2138
+ 钼 鉬
2139
+ 钽 鉭
2140
+ 钾 鉀
2141
+ 钿 鈿
2142
+ 铀 鈾
2143
+ 铁 鐵
2144
+ 铂 鉑
2145
+ 铃 鈴
2146
+ 铄 鑠
2147
+ 铅 鉛
2148
+ 铆 鉚
2149
+ 铇 鉋
2150
+ 铈 鈰
2151
+ 铉 鉉
2152
+ 铊 鉈
2153
+ 铋 鉍
2154
+ 铌 鈮
2155
+ 铍 鈹
2156
+ 铎 鐸
2157
+ 铏 鉶
2158
+ 铐 銬
2159
+ 铑 銠
2160
+ 铒 鉺
2161
+ 铓 鋩
2162
+ 铔 錏
2163
+ 铕 ��
2164
+ 铖 鋮
2165
+ 铗 鋏
2166
+ 铘 鋣
2167
+ 铙 鐃
2168
+ 铚 銍
2169
+ 铛 鐺
2170
+ 铜 銅
2171
+ 铝 鋁
2172
+ 铞 銱
2173
+ 铟 銦
2174
+ 铠 鎧
2175
+ 铡 鍘
2176
+ 铢 銖
2177
+ 铣 銑
2178
+ 铤 鋌
2179
+ 铥 銩
2180
+ 铦 銛
2181
+ 铧 鏵
2182
+ 铨 銓
2183
+ 铩 鎩
2184
+ 铪 鉿
2185
+ 铫 銚
2186
+ 铬 鉻
2187
+ 铭 銘
2188
+ 铮 錚
2189
+ 铯 銫
2190
+ 铰 鉸
2191
+ 铱 銥
2192
+ 铲 鏟 剷
2193
+ 铳 銃
2194
+ 铴 鐋
2195
+ 铵 銨
2196
+ 银 銀
2197
+ 铷 銣
2198
+ 铸 鑄
2199
+ 铹 鐒
2200
+ 铺 鋪
2201
+ 铻 鋙
2202
+ 铼 錸
2203
+ 铽 鋱
2204
+ 链 鏈 鍊
2205
+ 铿 鏗
2206
+ 销 銷
2207
+ 锁 鎖
2208
+ 锂 鋰
2209
+ 锃 鋥
2210
+ 锄 鋤
2211
+ 锅 鍋
2212
+ 锆 鋯
2213
+ 锇 鋨
2214
+ 锈 鏽
2215
+ 锉 銼
2216
+ 锊 鋝
2217
+ 锋 鋒
2218
+ 锌 鋅
2219
+ 锍 鋶
2220
+ 锎 鐦
2221
+ 锏 鐧
2222
+ 锐 銳
2223
+ 锑 銻
2224
+ 锒 鋃
2225
+ 锓 鋟
2226
+ 锔 鋦
2227
+ 锕 錒
2228
+ 锖 錆
2229
+ 锗 鍺
2230
+ 锘 鍩
2231
+ 错 錯
2232
+ 锚 錨
2233
+ 锛 錛
2234
+ 锜 錡
2235
+ 锝 鍀
2236
+ 锞 錁
2237
+ 锟 錕
2238
+ 锠 錩
2239
+ 锡 錫
2240
+ 锢 錮
2241
+ 锣 鑼
2242
+ 锤 錘
2243
+ 锥 錐
2244
+ 锦 錦
2245
+ 锧 鑕
2246
+ 锨 鍁
2247
+ 锩 錈
2248
+ 锪 鍃
2249
+ 锫 錇 鉳
2250
+ 锬 錟
2251
+ 锭 錠
2252
+ 键 鍵
2253
+ 锯 鋸
2254
+ 锰 錳
2255
+ 锱 錙
2256
+ 锲 鍥
2257
+ 锳 鍈
2258
+ 锴 鍇
2259
+ 锵 鏘
2260
+ 锶 鍶
2261
+ 锷 鍔
2262
+ 锸 鍤
2263
+ 锹 鍬
2264
+ 锺 鍾
2265
+ 锻 鍛
2266
+ 锼 鎪
2267
+ 锽 鍠
2268
+ 锾 鍰
2269
+ 锿 鎄
2270
+ 镀 鍍
2271
+ 镁 鎂
2272
+ 镂 鏤
2273
+ 镃 鎡
2274
+ 镄 鐨
2275
+ 镅 鎇
2276
+ 镆 鏌
2277
+ 镇 鎮
2278
+ 镈 鎛
2279
+ 镉 鎘
2280
+ 镊 鑷
2281
+ 镋 钂 鎲
2282
+ 镌 鐫
2283
+ 镍 鎳
2284
+ 镎 鎿 錼
2285
+ 镏 鎦
2286
+ 镐 鎬
2287
+ 镑 鎊
2288
+ 镒 鎰
2289
+ 镓 鎵
2290
+ 镔 鑌
2291
+ 镕 鎔
2292
+ 镖 鏢
2293
+ 镗 鏜
2294
+ 镘 鏝
2295
+ 镙 鏍
2296
+ 镚 鏰
2297
+ 镛 鏞
2298
+ 镜 鏡
2299
+ 镝 鏑
2300
+ 镞 鏃
2301
+ 镟 鏇
2302
+ 镠 鏐
2303
+ 镡 鐔
2304
+ 镢 钁 鐝
2305
+ 镣 鐐
2306
+ 镤 鏷
2307
+ 镥 鑥
2308
+ 镦 鐓
2309
+ 镧 鑭
2310
+ 镨 鐠
2311
+ 镩 鑹
2312
+ 镪 鏹
2313
+ 镫 鐙
2314
+ 镬 鑊
2315
+ 镭 鐳
2316
+ 镮 鐶
2317
+ 镯 鐲
2318
+ 镰 鐮 鎌
2319
+ 镱 鐿
2320
+ 镲 鑔
2321
+ 镳 鑣
2322
+ 镴 鑞
2323
+ 镵 鑱
2324
+ 镶 鑲
2325
+ 长 長
2326
+ 门 門
2327
+ 闩 閂
2328
+ 闪 閃
2329
+ 闫 閆
2330
+ 闬 閈
2331
+ 闭 閉
2332
+ 问 問
2333
+ 闯 闖
2334
+ 闰 閏
2335
+ 闱 闈
2336
+ 闲 閒 閑
2337
+ 闳 閎
2338
+ 间 間
2339
+ 闵 閔
2340
+ 闶 閌
2341
+ 闷 悶
2342
+ 闸 閘
2343
+ 闹 鬧
2344
+ 闺 閨
2345
+ 闻 聞
2346
+ 闼 闥
2347
+ 闽 閩
2348
+ 闾 閭
2349
+ 闿 闓
2350
+ 阀 閥
2351
+ 阁 閣
2352
+ 阂 閡
2353
+ 阃 閫
2354
+ 阄 鬮
2355
+ 阅 閱
2356
+ 阆 閬
2357
+ 阇 闍
2358
+ 阈 閾
2359
+ 阉 閹
2360
+ 阊 閶
2361
+ 阋 鬩
2362
+ 阌 閿
2363
+ 阍 閽
2364
+ 阎 閻
2365
+ 阏 閼
2366
+ 阐 闡
2367
+ 阑 闌
2368
+ 阒 闃
2369
+ 阓 闠
2370
+ 阔 闊
2371
+ 阕 闋
2372
+ 阖 闔
2373
+ 阗 闐
2374
+ 阘 闒
2375
+ 阙 闕
2376
+ 阚 闞
2377
+ 阛 闤
2378
+ 队 隊
2379
+ 阳 陽
2380
+ 阴 陰
2381
+ 阵 陣
2382
+ 阶 階
2383
+ 际 際
2384
+ 陆 陸
2385
+ 陇 隴
2386
+ 陈 陳
2387
+ 陉 陘
2388
+ 陕 陝
2389
+ 陦 隯
2390
+ 陧 隉
2391
+ 陨 隕
2392
+ 险 險
2393
+ 随 隨
2394
+ 隐 隱
2395
+ 隶 隸
2396
+ 隽 雋
2397
+ 难 難
2398
+ 雇 僱
2399
+ 雏 雛
2400
+ 雕 雕 鵰
2401
+ 雠 讎
2402
+ 雳 靂
2403
+ 雾 霧
2404
+ 霁 霽
2405
+ 霉 黴
2406
+ 霡 霢
2407
+ 霭 靄
2408
+ 靓 靚
2409
+ 靔 靝
2410
+ 静 靜
2411
+ 面 面 麪
2412
+ 靥 靨
2413
+ 鞑 韃
2414
+ 鞒 鞽
2415
+ 鞯 韉
2416
+ 鞲 韝
2417
+ 韦 韋
2418
+ 韧 韌
2419
+ 韨 韍
2420
+ 韩 韓
2421
+ 韪 韙
2422
+ 韫 韞
2423
+ 韬 韜
2424
+ 韵 韻
2425
+ 页 頁
2426
+ 顶 頂
2427
+ 顷 頃
2428
+ 顸 頇
2429
+ 项 項
2430
+ 顺 順
2431
+ 须 須 鬚
2432
+ 顼 頊
2433
+ 顽 頑
2434
+ 顾 顧
2435
+ 顿 頓
2436
+ 颀 頎
2437
+ 颁 頒
2438
+ 颂 頌
2439
+ 颃 頏
2440
+ 预 預
2441
+ 颅 顱
2442
+ 领 領
2443
+ 颇 頗
2444
+ 颈 頸
2445
+ 颉 頡
2446
+ 颊 頰
2447
+ 颋 頲
2448
+ 颌 頜
2449
+ 颍 潁
2450
+ 颎 熲
2451
+ 颏 頦
2452
+ 颐 頤
2453
+ 频 頻
2454
+ 颒 頮
2455
+ 颓 頹
2456
+ 颔 頷
2457
+ 颕 頴
2458
+ 颖 穎
2459
+ 颗 顆
2460
+ 题 題
2461
+ 颙 顒
2462
+ 颚 顎
2463
+ 颛 顓
2464
+ 颜 顏
2465
+ 额 額
2466
+ 颞 顳
2467
+ 颟 顢
2468
+ 颠 顛
2469
+ 颡 顙
2470
+ 颢 顥
2471
+ 颣 纇
2472
+ 颤 顫
2473
+ 颥 顬
2474
+ 颦 顰
2475
+ 颧 顴
2476
+ 风 風
2477
+ 飏 颺
2478
+ 飐 颭
2479
+ 飑 颮
2480
+ 飒 颯
2481
+ 飓 颶
2482
+ 飔 颸
2483
+ 飕 颼
2484
+ 飖 颻
2485
+ 飗 飀
2486
+ 飘 飄
2487
+ 飙 飆
2488
+ 飚 飈
2489
+ 飞 飛
2490
+ 飨 饗
2491
+ 餍 饜
2492
+ 饣 飠
2493
+ 饤 飣
2494
+ 饥 飢 饑
2495
+ 饦 飥
2496
+ 饧 餳
2497
+ 饨 飩
2498
+ 饩 餼
2499
+ 饪 飪
2500
+ 饫 飫
2501
+ 饬 飭
2502
+ 饭 飯
2503
+ 饮 飲
2504
+ 饯 餞
2505
+ 饰 飾
2506
+ 饱 飽
2507
+ 饲 飼
2508
+ 饳 飿
2509
+ 饴 飴
2510
+ 饵 餌
2511
+ 饶 饒
2512
+ 饷 餉
2513
+ 饸 餄
2514
+ 饹 餎
2515
+ 饺 餃
2516
+ 饻 餏
2517
+ 饼 餅
2518
+ 饽 餑
2519
+ 饾 餖
2520
+ 饿 餓
2521
+ 馀 餘
2522
+ 馁 餒
2523
+ 馂 餕
2524
+ 馃 餜
2525
+ 馄 餛
2526
+ 馅 餡
2527
+ 馆 館
2528
+ 馇 餷
2529
+ 馈 饋
2530
+ 馉 餶
2531
+ 馊 餿
2532
+ 馋 饞
2533
+ 馌 饁
2534
+ 馍 饃
2535
+ 馎 餺
2536
+ 馏 餾
2537
+ 馐 饈
2538
+ 馑 饉
2539
+ 馒 饅
2540
+ 馓 饊
2541
+ 馔 饌
2542
+ 馕 饢
2543
+ 马 馬
2544
+ 驭 馭
2545
+ 驮 馱
2546
+ 驯 馴
2547
+ 驰 馳
2548
+ 驱 驅
2549
+ 驲 馹
2550
+ 驳 駁
2551
+ 驴 驢
2552
+ 驵 駔
2553
+ 驶 駛
2554
+ 驷 駟
2555
+ 驸 駙
2556
+ 驹 駒
2557
+ 驺 騶
2558
+ 驻 駐
2559
+ 驼 駝
2560
+ 驽 駑
2561
+ 驾 駕
2562
+ 驿 驛
2563
+ 骀 駘
2564
+ 骁 驍
2565
+ 骂 罵
2566
+ 骃 駰
2567
+ 骄 驕
2568
+ 骅 驊
2569
+ 骆 駱
2570
+ 骇 駭
2571
+ 骈 駢
2572
+ 骉 驫
2573
+ 骊 驪
2574
+ 骋 騁
2575
+ 验 驗
2576
+ 骍 騂
2577
+ 骎 駸
2578
+ 骏 駿
2579
+ 骐 騏
2580
+ 骑 騎
2581
+ 骒 騍
2582
+ 骓 騅
2583
+ 骔 騌
2584
+ 骕 驌
2585
+ 骖 驂
2586
+ 骗 騙
2587
+ 骘 騭
2588
+ 骙 騤
2589
+ 骚 騷
2590
+ 骛 騖
2591
+ 骜 驁
2592
+ 骝 騮
2593
+ 骞 騫
2594
+ 骟 騸
2595
+ 骠 驃
2596
+ 骡 騾
2597
+ 骢 驄
2598
+ 骣 驏
2599
+ 骤 驟
2600
+ 骥 驥
2601
+ 骦 驦
2602
+ 骧 驤
2603
+ 髅 髏
2604
+ 髋 髖
2605
+ 髌 髕
2606
+ 鬓 鬢
2607
+ 鬶 鬹
2608
+ 魇 魘
2609
+ 魉 魎
2610
+ 鱼 魚
2611
+ 鱽 魛
2612
+ 鱾 魢
2613
+ 鱿 魷
2614
+ 鲀 魨
2615
+ 鲁 魯
2616
+ 鲂 魴
2617
+ 鲃 䰾
2618
+ 鲄 魺
2619
+ 鲅 鮁
2620
+ 鲆 鮃
2621
+ 鲇 鮎
2622
+ 鲈 鱸
2623
+ 鲉 鮋
2624
+ 鲊 鮓
2625
+ 鲋 鮒
2626
+ 鲌 鮊
2627
+ 鲍 鮑
2628
+ 鲎 鱟
2629
+ 鲏 鮍
2630
+ 鲐 鮐
2631
+ 鲑 鮭
2632
+ 鲒 鮚
2633
+ 鲓 鮳
2634
+ 鲔 鮪
2635
+ 鲕 鮞
2636
+ 鲖 鮦
2637
+ 鲗 鰂
2638
+ 鲘 鮜
2639
+ 鲙 鱠
2640
+ 鲚 鱭
2641
+ 鲛 鮫
2642
+ 鲜 鮮
2643
+ 鲝 鮺
2644
+ 鲞 鯗
2645
+ 鲟 鱘
2646
+ 鲠 鯁
2647
+ 鲡 鱺
2648
+ 鲢 鰱
2649
+ 鲣 鰹
2650
+ 鲤 鯉
2651
+ 鲥 鰣
2652
+ 鲦 鰷
2653
+ 鲧 鯀
2654
+ 鲨 鯊
2655
+ 鲩 鯇
2656
+ 鲪 鮶
2657
+ 鲫 鯽
2658
+ 鲬 鯒
2659
+ 鲭 鯖
2660
+ 鲮 鯪
2661
+ 鲯 鯕
2662
+ 鲰 鯫
2663
+ 鲱 鯡
2664
+ 鲲 鯤
2665
+ 鲳 鯧
2666
+ 鲴 鯝
2667
+ 鲵 鯢
2668
+ 鲶 鯰
2669
+ 鲷 鯛
2670
+ 鲸 鯨
2671
+ 鲹 鰺
2672
+ 鲺 鯴
2673
+ 鲻 鯔
2674
+ 鲼 鱝
2675
+ 鲽 鰈
2676
+ 鲾 鰏
2677
+ 鲿 鱨
2678
+ 鳀 鯷
2679
+ 鳁 鰮
2680
+ 鳂 鰃
2681
+ 鳃 鰓
2682
+ 鳄 鱷
2683
+ 鳅 鰍
2684
+ 鳆 鰒
2685
+ 鳇 鰉
2686
+ 鳈 鰁
2687
+ 鳉 鱂
2688
+ 鳊 鯿
2689
+ 鳋 鰠
2690
+ 鳌 鰲
2691
+ 鳍 鰭
2692
+ 鳎 鰨
2693
+ 鳏 鰥
2694
+ 鳐 鰩
2695
+ 鳑 鰟
2696
+ 鳒 鰜
2697
+ 鳓 鰳
2698
+ 鳔 鰾
2699
+ 鳕 鱈
2700
+ 鳖 鱉
2701
+ 鳗 鰻
2702
+ 鳘 鰵
2703
+ 鳙 鱅
2704
+ 鳚 䲁
2705
+ 鳛 鰼
2706
+ 鳜 鱖
2707
+ 鳝 鱔
2708
+ 鳞 鱗
2709
+ 鳟 鱒
2710
+ 鳠 鱯
2711
+ 鳡 鱤
2712
+ 鳢 鱧
2713
+ 鳣 鱣
2714
+ 鳤 䲘
2715
+ 鸟 鳥
2716
+ 鸠 鳩
2717
+ 鸡 雞
2718
+ 鸢 鳶
2719
+ 鸣 鳴
2720
+ 鸤 鳲
2721
+ 鸥 鷗
2722
+ 鸦 鴉
2723
+ 鸧 鶬
2724
+ 鸨 鴇
2725
+ 鸩 鴆
2726
+ 鸪 鴣
2727
+ �� 鶇
2728
+ 鸬 鸕
2729
+ 鸭 鴨
2730
+ 鸮 鴞
2731
+ 鸯 鴦
2732
+ 鸰 鴒
2733
+ 鸱 鴟
2734
+ 鸲 鴝
2735
+ 鸳 鴛
2736
+ 鸴 鷽
2737
+ 鸵 鴕
2738
+ 鸶 鷥
2739
+ 鸷 鷙
2740
+ 鸸 鴯
2741
+ 鸹 鴰
2742
+ 鸺 鵂
2743
+ 鸻 鴴
2744
+ 鸼 鵃
2745
+ 鸽 鴿
2746
+ 鸾 鸞
2747
+ 鸿 鴻
2748
+ 鹀 鵐
2749
+ 鹁 鵓
2750
+ 鹂 鸝
2751
+ 鹃 鵑
2752
+ 鹄 鵠
2753
+ 鹅 鵝
2754
+ 鹆 鵒
2755
+ 鹇 鷳 鷴
2756
+ 鹈 鵜
2757
+ 鹉 鵡
2758
+ 鹊 鵲
2759
+ 鹋 鶓
2760
+ 鹌 鵪
2761
+ 鹍 鵾
2762
+ 鹎 鵯
2763
+ 鹏 鵬
2764
+ 鹐 鵮
2765
+ 鹑 鶉
2766
+ 鹒 鶊
2767
+ 鹓 鵷
2768
+ 鹔 鷫
2769
+ 鹕 鶘
2770
+ 鹖 鶡
2771
+ 鹗 鶚
2772
+ 鹘 鶻
2773
+ 鹙 鶖
2774
+ 鹚 鷀
2775
+ 鹛 鶥
2776
+ 鹜 鶩
2777
+ 鹝 鷊
2778
+ 鹞 鷂
2779
+ 鹟 鶲
2780
+ 鹠 鶹
2781
+ 鹡 鶺
2782
+ 鹢 鷁
2783
+ 鹣 鶼
2784
+ 鹤 鶴
2785
+ 鹥 鷖
2786
+ 鹦 鸚
2787
+ 鹧 鷓
2788
+ 鹨 鷚
2789
+ 鹩 鷯
2790
+ 鹪 鷦
2791
+ 鹫 鷲
2792
+ 鹬 鷸
2793
+ 鹭 鷺
2794
+ 鹮 䴉
2795
+ 鹯 鸇
2796
+ 鹰 鷹
2797
+ 鹱 鸌
2798
+ 鹲 鸏
2799
+ 鹳 鸛
2800
+ 鹴 鸘
2801
+ 鹾 鹺
2802
+ 麦 麥
2803
+ 麸 麩
2804
+ 麹 麴
2805
+ 麺 麪
2806
+ 麽 麼
2807
+ 黄 黃
2808
+ 黉 黌
2809
+ 黡 黶
2810
+ 黩 黷
2811
+ 黪 黲
2812
+ 黾 黽
2813
+ 鼋 黿
2814
+ 鼌 鼂
2815
+ 鼍 鼉
2816
+ 鼹 鼴
2817
+ 齐 齊
2818
+ 齑 齏
2819
+ 齿 齒
2820
+ 龀 齔
2821
+ 龁 齕
2822
+ 龂 齗
2823
+ 龃 齟
2824
+ 龄 齡
2825
+ 龅 齙
2826
+ 龆 齠
2827
+ 龇 齜
2828
+ 龈 齦
2829
+ 龉 齬
2830
+ 龊 齪
2831
+ 龋 齲
2832
+ 龌 齷
2833
+ 龙 龍
2834
+ 龚 龔
2835
+ 龛 龕
2836
+ 龟 龜
2837
+ 鿎 䃮
2838
+ 鿏 䥑
2839
+ 鿒 鿓
2840
+ 鿔 鎶
2841
+ 𠀾 𠁞
2842
+ 𠆲 儣
2843
+ 𠆿 𠌥
2844
+ 𠇹 俓
2845
+ 𠉂 㒓
2846
+ 𠉗 𠏢
2847
+ 𠋆 儭
2848
+ 𠚳 𠠎
2849
+ 𠛅 剾
2850
+ 𠛆 𠞆
2851
+ 𠛾 𪟖
2852
+ 𠡠 勑
2853
+ 𠮶 嗰
2854
+ 𠯟 哯
2855
+ 𠯠 噅
2856
+ 𠰱 㘉
2857
+ 𠰷 嚧
2858
+ 𠱞 囃
2859
+ 𠲥 𡅏
2860
+ 𠴛 𡃕
2861
+ 𠴢 𡄔
2862
+ 𠵸 𡄣
2863
+ 𠵾 㗲
2864
+ 𡋀 𡓾
2865
+ 𡋗 𡑭
2866
+ 𡋤 壗
2867
+ 𡍣 𡔖
2868
+ 𡒄 壈
2869
+ 𡝠 㜷
2870
+ 𡞋 㜗
2871
+ 𡞱 㜢
2872
+ 𡠟 孎
2873
+ 𡥧 孻
2874
+ 𡭜 𡮉
2875
+ 𡭬 𡮣
2876
+ 𡳃 𡳳
2877
+ 𡳒 𦘧
2878
+ 𡶴 嵼
2879
+ 𡸃 𡽗
2880
+ 𡺃 嶈
2881
+ 𡺄 嶘
2882
+ 𢋈 㢝
2883
+ 𢗓 㦛
2884
+ 𢘙 𢤱
2885
+ 𢘝 𢣚
2886
+ 𢘞 𢣭
2887
+ 𢙏 愻
2888
+ 𢙐 憹
2889
+ 𢙑 𢠼
2890
+ 𢙒 憢
2891
+ 𢙓 懀
2892
+ 𢛯 㦎
2893
+ 𢠁 懎
2894
+ 𢢐 𤢻
2895
+ 𢧐 戰
2896
+ 𢫊 𢷮
2897
+ 𢫞 𢶫
2898
+ 𢫬 摋
2899
+ 𢬍 擫
2900
+ 𢬦 𢹿
2901
+ 𢭏 擣
2902
+ 𢽾 斅
2903
+ 𣃁 斸
2904
+ 𣆐 曥
2905
+ 𣈣 𣋋
2906
+ 𣍨 𦢈
2907
+ 𣍯 腪
2908
+ 𣍰 脥
2909
+ 𣎑 臗
2910
+ 𣏢 槫
2911
+ 𣐕 桱
2912
+ 𣐤 欍
2913
+ 𣑶 𣠲
2914
+ 𣒌 楇
2915
+ 𣓿 橯
2916
+ 𣔌 樤
2917
+ 𣗊 樠
2918
+ 𣗋 欓
2919
+ 𣗙 㰙
2920
+ 𣘐 㯤
2921
+ 𣘓 𣞻
2922
+ 𣘴 檭
2923
+ 𣘷 𣝕
2924
+ 𣚚 欘
2925
+ 𣞎 𣠩
2926
+ 𣨼 殢
2927
+ 𣭤 𣯴
2928
+ 𣯣 𣯩
2929
+ 𣱝 氭
2930
+ 𣲗 湋
2931
+ 𣲘 潕
2932
+ 𣳆 㵗
2933
+ 𣶩 澅
2934
+ 𣶫 𣿉
2935
+ 𣶭 𪷓
2936
+ 𣷷 𤅶
2937
+ 𣸣 濆
2938
+ 𣺼 灙
2939
+ 𣺽 𤁣
2940
+ 𣽷 瀃
2941
+ 𤆡 熓
2942
+ 𤆢 㷍
2943
+ 𤇃 爄
2944
+ 𤇄 熌
2945
+ 𤇭 爖
2946
+ 𤇹 熚
2947
+ 𤈶 熉
2948
+ 𤈷 㷿
2949
+ 𤊀 𤒎
2950
+ 𤊰 𤓩
2951
+ 𤋏 熡
2952
+ 𤎺 𤓎
2953
+ 𤎻 𤑳
2954
+ 𤙯 𤛮
2955
+ 𤝢 𤢟
2956
+ 𤞃 獩
2957
+ 𤞤 玁
2958
+ 𤠋 㺏
2959
+ 𤦀 瓕
2960
+ 𤩽 瓛
2961
+ 𤳄 𤳸
2962
+ 𤶊 癐
2963
+ 𤶧 𤸫
2964
+ 𤻊 㿗
2965
+ 𤽯 㿧
2966
+ 𤾀 皟
2967
+ 𤿲 麬
2968
+ 𥁢 䀉
2969
+ 𥅘 𥌃
2970
+ 𥅴 䀹
2971
+ 𥅿 𥊝
2972
+ 𥆧 瞤
2973
+ 𥇢 䁪
2974
+ 𥎝 䂎
2975
+ 𥐟 礒
2976
+ 𥐯 𥖅
2977
+ 𥐰 𥕥
2978
+ 𥐻 碙
2979
+ 𥞦 𥞵
2980
+ 𥧂 𥨐
2981
+ 𥩟 竚
2982
+ 𥩺 𥪂
2983
+ 𥫣 籅
2984
+ 𥬀 䉙
2985
+ 𥬞 籋
2986
+ 𥬠 篘
2987
+ 𥭉 𥵊
2988
+ 𥮋 𥸠
2989
+ 𥮜 䉲
2990
+ 𥮾 篸
2991
+ 𥱔 𥵃
2992
+ 𥹥 𥼽
2993
+ 𥺅 䊭
2994
+ 𥺇 𥽖
2995
+ 𦈈 𥿊
2996
+ 𦈉 緷
2997
+ 𦈋 綇
2998
+ 𦈌 綀
2999
+ 𦈎 繟
3000
+ 𦈏 緍
3001
+ 𦈐 縺
3002
+ 𦈑 緸
3003
+ 𦈒 𦂅
3004
+ 𦈓 䋿
3005
+ 𦈔 縎
3006
+ 𦈕 緰
3007
+ 𦈖 䌈
3008
+ 𦈗 𦃄
3009
+ 𦈘 䌋
3010
+ 𦈙 䌰
3011
+ 𦈚 縬
3012
+ 𦈛 繓
3013
+ 𦈜 䌖
3014
+ 𦈝 繏
3015
+ 𦈞 䌟
3016
+ 𦈟 䌝
3017
+ 𦈠 䌥
3018
+ 𦈡 繻
3019
+ 𦍠 䍽
3020
+ 𦛨 朥
3021
+ 𦝼 膢
3022
+ 𦟗 𦣎
3023
+ 𦨩 𦪽
3024
+ 𦰏 蓧
3025
+ 𦰴 䕳
3026
+ 𦶟 爇
3027
+ 𦶻 𦾟
3028
+ 𦻕 蘟
3029
+ 𧉐 𧕟
3030
+ 𧉞 䗿
3031
+ 𧌥 𧎈
3032
+ 𧏖 蠙
3033
+ 𧏗 蠀
3034
+ 𧑏 蠾
3035
+ 𧒭 𧔥
3036
+ 𧜭 䙱
3037
+ 𧝝 襰
3038
+ 𧝧 𧟀
3039
+ 𧮪 詀
3040
+ 𧳕 𧳟
3041
+ 𧹑 䞈
3042
+ 𧹒 買
3043
+ 𧹓 𧶔
3044
+ 𧹔 賬
3045
+ 𧹕 䝻
3046
+ 𧹖 賟
3047
+ 𧹗 贃
3048
+ 𧿈 𨇁
3049
+ 𨀁 躘
3050
+ 𨀱 𨄣
3051
+ 𨁴 𨅍
3052
+ 𨂺 𨈊
3053
+ 𨄄 𨈌
3054
+ 𨅛 䠱
3055
+ 𨅫 𨇞
3056
+ 𨅬 躝
3057
+ 𨉗 軉
3058
+ 𨐅 軗
3059
+ 𨐆 𨊻
3060
+ 𨐇 𨏠
3061
+ 𨐈 輄
3062
+ 𨐉 𨎮
3063
+ 𨐊 𨏥
3064
+ 𨑹 䢨
3065
+ 𨟳 𨣞
3066
+ 𨠨 𨣧
3067
+ 𨡙 𨢿
3068
+ 𨡺 𨣈
3069
+ 𨤰 𨤻
3070
+ 𨰾 鎷
3071
+ 𨰿 釳
3072
+ 𨱀 𨥛
3073
+ 𨱁 鈠
3074
+ 𨱂 鈋
3075
+ 𨱃 鈲
3076
+ 𨱄 鈯
3077
+ 𨱅 鉁
3078
+ 𨱆 龯
3079
+ 𨱇 銶
3080
+ 𨱈 鋉
3081
+ 𨱉 鍄
3082
+ 𨱊 𨧱
3083
+ 𨱋 錂
3084
+ 𨱌 鏆
3085
+ 𨱍 鎯
3086
+ 𨱎 鍮
3087
+ 𨱏 鎝
3088
+ 𨱐 𨫒
3089
+ 𨱑 鐄
3090
+ 𨱒 鏉
3091
+ 𨱓 鐎
3092
+ 𨱔 鐏
3093
+ 𨱕 𨮂
3094
+ 𨱖 䥩
3095
+ 𨷿 䦳
3096
+ 𨸀 𨳕
3097
+ 𨸁 𨳑
3098
+ 𨸂 閍
3099
+ 𨸃 閐
3100
+ 𨸄 䦘
3101
+ 𨸅 𨴗
3102
+ 𨸆 𨵩
3103
+ 𨸇 𨵸
3104
+ 𨸉 𨶀
3105
+ 𨸊 𨶏
3106
+ 𨸋 𨶲
3107
+ 𨸌 𨶮
3108
+ 𨸎 𨷲
3109
+ 𨸘 𨽏
3110
+ 𨸟 䧢
3111
+ 𩏼 䪏
3112
+ 𩏽 𩏪
3113
+ 𩏾 𩎢
3114
+ 𩏿 䪘
3115
+ 𩐀 䪗
3116
+ 𩓋 顂
3117
+ 𩖕 𩓣
3118
+ 𩖖 顃
3119
+ 𩖗 䫴
3120
+ 𩙥 颰
3121
+ 𩙦 𩗀
3122
+ 𩙧 䬞
3123
+ 𩙨 𩘹
3124
+ 𩙩 𩘀
3125
+ 𩙪 颷
3126
+ 𩙫 颾
3127
+ 𩙬 𩘺
3128
+ 𩙭 𩘝
3129
+ 𩙮 䬘
3130
+ 𩙯 䬝
3131
+ 𩙰 𩙈
3132
+ 𩟿 𩚛
3133
+ 𩠀 𩚥
3134
+ 𩠁 𩚵
3135
+ 𩠂 𩛆
3136
+ 𩠃 𩛩
3137
+ 𩠅 𩟐
3138
+ 𩠆 𩜦
3139
+ 𩠇 䭀
3140
+ 𩠈 䭃
3141
+ 𩠉 𩜇
3142
+ 𩠊 𩜵
3143
+ 𩠋 𩝔
3144
+ 𩠌 餸
3145
+ 𩠎 𩞄
3146
+ 𩠏 𩞦
3147
+ 𩠠 𩠴
3148
+ 𩡖 𩡣
3149
+ 𩧦 𩡺
3150
+ 𩧨 駎
3151
+ 𩧩 𩤊
3152
+ 𩧪 䮾
3153
+ 𩧫 駚
3154
+ 𩧬 𩢡
3155
+ 𩧭 䭿
3156
+ 𩧮 𩢾
3157
+ 𩧯 驋
3158
+ 𩧰 䮝
3159
+ 𩧱 𩥉
3160
+ 𩧲 駧
3161
+ 𩧳 𩢸
3162
+ 𩧴 駩
3163
+ 𩧵 𩢴
3164
+ 𩧶 𩣏
3165
+ 𩧸 𩣫
3166
+ 𩧺 駶
3167
+ 𩧻 𩣵
3168
+ 𩧼 𩣺
3169
+ 𩧿 䮠
3170
+ 𩨀 騔
3171
+ 𩨁 䮞
3172
+ 𩨂 驄
3173
+ 𩨃 騝
3174
+ 𩨄 騪
3175
+ 𩨅 𩤸
3176
+ 𩨆 𩤙
3177
+ 𩨇 䮫
3178
+ 𩨈 騟
3179
+ 𩨉 𩤲
3180
+ 𩨊 騚
3181
+ 𩨋 𩥄
3182
+ 𩨌 𩥑
3183
+ 𩨍 𩥇
3184
+ 𩨎 龭
3185
+ 𩨏 䮳
3186
+ 𩨐 𩧆
3187
+ 𩩈 䯤
3188
+ 𩬣 𩭙
3189
+ 𩬤 𩰀
3190
+ 𩭹 鬖
3191
+ 𩯒 𩯳
3192
+ 𩰰 𩰹
3193
+ 𩲒 𩳤
3194
+ 𩴌 𩴵
3195
+ 𩽹 魥
3196
+ 𩽺 𩵩
3197
+ 𩽻 𩵹
3198
+ 𩽼 鯶
3199
+ 𩽽 𩶱
3200
+ 𩽾 鮟
3201
+ 𩽿 𩶰
3202
+ 𩾁 鯄
3203
+ 𩾂 䲖
3204
+ 𩾃 鮸
3205
+ 𩾄 𩷰
3206
+ 𩾅 𩸃
3207
+ 𩾆 𩸦
3208
+ 𩾇 鯱
3209
+ 𩾈 䱙
3210
+ 𩾊 䱬
3211
+ 𩾋 䱰
3212
+ 𩾌 鱇
3213
+ 𩾎 𩽇
3214
+ 𪉂 䲰
3215
+ 𪉃 鳼
3216
+ 𪉄 𩿪
3217
+ 𪉅 𪀦
3218
+ 𪉆 鴲
3219
+ 𪉈 鴜
3220
+ 𪉉 𪁈
3221
+ 𪉊 鷨
3222
+ 𪉋 𪀾
3223
+ 𪉌 𪁖
3224
+ 𪉍 鵚
3225
+ 𪉎 𪂆
3226
+ 𪉏 𪃏
3227
+ 𪉐 𪃍
3228
+ 𪉑 鷔
3229
+ 𪉒 𪄕
3230
+ 𪉔 𪄆
3231
+ 𪉕 𪇳
3232
+ 𪎈 䴬
3233
+ 𪎉 ���
3234
+ 𪎊 麨
3235
+ 𪎋 䴴
3236
+ 𪎌 麳
3237
+ 𪑅 䵳
3238
+ 𪔭 𪔵
3239
+ 𪚏 𪘀
3240
+ 𪚐 𪘯
3241
+ 𪜎 𠿕
3242
+ 𪞝 凙
3243
+ 𪟎 㔋
3244
+ 𪟝 勣
3245
+ 𪠀 𧷎
3246
+ 𪠟 㓄
3247
+ 𪠡 𠬙
3248
+ 𪠳 唓
3249
+ 𪠵 㖮
3250
+ 𪠸 嚛
3251
+ 𪠺 𠽃
3252
+ 𪠽 噹
3253
+ 𪡀 嘺
3254
+ 𪡃 嘪
3255
+ 𪡋 噞
3256
+ 𪡏 嗹
3257
+ 𪡛 㗿
3258
+ 𪡞 嘳
3259
+ 𪡺 𡃄
3260
+ 𪢌 㘓
3261
+ 𪢐 𡃤
3262
+ 𪢒 𡂡
3263
+ 𪢕 嚽
3264
+ 𪢖 𡅯
3265
+ 𪢠 囒
3266
+ 𪢮 圞
3267
+ 𪢸 墲
3268
+ 𪣆 埬
3269
+ 𪣒 堚
3270
+ 𪣻 塿
3271
+ 𪤄 𡓁
3272
+ 𪤚 壣
3273
+ 𪥠 𧹈
3274
+ 𪥫 孇
3275
+ 𪥰 嬣
3276
+ 𪥿 嬻
3277
+ 𪧀 孾
3278
+ 𪧘 寠
3279
+ 𪨊 㞞
3280
+ 𪨗 屩
3281
+ 𪨧 崙
3282
+ 𪨩 𡸗
3283
+ 𪨶 輋
3284
+ 𪨷 巗
3285
+ 𪨹 𡹬
3286
+ 𪩇 㟺
3287
+ 𪩎 巊
3288
+ 𪩘 巘
3289
+ 𪩛 𡿖
3290
+ 𪩷 幝
3291
+ 𪩸 幩
3292
+ 𪪏 廬
3293
+ 𪪑 㢗
3294
+ 𪪞 廧
3295
+ 𪪴 𢍰
3296
+ 𪪼 彃
3297
+ 𪫌 徿
3298
+ 𪫡 𢤩
3299
+ 𪫷 㦞
3300
+ 𪫺 憸
3301
+ 𪬚 𢣐
3302
+ 𪬯 𢤿
3303
+ 𪭝 𢯷
3304
+ 𪭢 摐
3305
+ 𪭧 擟
3306
+ 𪭯 𢶒
3307
+ 𪭵 掚
3308
+ 𪭾 撊
3309
+ 𪮃 㨻
3310
+ 𪮋 㩋
3311
+ 𪮖 撧
3312
+ 𪮳 𢺳
3313
+ 𪮶 攋
3314
+ 𪯋 㪎
3315
+ 𪰶 曊
3316
+ 𪱥 膹
3317
+ 𪱷 梖
3318
+ 𪲎 櫅
3319
+ 𪲔 欐
3320
+ 𪲛 檵
3321
+ 𪲮 櫠
3322
+ 𪳍 欇
3323
+ 𪳗 𣜬
3324
+ 𪴙 欑
3325
+ 𪵑 毊
3326
+ 𪵣 霼
3327
+ 𪵱 濿
3328
+ 𪶄 溡
3329
+ 𪶒 𤄷
3330
+ 𪶮 𣽏
3331
+ 𪷍 㵾
3332
+ 𪷽 灒
3333
+ 𪸕 熂
3334
+ 𪸩 煇
3335
+ 𪹀 𤑹
3336
+ 𪹠 𤓌
3337
+ 𪹳 爥
3338
+ 𪹹 𤒻
3339
+ 𪺣 𤘀
3340
+ 𪺪 𤜆
3341
+ 𪺭 犞
3342
+ 𪺷 獊
3343
+ 𪺸 𤠮
3344
+ 𪺻 㺜
3345
+ 𪺽 猌
3346
+ 𪻐 瑽
3347
+ 𪻨 瓄
3348
+ 𪻲 瑻
3349
+ 𪻺 璝
3350
+ 𪼋 㻶
3351
+ 𪼴 𤬅
3352
+ 𪽈 畼
3353
+ 𪽝 𤳷
3354
+ 𪽪 痮
3355
+ 𪽭 𤷃
3356
+ 𪽮 㿖
3357
+ 𪽴 𤺔
3358
+ 𪽷 瘱
3359
+ 𪾔 盨
3360
+ 𪾢 睍
3361
+ 𪾣 眝
3362
+ 𪾦 矑
3363
+ 𪾸 矉
3364
+ 𪿊 𥏝
3365
+ 𪿞 𥖲
3366
+ 𪿫 礮
3367
+ 𪿵 𥗇
3368
+ 𫀌 𥜰
3369
+ 𫀓 𥜐
3370
+ 𫀨 䅐
3371
+ 𫀬 䅳
3372
+ 𫀮 𥢷
3373
+ 𫁂 䆉
3374
+ 𫁟 竱
3375
+ 𫁡 鴗
3376
+ 𫁱 𥶽
3377
+ 𫁲 䉑
3378
+ 𫁳 𥯤
3379
+ 𫁷 䉶
3380
+ 𫁺 𥴼
3381
+ 𫂃 簢
3382
+ 𫂆 簂
3383
+ 𫂈 䉬
3384
+ 𫂖 𥴨
3385
+ 𫂿 𥻦
3386
+ 𫃗 𩏷
3387
+ 𫄙 糺
3388
+ 𫄚 䊺
3389
+ 𫄛 紟
3390
+ 𫄜 䋃
3391
+ 𫄝 𥾯
3392
+ 𫄞 䋔
3393
+ 𫄟 絁
3394
+ 𫄠 絙
3395
+ 𫄡 絧
3396
+ 𫄢 絥
3397
+ 𫄣 繷
3398
+ 𫄤 繨
3399
+ 𫄥 纚
3400
+ 𫄦 𦀖
3401
+ 𫄧 綖
3402
+ 𫄨 絺
3403
+ 𫄩 䋦
3404
+ 𫄪 𦅇
3405
+ 𫄫 綟
3406
+ 𫄬 緤
3407
+ 𫄭 緮
3408
+ 𫄮 䋼
3409
+ 𫄯 𦃩
3410
+ 𫄰 縍
3411
+ 𫄱 繬
3412
+ 𫄲 縸
3413
+ 𫄳 縰
3414
+ 𫄴 繂
3415
+ 𫄵 𦅈
3416
+ 𫄶 繈
3417
+ 𫄷 繶
3418
+ 𫄸 纁
3419
+ 𫄹 纗
3420
+ 𫅅 䍤
3421
+ 𫅗 羵
3422
+ 𫅥 𦒀
3423
+ 𫅭 䎙
3424
+ 𫅼 𦔖
3425
+ 𫆏 聻
3426
+ 𫆝 𦟼
3427
+ 𫆫 𦡝
3428
+ 𫇘 𦧺
3429
+ 𫇛 艣
3430
+ 𫇪 𦱌
3431
+ 𫇭 蔿
3432
+ 𫇴 蒭
3433
+ 𫇽 蕽
3434
+ 𫈉 蕳
3435
+ 𫈎 葝
3436
+ 𫈟 蔯
3437
+ 𫈵 蕝
3438
+ 𫉁 薆
3439
+ 𫉄 藷
3440
+ 𫊪 䗅
3441
+ 𫊮 蠦
3442
+ 𫊸 蟜
3443
+ 𫊹 𧒯
3444
+ 𫊻 蟳
3445
+ 𫋇 蟂
3446
+ 𫋌 蟘
3447
+ 𫋲 䙔
3448
+ 𫋷 襗
3449
+ 𫋹 襓
3450
+ 𫋻 襘
3451
+ 𫌀 襀
3452
+ 𫌇 襵
3453
+ 𫌋 𧞫
3454
+ 𫌨 覼
3455
+ 𫌪 覛
3456
+ 𫌫 𧡴
3457
+ 𫌬 𧢄
3458
+ 𫌭 覹
3459
+ 𫌯 䚩
3460
+ 𫍐 𧭹
3461
+ 𫍙 訑
3462
+ 𫍚 訞
3463
+ 𫍛 訜
3464
+ 𫍜 詓
3465
+ 𫍝 諫
3466
+ 𫍞 𧦝
3467
+ 𫍟 𧦧
3468
+ 𫍠 䛄
3469
+ 𫍡 詑
3470
+ 𫍢 譊
3471
+ 𫍣 詷
3472
+ 𫍤 譑
3473
+ 𫍥 誂
3474
+ 𫍦 譨
3475
+ 𫍧 誺
3476
+ 𫍨 誫
3477
+ 𫍩 諣
3478
+ 𫍪 誋
3479
+ 𫍫 䛳
3480
+ 𫍬 誷
3481
+ 𫍭 𧩕
3482
+ 𫍮 誳
3483
+ 𫍯 諴
3484
+ 𫍰 諰
3485
+ 𫍱 諯
3486
+ 𫍲 謏
3487
+ 𫍳 諥
3488
+ 𫍴 謱
3489
+ 𫍵 謸
3490
+ 𫍶 𧩼
3491
+ 𫍷 謉
3492
+ 𫍸 謆
3493
+ 𫍹 謯
3494
+ 𫍺 𧫝
3495
+ 𫍻 譆
3496
+ 𫍼 𧬤
3497
+ 𫍽 譞
3498
+ 𫍾 𧭈
3499
+ 𫍿 譾
3500
+ 𫎆 豵
3501
+ 𫎌 貗
3502
+ 𫎦 贚
3503
+ 𫎧 䝭
3504
+ 𫎨 𧸘
3505
+ 𫎩 賝
3506
+ 𫎪 䞋
3507
+ 𫎫 贉
3508
+ 𫎬 贑
3509
+ 𫎭 䞓
3510
+ 𫎱 䟐
3511
+ 𫎳 䟆
3512
+ 𫎸 𧽯
3513
+ 𫎺 䟃
3514
+ 𫏃 䠆
3515
+ 𫏆 蹳
3516
+ 𫏋 蹻
3517
+ 𫏌 𨂐
3518
+ 𫏐 蹔
3519
+ 𫏑 𨇽
3520
+ 𫏕 𨆪
3521
+ 𫏞 𨇰
3522
+ 𫏨 𨇤
3523
+ 𫐄 軏
3524
+ 𫐅 軕
3525
+ 𫐆 轣
3526
+ 𫐇 軜
3527
+ 𫐈 軷
3528
+ 𫐉 軨
3529
+ 𫐊 軬
3530
+ 𫐋 𨎌
3531
+ 𫐌 軿
3532
+ 𫐍 𨌈
3533
+ 𫐎 輢
3534
+ 𫐏 輖
3535
+ 𫐐 輗
3536
+ 𫐑 輨
3537
+ 𫐒 輷
3538
+ 𫐓 輮
3539
+ 𫐔 𨍰
3540
+ 𫐕 轊
3541
+ 𫐖 轇
3542
+ 𫐗 轐
3543
+ 𫐘 轗
3544
+ 𫐙 轠
3545
+ 𫐷 遱
3546
+ 𫑘 鄟
3547
+ 𫑡 鄳
3548
+ 𫑷 醶
3549
+ 𫓥 釟
3550
+ 𫓦 釨
3551
+ 𫓧 鈇
3552
+ 𫓨 鈛
3553
+ 𫓩 鏦
3554
+ 𫓪 鈆
3555
+ 𫓫 𨥟
3556
+ 𫓬 鉔
3557
+ 𫓭 鉠
3558
+ 𫓮 𨪕
3559
+ 𫓯 銈
3560
+ 𫓰 銊
3561
+ 𫓱 鐈
3562
+ 𫓲 銁
3563
+ 𫓳 𨰋
3564
+ 𫓴 鉾
3565
+ 𫓵 鋠
3566
+ 𫓶 鋗
3567
+ 𫓷 𫒡
3568
+ 𫓸 錽
3569
+ 𫓹 錤
3570
+ 𫓺 鐪
3571
+ 𫓻 錜
3572
+ 𫓼 𨨛
3573
+ 𫓽 錝
3574
+ 𫓾 錥
3575
+ 𫓿 𨨢
3576
+ 𫔀 鍊
3577
+ 𫔁 鐼
3578
+ 𫔂 鍉
3579
+ 𫔃 𨰲
3580
+ 𫔄 鍒
3581
+ 𫔅 鎍
3582
+ 𫔆 䥯
3583
+ 𫔇 鎞
3584
+ 𫔈 鎙
3585
+ 𫔉 𨰃
3586
+ 𫔊 鏥
3587
+ 𫔋 䥗
3588
+ 𫔌 鏾
3589
+ 𫔍 鐇
3590
+ 𫔎 鐍
3591
+ 𫔏 𨬖
3592
+ 𫔐 𨭸
3593
+ 𫔑 𨭖
3594
+ 𫔒 𨮳
3595
+ 𫔓 𨯟
3596
+ 𫔔 鑴
3597
+ 𫔕 𨰥
3598
+ 𫔖 𨲳
3599
+ 𫔭 開
3600
+ 𫔮 閒
3601
+ 𫔯 閗
3602
+ 𫔰 閞
3603
+ 𫔲 𨴹
3604
+ 𫔴 閵
3605
+ 𫔵 䦯
3606
+ 𫔶 闑
3607
+ 𫔽 𨼳
3608
+ 𫕚 𩀨
3609
+ 𫕥 霣
3610
+ 𫕨 𩅙
3611
+ 𫖃 靧
3612
+ 𫖅 䪊
3613
+ 𫖇 鞾
3614
+ 𫖑 𩎖
3615
+ 𫖒 韠
3616
+ 𫖓 𩏂
3617
+ 𫖔 韛
3618
+ 𫖕 韝
3619
+ 𫖖 𩏠
3620
+ 𫖪 𩑔
3621
+ 𫖫 䪴
3622
+ 𫖬 䪾
3623
+ 𫖭 𩒎
3624
+ 𫖮 顗
3625
+ 𫖯 頫
3626
+ 𫖰 䫂
3627
+ 𫖱 䫀
3628
+ 𫖲 䫟
3629
+ 𫖳 頵
3630
+ 𫖴 𩔳
3631
+ 𫖵 𩓥
3632
+ 𫖶 顅
3633
+ 𫖷 𩔑
3634
+ 𫖸 願
3635
+ 𫖹 顣
3636
+ 𫖺 䫶
3637
+ 𫗇 䫻
3638
+ 𫗈 𩗓
3639
+ 𫗉 𩗴
3640
+ 𫗊 䬓
3641
+ 𫗋 飋
3642
+ 𫗚 𩟗
3643
+ 𫗞 飦
3644
+ 𫗟 䬧
3645
+ 𫗠 餦
3646
+ 𫗡 𩚩
3647
+ 𫗢 飵
3648
+ 𫗣 飶
3649
+ 𫗤 𩛌
3650
+ 𫗥 餫
3651
+ 𫗦 餔
3652
+ 𫗧 餗
3653
+ 𫗨 𩛡
3654
+ 𫗩 饠
3655
+ 𫗪 餧
3656
+ 𫗫 餬
3657
+ 𫗬 餪
3658
+ 𫗭 餵
3659
+ 𫗮 餭
3660
+ 𫗯 餱
3661
+ 𫗰 䭔
3662
+ 𫗱 䭑
3663
+ 𫗳 𩝽
3664
+ 𫗴 饘
3665
+ 𫗵 饟
3666
+ 𫘛 馯
3667
+ 𫘜 馼
3668
+ 𫘝 駃
3669
+ 𫘞 駞
3670
+ 𫘟 駊
3671
+ 𫘠 駤
3672
+ 𫘡 駫
3673
+ 𫘣 駻
3674
+ 𫘤 騃
3675
+ 𫘥 騉
3676
+ 𫘦 騊
3677
+ 𫘧 騄
3678
+ 𫘨 騠
3679
+ 𫘩 騜
3680
+ 𫘪 騵
3681
+ 𫘫 騴
3682
+ 𫘬 騱
3683
+ 𫘭 騻
3684
+ 𫘮 䮰
3685
+ 𫘯 驓
3686
+ 𫘰 驙
3687
+ 𫘱 驨
3688
+ 𫘽 鬠
3689
+ 𫙂 𩯁
3690
+ 𫚈 鱮
3691
+ 𫚉 魟
3692
+ 𫚊 鰑
3693
+ 𫚋 鱄
3694
+ 𫚌 魦
3695
+ 𫚍 魵
3696
+ 𫚎 𩶁
3697
+ 𫚏 䱁
3698
+ 𫚐 䱀
3699
+ 𫚑 鮅
3700
+ 𫚒 鮄
3701
+ 𫚓 鮤
3702
+ 𫚔 鮰
3703
+ 𫚕 鰤
3704
+ 𫚖 鮆
3705
+ 𫚗 鮯
3706
+ 𫚘 𩻮
3707
+ 𫚙 鯆
3708
+ 𫚚 鮿
3709
+ 𫚛 鮵
3710
+ 𫚜 䲅
3711
+ 𫚝 𩸄
3712
+ 𫚞 鯬
3713
+ 𫚟 𩸡
3714
+ 𫚠 䱧
3715
+ 𫚡 鯞
3716
+ 𫚢 鰋
3717
+ 𫚣 鯾
3718
+ 𫚤 鰦
3719
+ 𫚥 鰕
3720
+ 𫚦 鰫
3721
+ 𫚧 鰽
3722
+ 𫚨 𩻗
3723
+ 𫚩 𩻬
3724
+ 𫚪 鱊
3725
+ 𫚫 鱢
3726
+ 𫚬 𩼶
3727
+ 𫚭 鱲
3728
+ 𫛚 鳽
3729
+ 𫛛 鳷
3730
+ 𫛜 鴀
3731
+ 𫛝 鴅
3732
+ 𫛞 鴃
3733
+ �� 鸗
3734
+ 𫛠 𩿤
3735
+ 𫛡 鴔
3736
+ 𫛢 鸋
3737
+ 𫛣 鴥
3738
+ 𫛤 鴐
3739
+ 𫛥 鵊
3740
+ 𫛦 鴮
3741
+ 𫛧 𪀖
3742
+ 𫛨 鵧
3743
+ 𫛩 鴳
3744
+ 𫛪 鴽
3745
+ 𫛫 鶰
3746
+ 𫛬 䳜
3747
+ 𫛭 鵟
3748
+ 𫛮 䳤
3749
+ 𫛯 鶭
3750
+ 𫛰 䳢
3751
+ 𫛱 鵫
3752
+ 𫛲 鵰
3753
+ 𫛳 鵩
3754
+ 𫛴 鷤
3755
+ 𫛵 鶌
3756
+ 𫛶 鶒
3757
+ 𫛷 鶦
3758
+ 𫛸 鶗
3759
+ 𫛹 𪃧
3760
+ 𫛺 䳧
3761
+ 𫛻 𪃒
3762
+ 𫛼 䳫
3763
+ 𫛽 鷅
3764
+ 𫛾 𪆷
3765
+ 𫜀 鷐
3766
+ 𫜁 鷩
3767
+ 𫜂 𪅂
3768
+ 𫜃 鷣
3769
+ 𫜄 鷷
3770
+ 𫜅 䴋
3771
+ 𫜊 𪉸
3772
+ 𫜑 麷
3773
+ 𫜒 䴱
3774
+ 𫜓 𪌭
3775
+ 𫜔 䴽
3776
+ 𫜕 𪍠
3777
+ 𫜙 䵴
3778
+ 𫜟 𪓰
3779
+ 𫜨 䶕
3780
+ 𫜩 齧
3781
+ 𫜪 齩
3782
+ 𫜫 𫜦
3783
+ 𫜬 齰
3784
+ 𫜭 齭
3785
+ 𫜮 齴
3786
+ 𫜯 𪙏
3787
+ 𫜰 齾
3788
+ 𫜲 龓
3789
+ 𫜳 䶲
3790
+ 𫝈 㑮
3791
+ 𫝋 𠐊
3792
+ 𫝦 㛝
3793
+ 𫝧 㜐
3794
+ 𫝨 媈
3795
+ 𫝩 嬦
3796
+ 𫝪 𡟫
3797
+ 𫝫 婡
3798
+ 𫝬 嬇
3799
+ 𫝭 孆
3800
+ 𫝮 孄
3801
+ 𫝵 嶹
3802
+ 𫞅 𦠅
3803
+ 𫞗 潣
3804
+ 𫞚 澬
3805
+ 𫞛 㶆
3806
+ 𫞝 灍
3807
+ 𫞠 爧
3808
+ 𫞡 爃
3809
+ 𫞢 𤛱
3810
+ 𫞣 㹽
3811
+ 𫞥 珼
3812
+ 𫞦 璾
3813
+ 𫞧 𤩂
3814
+ 𫞨 璼
3815
+ 𫞩 璊
3816
+ 𫞷 𥢶
3817
+ 𫟃 絍
3818
+ 𫟄 綋
3819
+ 𫟅 綡
3820
+ 𫟆 緟
3821
+ 𫟇 𦆲
3822
+ 𫟑 䖅
3823
+ 𫟕 䕤
3824
+ 𫟞 訨
3825
+ 𫟟 詊
3826
+ 𫟠 譂
3827
+ 𫟡 誴
3828
+ 𫟢 䜖
3829
+ 𫟤 䡐
3830
+ 𫟥 䡩
3831
+ 𫟦 䡵
3832
+ 𫟫 𨞺
3833
+ 𫟬 𨟊
3834
+ 𫟲 釚
3835
+ 𫟳 釲
3836
+ 𫟴 鈖
3837
+ 𫟵 鈗
3838
+ 𫟶 銏
3839
+ 𫟷 鉝
3840
+ 𫟸 鉽
3841
+ 𫟹 鉷
3842
+ 𫟺 䤤
3843
+ 𫟻 銂
3844
+ 𫟼 鐽
3845
+ 𫟽 𨧰
3846
+ 𫟾 𨩰
3847
+ 𫟿 鎈
3848
+ 𫠀 䥄
3849
+ 𫠁 鑉
3850
+ 𫠂 閝
3851
+ 𫠅 韚
3852
+ 𫠆 頍
3853
+ 𫠇 𩖰
3854
+ 𫠈 䫾
3855
+ 𫠊 䮄
3856
+ 𫠋 騼
3857
+ 𫠌 𩦠
3858
+ 𫠏 𩵦
3859
+ 𫠐 魽
3860
+ 𫠑 䱸
3861
+ 𫠒 鱆
3862
+ 𫠖 𩿅
3863
+ 𫠜 齯
3864
+ 𫢸 僤
3865
+ 𫧃 𣍐
3866
+ 𫧮 𪋿
3867
+ 𫫇 噁
3868
+ 𫬐 㘔
3869
+ 𫭟 塸
3870
+ 𫭢 埨
3871
+ 𫭼 𡑍
3872
+ 𫮃 墠
3873
+ 𫰛 娙
3874
+ 𫵷 㠣
3875
+ 𫶇 嵽
3876
+ 𫷷 廞
3877
+ 𫸩 彄
3878
+ 𬀩 暐
3879
+ 𬀪 晛
3880
+ 𬂩 梜
3881
+ 𬃊 櫍
3882
+ 𬇕 澫
3883
+ 𬇙 浿
3884
+ 𬇹 漍
3885
+ 𬉼 熰
3886
+ 𬊈 燖
3887
+ 𬊤 燀
3888
+ 𬍛 瓅
3889
+ 𬍡 璗
3890
+ 𬍤 璕
3891
+ 𬒈 礐
3892
+ 𬒗 𥗽
3893
+ 𬕂 篢
3894
+ 𬘓 紃
3895
+ 𬘘 紞
3896
+ 𬘡 絪
3897
+ 𬘩 綎
3898
+ 𬘫 綄
3899
+ 𬘬 綪
3900
+ 𬘭 綝
3901
+ 𬘯 綧
3902
+ 𬙂 縯
3903
+ 𬙊 纆
3904
+ 𬙋 纕
3905
+ 𬜬 蔄
3906
+ 𬜯 䓣
3907
+ 𬞟 蘋
3908
+ 𬟁 虉
3909
+ 𬟽 蝀
3910
+ 𬣙 訏
3911
+ 𬣞 詝
3912
+ 𬣡 諓
3913
+ 𬣳 詪
3914
+ 𬤇 諲
3915
+ 𬤊 諟
3916
+ 𬤝 譓
3917
+ 𬨂 軝
3918
+ 𬨎 輶
3919
+ 𬩽 鄩
3920
+ 𬪩 醲
3921
+ 𬬩 釴
3922
+ 𬬭 錀
3923
+ 𬬮 鋹
3924
+ 𬬱 釿
3925
+ 𬬸 鉥
3926
+ 𬬹 鉮
3927
+ 𬬻 鑪
3928
+ 𬬿 鉊
3929
+ 𬭁 鉧
3930
+ 𬭊 𨧀
3931
+ 𬭎 鋐
3932
+ 𬭚 錞
3933
+ 𬭛 𨨏
3934
+ 𬭤 鍭
3935
+ 𬭩 鎓
3936
+ 𬭬 鏏
3937
+ 𬭭 鏚
3938
+ 𬭯 䥕
3939
+ 𬭳 𨭎
3940
+ 𬭶 𨭆
3941
+ 𬭸 鏻
3942
+ 𬭼 鐩
3943
+ 𬮱 闉
3944
+ 𬮿 隑
3945
+ 𬯀 隮
3946
+ 𬯎 隤
3947
+ 𬱖 頔
3948
+ 𬱟 頠
3949
+ 𬳵 駓
3950
+ 𬳶 駉
3951
+ 𬳽 駪
3952
+ 𬳿 駼
3953
+ 𬴂 騑
3954
+ 𬴃 騞
3955
+ 𬴊 驎
3956
+ 𬶋 鮈
3957
+ 𬶍 鮀
3958
+ 𬶏 鮠
3959
+ 𬶐 鮡
3960
+ 𬶟 鯻
3961
+ 𬶠 鰊
3962
+ 𬶨 鱀
3963
+ 𬶭 鰶
3964
+ 𬶮 鱚
3965
+ 𬷕 鵏
3966
+ 𬸘 鶠
3967
+ 𬸚 鸑
3968
+ 𬸣 鶱
3969
+ 𬸦 鷟
3970
+ 𬸪 鷭
3971
+ 𬸯 鷿
3972
+ 𬹼 齘
3973
+ 𬺈 齮
3974
+ 𬺓 齼
3975
+ 𰬸 繐
3976
+ 𰰨 菕
3977
+ 𰶎 譅
3978
+ 𰾄 鋂
3979
+ 𰾭 鑀
3980
+ 𱊜 𪈼
data/dict/rules/tw_variants.tsv ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 僞 偽
2
+ 啓 啟
3
+ 喫 吃
4
+ 嫺 嫻
5
+ 嬀 媯
6
+ 峯 峰
7
+ 幺 么
8
+ 擡 抬
9
+ 棱 稜
10
+ 檐 簷
11
+ 污 汙
12
+ 泄 洩
13
+ 潙 溈
14
+ 潨 潀
15
+ 爲 為
16
+ 牀 床
17
+ 痹 痺
18
+ 癡 痴
19
+ 皁 皂
20
+ 着 著
21
+ 睾 睪
22
+ 祕 秘
23
+ 竈 灶
24
+ 糉 粽
25
+ 繮 韁
26
+ 纔 才
27
+ 羣 群
28
+ 脣 唇
29
+ 蔘 參
30
+ 蔿 蒍
31
+ 衆 眾
32
+ 裏 裡
33
+ 覈 核
34
+ 踊 踴
35
+ 鉢 缽
36
+ 鍼 針
37
+ 鮎 鯰
38
+ 麪 麵
39
+ 齶 顎
data/dict/variant_rank.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"order": {"㐹": ["㑶", "㐹"], "万": ["萬", "万"], "丑": ["醜", "丑"], "个": ["個", "箇"], "丰": ["豐", "丰"], "了": ["了", "瞭"], "于": ["於", "于"], "云": ["雲", "云"], "亘": ["亘", "亙"], "仆": ["僕", "仆"], "仇": ["仇", "讎"], "仑": ["崙", "侖"], "价": ["價", "价"], "仿": ["仿", "彷"], "伙": ["夥", "伙"], "余": ["餘", "余"], "佛": ["佛", "彿"], "佣": ["傭", "佣"], "俊": ["俊", "儁"], "修": ["修", "脩"], "借": ["藉", "借"], "僵": ["僵", "殭"], "克": ["克", "剋"], "党": ["黨", "党"], "冬": ["冬", "鼕"], "冲": ["衝", "沖"], "凄": ["淒", "悽"], "准": ["準", "准"], "凌": ["凌", "淩"], "几": ["幾", "几"], "凶": ["兇", "凶"], "出": ["出", "齣"], "划": ["劃", "划"], "别": ["別", "彆"], "刮": ["刮", "颳"], "制": ["制", "製"], "勋": ["勳", "勛"], "千": ["千", "韆"], "升": ["升", "昇"], "卜": ["卜", "蔔"], "占": ["占", "佔"], "卤": ["鹵", "滷"], "卷": ["卷", "捲"], "厂": ["廠", "厂"], "历": ["歷", "曆"], "厘": ["釐", "厘"], "参": ["參", "蔘"], "发": ["發", "髮"], "只": ["只", "隻", "祇"], "台": ["台", "臺", "颱", "檯"], "叶": ["葉", "叶"], "叹": ["嘆", "歎"], "吁": ["籲", "吁"], "吃": ["吃", "喫"], "合": ["合", "閤"], "吊": ["吊", "弔"], "同": ["同", "衕"], "后": ["後", "后"], "向": ["向", "嚮", "曏"], "周": ["周", "週", "賙"], "咨": ["諮", "咨"], "咸": ["鹹", "咸"], "咽": ["咽", "嚥"], "哄": ["哄", "鬨"], "哗": ["嘩", "譁"], "唇": ["唇", "脣"], "啮": ["齧", "嚙"], "喂": ["餵", "喂"], "噪": ["噪", "譟"], "回": ["回", "迴"], "团": ["團", "糰"], "困": ["困", "睏"], "坛": ["壇", "罈"], "坝": ["壩", "垻"], "埙": ["塤", "壎"], "复": ["復", "複", "覆"], "夫": ["夫", "伕"], "夸": ["誇", "夸"], "奸": ["姦", "奸"], "姜": ["姜", "薑"], "娘": ["娘", "孃"], "娴": ["嫻", "嫺"], "宁": ["寧", "甯"], "它": ["它", "牠"], "家": ["家", "傢"], "尝": ["嘗", "嚐"], "尸": ["屍", "尸"], "尽": ["盡", "儘"], "局": ["局", "侷"], "岩": ["岩", "巖"], "岳": ["岳", "嶽"], "巨": ["巨", "鉅"], "布": ["布", "佈"], "帘": ["簾", "帘"], "席": ["席", "蓆"], "干": ["幹", "干", "乾"], "并": ["並", "併"], "幸": ["幸", "倖"], "广": ["廣", "广"], "庵": ["庵", "菴"], "弥": ["彌", "瀰"], "弦": ["弦", "絃"], "当": ["當", "噹"], "录": ["錄", "彔"], "彩": ["彩", "綵"], "征": ["徵", "征"], "御": ["禦", "御"], "志": ["志", "誌"], "念": ["念", "唸"], "恤": ["恤", "卹"], "恶": ["惡", "噁"], "愈": ["愈", "癒"], "愿": ["願", "愿"], "戚": ["戚", "慼"], "才": ["才", "纔"], "扎": ["扎", "紮"], "托": ["托", "託"], "扣": ["扣", "釦"], "折": ["折", "摺"], "抵": ["抵", "牴"], "拐": ["拐", "柺"], "挂": ["掛", "挂"], "挨": ["挨", "捱"], "挽": ["挽", "輓"], "据": ["據", "据"], "搜": ["搜", "蒐"], "摆": ["擺", "襬"], "斗": ["鬥", "斗"], "旋": ["旋", "鏇"], "昆": ["昆", "崑"], "暗": ["暗", "闇"], "曲": ["曲", "麴"], "术": ["術", "朮"], "朱": ["朱", "硃"], "朴": ["朴", "樸"], "杆": ["桿", "杆"], "杠": ["槓", "杠"], "杯": ["盃", "杯"], "杰": ["傑", "杰"], "松": ["松", "鬆"], "板": ["板", "闆"], "极": ["極", "极"], "柜": ["櫃", "柜"], "栗": ["栗", "慄"], "核": ["核", "覈"], "梁": ["梁", "樑"], "欲": ["欲", "慾"], "毁": ["毀", "燬", "譭"], "汇": ["匯", "彙"], "沈": ["沈", "瀋"], "沾": ["沾", "霑"], "泛": ["泛", "氾", "汎"], "注": ["注", "註"], "涂": ["塗", "涂"], "涌": ["湧", "涌"], "淀": ["澱", "淀"], "游": ["遊", "游"], "滟": ["灩", "灧"], "漓": ["漓", "灕"], "炼": ["煉", "鍊"], "烟": ["煙", "菸"], "熏": ["燻", "熏"], "玩": ["玩", "翫"], "璇": ["璇", "璿"], "症": ["症", "癥"], "皂": ["皂", "皁"], "矩": ["矩", "榘"], "确": ["確", "确"], "私": ["私", "俬"], "秋": ["秋", "鞦"], "种": ["種", "种"], "筑": ["築", "筑"], "签": ["簽", "籤"], "系": ["系", "係", "繫"], "纤": ["纖", "縴"], "绱": ["鞝", "緔"], "绷": ["繃", "綳"], "胄": ["冑", "胄"], "背": ["背", "揹"], "胜": ["勝", "胜"], "胡": ["胡", "鬍", "衚"], "脏": ["臟", "髒"], "腊": ["臘", "腊"], "腌": ["醃", "腌"], "膻": ["羶", "膻"], "致": ["致", "緻"], "舍": ["舍", "捨"], "艳": ["艷", "豔"], "芸": ["芸", "蕓"], "苏": ["蘇", "甦", "囌"], "苔": ["苔", "薹"], "苹": ["蘋", "苹"], "范": ["範", "范"], "荐": ["薦", "荐"], "荡": ["盪", "蕩"], "荫": ["蔭", "廕"], "药": ["藥", "葯"], "获": ["獲", "穫"], "蒙": ["蒙", "濛", "矇", "懞"], "蔑": ["蔑", "衊"], "虫": ["蟲", "虫"], "蚝": ["蠔", "蚝"], "蜡": ["蠟", "蜡"], "蝎": ["蠍", "蝎"], "表": ["表", "錶"], "袅": ["裊", "嫋"], "裥": ["襉", "襇"], "证": ["證", "証"], "谥": ["諡", "謚"], "谷": ["谷", "穀"], "赝": ["贗", "贋"], "赞": ["讚", "贊"], "跖": ["蹠", "跖"], "辟": ["闢", "辟"], "迹": ["跡", "蹟"], "适": ["適", "适"], "郁": ["鬱", "郁"], "酸": ["酸", "痠"], "采": ["採", "采", "寀"], "里": ["里", "裏"], "鉴": ["鑑", "鑒"], "针": ["針", "鍼"], "钟": ["鐘", "鍾", "鈡"], "钥": ["鑰", "鈅"], "钫": ["鍅", "鈁"], "钻": ["鑽", "鉆"], "铲": ["鏟", "剷"], "链": ["鏈", "鍊"], "锫": ["鉳", "錇"], "镋": ["钂", "鎲"], "镎": ["錼", "鎿"], "镢": ["钁", "鐝"], "镰": ["鐮", "鎌"], "闲": ["閒", "閑"], "雕": ["雕", "鵰"], "面": ["面", "麪"], "须": ["須", "鬚"], "饥": ["飢", "饑"], "鹇": ["鷴", "鷳"]}, "freq": {"勋": 0, "彔": 23, "布": 301361, "鞝": 0, "雕": 7751, "鏟": 722, "汎": 239, "剋": 1116, "鵰": 580, "玩": 82086, "弥": 0, "抵": 29498, "俊": 12363, "尝": 0, "柜": 360, "鬆": 17624, "齣": 1040, "沾": 2719, "纤": 0, "崙": 3331, "樑": 2863, "蔔": 2096, "賙": 11, "绷": 0, "矇": 285, "穀": 2545, "劃": 98028, "闢": 2231, "硃": 84, "蹟": 6668, "镰": 0, "衕": 32, "準": 130602, "夥": 12142, "濛": 582, "御": 6814, "薑": 1780, "襬": 215, "弦": 8610, "岩": 16830, "汇": 0, "裥": 0, "涌": 2838, "蔘": 307, "佈": 56214, "丰": 123, "誌": 39210, "嚮": 1446, "摆": 0, "鈅": 4, "廠": 72208, "姜": 3922, "采": 8259, "薦": 17013, "傢": 6370, "灩": 33, "鉴": 0, "乾": 22299, "澱": 2469, "淀": 516, "几": 348, "別": 205565, "灧": 2, "豐": 31918, "鎲": 0, "纖": 10477, "諮": 7138, "发": 0, "据": 460, "捲": 8893, "牠": 16297, "曲": 216878, "燻": 436, "尸": 371, "绱": 0, "注": 73380, "钥": 0, "党": 123, "佔": 24301, "苹": 39, "游": 27168, "席": 78816, "鐮": 1273, "熏": 396, "蚝": 78, "適": 62052, "勳": 9229, "埙": 0, "喫": 326, "裏": 12333, "划": 2820, "蒐": 2570, "涂": 739, "厘": 6845, "價": 113969, "確": 101004, "懞": 3, "藉": 22729, "周": 90587, "占": 35162, "毀": 30459, "迴": 23577, "鬚": 2745, "於": 1312864, "譟": 73, "剷": 457, "築": 48135, "覆": 23545, "蠔": 487, "余": 5157, "縴": 64, "曏": 0, "廣": 171565, "鷳": 26, "于": 14971, "证": 0, "參": 400744, "禦": 9122, "念": 70569, "板": 53291, "壇": 16617, "咸": 2376, "煙": 14373, "冲": 0, "岳": 4294, "愈": 8688, "甯": 424, "儘": 27904, "万": 138, "佣": 356, "蘇": 99623, "㑶": 0, "醃": 842, "鑰": 6957, "背": 58502, "種": 395292, "瀰": 649, "后": 17752, "滟": 0, "冬": 24147, "朮": 303, "捱": 190, "衊": 199, "恶": 0, "唸": 2257, "彩": 35576, "幸": 25853, "羶": 50, "塗": 10386, "仆": 269, "當": 399803, "盪": 3794, "幾": 105542, "諡": 259, "恤": 1622, "薹": 95, "沈": 8080, "係": 62420, "镎": 0, "胄": 74, "須": 62545, "菴": 45, "鍊": 4131, "癥": 650, "擺": 12932, "曆": 8805, "僵": 2478, "嚥": 482, "鐝": 0, "箇": 223, "私": 33093, "才": 122472, "系": 292386, "千": 72756, "托": 54810, "嫻": 1196, "衝": 44976, "託": 14120, "个": 0, "閒": 9397, "嘩": 695, "絃": 388, "彆": 293, "并": 0, "赞": 0, "症": 36765, "皁": 1, "齧": 415, "簽": 37940, "当": 0, "譭": 23, "據": 149785, "極": 86745, "扎": 11767, "姦": 2516, "幹": 27331, "淩": 493, "丑": 1921, "克": 400114, "醜": 4340, "范": 9718, "悽": 169, "團": 224531, "卹": 165, "烟": 0, "僕": 3231, "孃": 403, "鬍": 2716, "髒": 2396, "朱": 18398, "苔": 2146, "昇": 7222, "鍾": 6476, "錼": 160, "胡": 23546, "参": 0, "鍼": 9, "搜": 22745, "蕩": 3417, "饑": 1596, "氾": 504, "漓": 454, "唇": 8575, "摺": 3221, "湧": 4121, "亙": 153, "毁": 0, "筑": 1797, "樸": 2401, "韆": 219, "栗": 4642, "卤": 0, "合": 440915, "袅": 0, "寀": 8, "它": 179761, "历": 0, "釐": 16136, "闆": 8086, "柺": 38, "穫": 2162, "困": 25654, "荡": 0, "霑": 437, "併": 39454, "蘋": 19291, "种": 105, "贋": 18, "佛": 54112, "歷": 128385, "雲": 48516, "杠": 188, "歎": 1382, "咨": 1258, "鑽": 7488, "核": 86874, "採": 104353, "极": 14, "鐘": 46447, "适": 53, "锫": 0, "家": 621440, "弔": 638, "徵": 37931, "瞭": 12781, "嚐": 2650, "跡": 13041, "簾": 1711, "表": 405838, "药": 0, "颱": 15690, "蔑": 701, "侖": 2173, "复": 0, "燬": 229, "纔": 201, "闲": 0, "慾": 4510, "鉆": 132, "吊": 7623, "杰": 3458, "範": 59486, "迹": 0, "菸": 6451, "只": 223793, "瀋": 6843, "籲": 8007, "鈁": 21, "凄": 0, "帘": 43, "借": 19996, "翫": 2, "艳": 0, "襉": 1, "贗": 229, "謚": 35, "裊": 91, "巖": 833, "掛": 23892, "鏈": 15101, "註": 31275, "繃": 1212, "捨": 4497, "庵": 970, "睏": 135, "麪": 30, "腊": 51, "向": 219950, "旋": 40800, "鞦": 218, "綳": 2, "鹵": 2164, "製": 195427, "吃": 68673, "酸": 57845, "發": 880833, "錇": 5, "钫": 0, "蟲": 23301, "鹹": 2484, "屍": 9569, "吁": 395, "後": 876866, "傑": 47688, "慼": 18, "嘆": 3714, "覈": 29, "針": 38959, "面": 528018, "蓆": 103, "里": 274290, "制": 225746, "璇": 528, "饥": 0, "回": 197789, "餵": 2409, "儁": 56, "亘": 188, "叹": 0, "㐹": 0, "蹠": 384, "铲": 0, "钂": 1, "獲": 170683, "戚": 2746, "錶": 4707, "彙": 4841, "伙": 5440, "鍅": 342, "颳": 464, "录": 0, "塤": 17, "志": 46127, "倖": 5081, "閑": 1091, "閤": 107, "糰": 547, "干": 22480, "叶": 205, "修": 100377, "侷": 978, "鬥": 65804, "秋": 22424, "仇": 7375, "桿": 8815, "���": 28627, "葯": 317, "罈": 66, "贊": 13929, "昆": 12103, "並": 504193, "鹇": 0, "囌": 23, "鑒": 2204, "哄": 825, "遊": 203398, "坝": 0, "蝎": 35, "宁": 0, "廕": 2, "郁": 3314, "餘": 47777, "腌": 33, "週": 45598, "個": 1036052, "綵": 330, "蔭": 3294, "榘": 105, "卜": 7774, "蠟": 2855, "厂": 11, "准": 21974, "针": 0, "櫃": 10167, "鷴": 51, "彷": 3116, "仑": 0, "尽": 0, "鎿": 21, "滷": 742, "壎": 14, "镋": 0, "嶽": 1425, "麴": 441, "胜": 101, "杆": 4592, "崑": 1429, "挂": 134, "鬨": 225, "咽": 2013, "藥": 66759, "喂": 1179, "復": 74827, "臘": 16717, "複": 40642, "蠍": 1766, "征": 10798, "勝": 77182, "松": 37243, "臺": 81324, "云": 2304, "获": 0, "籤": 11639, "錄": 136660, "槓": 1720, "须": 0, "哗": 0, "拐": 1478, "牴": 351, "艷": 3285, "矩": 8420, "斗": 7764, "誇": 3621, "蜡": 6, "匯": 25031, "刮": 1876, "局": 149118, "荫": 0, "殭": 1695, "舍": 13219, "嚙": 399, "祇": 1352, "冑": 367, "伕": 158, "扣": 12530, "灕": 32, "辟": 868, "夫": 120083, "欲": 8856, "镢": 0, "脩": 177, "讎": 13, "揹": 378, "萬": 176064, "豔": 2015, "髮": 20972, "慄": 861, "讚": 14138, "价": 35, "沖": 10932, "广": 30, "煉": 6260, "璿": 126, "钟": 0, "脣": 158, "甦": 2107, "鬱": 5262, "嫺": 54, "釦": 132, "彿": 2607, "隻": 28963, "暗": 28524, "荐": 59, "蒙": 45036, "傭": 3332, "噹": 1083, "啮": 0, "愿": 692, "娘": 12020, "同": 541538, "壩": 3381, "炼": 0, "出": 882371, "娴": 0, "鏇": 31, "紮": 3891, "夸": 1837, "钁": 1, "垻": 56, "仿": 12437, "闇": 1309, "鉅": 1214, "脏": 0, "鎌": 739, "奸": 1092, "襇": 1, "緻": 5579, "鉳": 450, "卷": 17950, "升": 96716, "寧": 36100, "繫": 12164, "術": 161509, "朴": 6223, "嫋": 20, "挽": 2543, "飢": 1888, "鈡": 5, "彌": 8224, "勛": 1216, "痠": 372, "赝": 0, "噁": 1427, "谥": 0, "盃": 43193, "噪": 4287, "惡": 39973, "葉": 61789, "梁": 19258, "谷": 32815, "膻": 30, "致": 104980, "兇": 5786, "凶": 1837, "别": 0, "链": 0, "輓": 263, "台": 399155, "証": 1735, "檯": 2434, "臟": 12275, "鑑": 10245, "凌": 15384, "巨": 38003, "譁": 458, "折": 21220, "證": 108076, "衚": 31, "了": 1305551, "嘗": 13150, "癒": 4117, "杯": 14803, "签": 0, "跖": 159, "虫": 252, "盡": 28114, "苏": 0, "俬": 109, "願": 38015, "皂": 2302, "鼕": 4, "钻": 0, "淒": 423, "黨": 136221, "确": 35, "芸": 1924, "坛": 0, "术": 0, "挨": 1161, "緔": 0, "团": 0, "蕓": 57}}
data/model/tau.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "variant": 0.0,
3
+ "lexical": 3.0,
4
+ "style": 6.0
5
+ }
twinity-1.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:28b90f39fa5e4a353ced5a3966a9f8b84300ee14fe5ac2eebfdf079b84398f9f
3
+ size 106449346
twlat/__init__.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """TWLAT — 中國大陸中文 → 臺灣正體中文的確定性轉換器。
2
+
3
+ 以字典編譯的 conversion lattice 界定動作空間,8.9M 參數的模型只裁決
4
+ 語境相依的歧義,Viterbi 全域解碼 + 最小 splice 產生輸出。
5
+
6
+ >>> import twlat
7
+ >>> twlat.convert("这个程序有bug,请在服务器上重新部署。")
8
+ '這個程式有 bug,請在伺服器上重新部署。'
9
+
10
+ >>> conv = twlat.Converter(device="cpu")
11
+ >>> conv.convert_batch(["文本一", "文本二"])
12
+ ['文本一', '文本二']
13
+
14
+ 熱更新:`dict/lattice_lexicon.json` 重新編譯即可新增字典條目,
15
+ 不需要重新訓練(候選由共用 char embedding 動態編碼)。
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import functools
20
+ import pathlib
21
+
22
+ __version__ = "0.3.1"
23
+ __all__ = ["Converter", "convert", "convert_batch", "Decision", "Result",
24
+ "DEFAULT_CKPT", "__version__"]
25
+
26
+ REPO = pathlib.Path(__file__).resolve().parents[2]
27
+ DEFAULT_CKPT = REPO / "runs/v3/best.pt"
28
+
29
+
30
+ class Decision:
31
+ """模型對單一 lattice 邊做出的改寫決策。"""
32
+
33
+ __slots__ = ("start", "end", "source", "target", "utility", "rule_type")
34
+
35
+ def __init__(self, d: dict):
36
+ self.start, self.end = d["span"]
37
+ self.source = d["from"]
38
+ self.target = d["to"]
39
+ self.utility = d["utility"]
40
+ self.rule_type = d["rule_type"]
41
+
42
+ def __repr__(self) -> str:
43
+ return (f"Decision({self.source!r}→{self.target!r} @[{self.start},"
44
+ f"{self.end}) {self.rule_type} u={self.utility:.2f})")
45
+
46
+
47
+ class Result:
48
+ """單一段落的轉換結果。`str(result)` 即輸出文字。"""
49
+
50
+ __slots__ = ("text", "decisions", "fast_path")
51
+
52
+ def __init__(self, r):
53
+ self.text: str = r.output
54
+ self.decisions: list[Decision] = [Decision(d) for d in r.decisions]
55
+ self.fast_path: bool = r.fast_path
56
+
57
+ def __str__(self) -> str:
58
+ return self.text
59
+
60
+ def __repr__(self) -> str:
61
+ return f"Result({self.text!r}, {len(self.decisions)} decisions)"
62
+
63
+
64
+ class Converter:
65
+ """可重複使用的轉換器(載入一次模型,之後重複呼叫)。
66
+
67
+ Parameters
68
+ ----------
69
+ ckpt : 模型 checkpoint 路徑(預設 runs/v3/best.pt)
70
+ device : "cpu" / "mps" / "cuda";預設自動偵測。CPU 單執行緒吞吐最佳
71
+ (~11k 字/秒),見技術報告 §18.15。
72
+ preset : 操作點(見 twlat.decoder.PRESETS)——
73
+ "accuracy"(benchmark 最佳,最保守)、
74
+ "balanced"(產品預設)、"taiwanize"(額外修正陸式專用詞)、
75
+ "aggressive"(最大召回)。傳 None 則用 model/tau_v3.json。
76
+ tau : 直接指定 per-rule-group 門檻(覆寫 preset 的 τ)。
77
+ lexicon : 替代 lattice lexicon(熱更新用)。
78
+ """
79
+
80
+ def __init__(self, ckpt=None, device: str | None = None, tau=None,
81
+ lexicon=None, preset: str | None = "balanced"):
82
+ import sys
83
+ sys.path[:0] = [str(REPO / "src")]
84
+ from twlat.decoder import FO_BONUS, PRESETS
85
+ from twlat.runtime_v3 import TWLATV3Runtime
86
+ fo = 0.0
87
+ if preset is not None:
88
+ if preset not in PRESETS:
89
+ raise ValueError(f"preset 須為 {sorted(PRESETS)}")
90
+ tau = tau or PRESETS[preset]
91
+ fo = FO_BONUS.get(preset, 0.0)
92
+ self.preset = preset
93
+ self._rt = TWLATV3Runtime(str(ckpt or DEFAULT_CKPT), device=device,
94
+ tau=tau, lexicon_path=lexicon, fo_bonus=fo)
95
+
96
+ def convert(self, text: str) -> str:
97
+ """單段轉換,回傳文字。"""
98
+ return self._rt.convert_batch([text])[0].output
99
+
100
+ def convert_batch(self, texts: list[str], batch_size: int = 8) -> list[str]:
101
+ """批次轉換。batch_size=8 為 CPU 最佳操作點。"""
102
+ return [r.output for r in self._rt.convert_batch(texts, batch_size)]
103
+
104
+ def explain(self, text: str) -> Result:
105
+ """回傳含逐項決策的結果(span、來源形式、目標形式、效用、規則型別)。"""
106
+ return Result(self._rt.convert_batch([text])[0])
107
+
108
+ def explain_batch(self, texts: list[str], batch_size: int = 8) -> list[Result]:
109
+ return [Result(r) for r in self._rt.convert_batch(texts, batch_size)]
110
+
111
+ @property
112
+ def lexicon_version(self) -> str:
113
+ return self._rt.lb.version
114
+
115
+
116
+ @functools.lru_cache(maxsize=2)
117
+ def _default(device: str | None = None) -> Converter:
118
+ return Converter(device=device)
119
+
120
+
121
+ def convert(text: str, device: str | None = None) -> str:
122
+ """便利函式:轉換單段文字(首次呼叫會載入模型並快取)。"""
123
+ return _default(device).convert(text)
124
+
125
+
126
+ def convert_batch(texts: list[str], device: str | None = None,
127
+ batch_size: int = 8) -> list[str]:
128
+ """便利函式:批次轉換。"""
129
+ return _default(device).convert_batch(texts, batch_size)
twlat/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (9.04 kB). View file
 
twlat/__pycache__/decoder.cpython-311.pyc ADDED
Binary file (7.23 kB). View file
 
twlat/__pycache__/features.cpython-311.pyc ADDED
Binary file (15 kB). View file
 
twlat/__pycache__/lattice.cpython-311.pyc ADDED
Binary file (25.5 kB). View file
 
twlat/__pycache__/model_r.cpython-311.pyc ADDED
Binary file (32.8 kB). View file
 
twlat/__pycache__/model_v3.cpython-311.pyc ADDED
Binary file (24.4 kB). View file
 
twlat/__pycache__/normalize.cpython-311.pyc ADDED
Binary file (11.2 kB). View file
 
twlat/__pycache__/paths.cpython-311.pyc ADDED
Binary file (1.77 kB). View file
 
twlat/__pycache__/protect.cpython-311.pyc ADDED
Binary file (2.49 kB). View file
 
twlat/__pycache__/quotes.cpython-311.pyc ADDED
Binary file (4.46 kB). View file
 
twlat/__pycache__/runtime_v3.cpython-311.pyc ADDED
Binary file (19 kB). View file
 
twlat/cli.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """twlat 命令列介面。
2
+
3
+ twlat "这个程序有bug" # 單段轉換
4
+ cat in.txt | twlat # 從 stdin 逐行轉換
5
+ twlat -i in.txt -o out.txt # 檔案轉檔案
6
+ twlat --preset taiwanize "视频" # 選操作點
7
+ twlat --explain "他在那里" # 顯示逐項決策
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import sys
14
+
15
+
16
+ def main(argv: list[str] | None = None) -> int:
17
+ ap = argparse.ArgumentParser(
18
+ prog="twlat",
19
+ description="中國大陸中文 → 臺灣正體中文(確定性、可解釋、離線)")
20
+ ap.add_argument("text", nargs="*", help="要轉換的文字;省略則讀 stdin")
21
+ ap.add_argument("-i", "--input", help="輸入檔(每行一段)")
22
+ ap.add_argument("-o", "--output", help="輸出檔")
23
+ ap.add_argument("--preset", default="balanced",
24
+ choices=["accuracy", "balanced", "taiwanize", "aggressive"],
25
+ help="操作點(預設 balanced)")
26
+ ap.add_argument("--device", default="cpu",
27
+ help="cpu/mps/cuda(預設 cpu;單執行緒吞吐最佳)")
28
+ ap.add_argument("--threads", type=int, default=1,
29
+ help="torch 執行緒數(預設 1,實測最快)")
30
+ ap.add_argument("--batch-size", type=int, default=8)
31
+ ap.add_argument("--explain", action="store_true", help="輸出逐項決策 JSON")
32
+ ap.add_argument("--ckpt", default=None)
33
+ ap.add_argument("--version", action="store_true")
34
+ a = ap.parse_args(argv)
35
+
36
+ import twlat
37
+ if a.version:
38
+ print(twlat.__version__)
39
+ return 0
40
+
41
+ import torch
42
+ torch.set_num_threads(max(1, a.threads))
43
+
44
+ if a.text:
45
+ lines = [" ".join(a.text)]
46
+ elif a.input:
47
+ with open(a.input, encoding="utf-8") as fh:
48
+ lines = [ln.rstrip("\n") for ln in fh]
49
+ else:
50
+ lines = [ln.rstrip("\n") for ln in sys.stdin]
51
+ if not lines:
52
+ return 0
53
+
54
+ conv = twlat.Converter(ckpt=a.ckpt, device=a.device, preset=a.preset)
55
+
56
+ if a.explain:
57
+ out = []
58
+ for r in conv.explain_batch(lines, batch_size=a.batch_size):
59
+ out.append({"text": r.text,
60
+ "decisions": [{"span": [d.start, d.end],
61
+ "from": d.source, "to": d.target,
62
+ "utility": round(d.utility, 3),
63
+ "rule_type": d.rule_type}
64
+ for d in r.decisions]})
65
+ payload = json.dumps(out, ensure_ascii=False, indent=1)
66
+ else:
67
+ payload = "\n".join(conv.convert_batch(lines, batch_size=a.batch_size))
68
+
69
+ if a.output:
70
+ with open(a.output, "w", encoding="utf-8") as fh:
71
+ fh.write(payload + "\n")
72
+ else:
73
+ print(payload)
74
+ return 0
75
+
76
+
77
+ if __name__ == "__main__":
78
+ raise SystemExit(main())
twlat/decoder.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """V3 解碼器:lattice 上的 Viterbi + 似然比檢定 + 最小 splice。
2
+
3
+ 決策規則:非 keep 候選必須以 per-rule-group margin τ 勝過 keep
4
+ (u = logit[cand] − logit[keep] − τ > 0 才成為選項),
5
+ 再以 DP 選出總效用最大的**不重疊**編輯集合——重疊的邊在這裡競爭,
6
+ 取代 V2 的「最長優先預先裁剪」。
7
+
8
+ Determinism:效用嚴格大於才更新(tie 傾向 keep/先做出的決策),
9
+ 無隨機性,同輸入必同輸出。
10
+
11
+ 輸出是對 base 文本的最小 splice 編輯清單:非站點區段一個位元組都不動,
12
+ 從結構上根除 V2 renderer 的間距/標點慣例劣勢。
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import math
17
+ from dataclasses import dataclass
18
+
19
+ import numpy as np
20
+
21
+ from twlat.lattice import TAU_GROUP, Lattice, LatticeBuilder
22
+
23
+ DEFAULT_TAU = {"variant": 0.0, "lexical": 0.0, "style": 0.0}
24
+
25
+ # 已驗證的操作點(neutral-dev 校準,數字見技術報告 §18.16)。
26
+ # 三者的差別只在「要多少證據才動手」,模型與字典完全相同。
27
+ PRESETS = {
28
+ # 最大化 benchmark site accuracy:要求 20:1 勝算才改動。
29
+ # 副作用:孤立短句中 網絡→網路(8:1)這類正確改動會被壓掉。
30
+ "accuracy": {"variant": 0.0, "lexical": 3.0, "style": 6.0},
31
+ # 產品預設:2.7:1 勝算即改動。主觀行為符合直覺,benchmark 代價 −0.4pp。
32
+ "balanced": {"variant": 0.0, "lexical": 1.0, "style": 3.0},
33
+ # 最大召回:模型認為較可能就改(僅硬過濾與 input_only 把關)。
34
+ "aggressive": {"variant": 0.0, "lexical": 0.0, "style": 0.0},
35
+ }
36
+
37
+ # fo_bonus 建議值(配合 PRESETS 使用)。陸式專用形式(服務器/網絡/軟件/視頻,
38
+ # 見 LatticeBuilder.cn_only)保留時扣分——字典說它們不該是輸出。
39
+ # benchmark 代價 −0.28pp(gold 本身含這些形式,見報告 §18.17)。
40
+ FO_BONUS = {"accuracy": 0.0, "balanced": 0.0, "aggressive": 0.0,
41
+ "taiwanize": 4.0}
42
+ PRESETS["taiwanize"] = dict(PRESETS["balanced"])
43
+
44
+
45
+ @dataclass
46
+ class Edit:
47
+ start: int
48
+ end: int
49
+ replacement: str
50
+ observed: str
51
+ utility: float
52
+ rule_type: str
53
+
54
+
55
+ def decode(lb: LatticeBuilder, lat: Lattice, logits: np.ndarray,
56
+ tau: dict[str, float] | None = None,
57
+ fo_bonus: float = 0.0) -> list[Edit]:
58
+ """logits: [n_edges, C],與 lat.edges 對齊(C 為該批的候選欄數)。
59
+
60
+ τ 的量綱:候選與 keep 的 logit 差**就是**模型 softmax 下的對數機率比
61
+ (log-softmax 對每列減去同一常數,差不變),因此 τ 可直接讀成勝算比門檻——
62
+ τ=1 ≈ 2.7:1、τ=3 ≈ 20:1。PRESETS 提供三個已驗證的操作點。
63
+ """
64
+ tau = tau or DEFAULT_TAU
65
+ options: list[tuple[int, int, float, str, str, str]] = []
66
+ for i, e in enumerate(lat.edges):
67
+ if i >= len(logits):
68
+ break
69
+ g = lb.groups[e.gid]
70
+ members = [lb.strings[x] for x in g["m"]]
71
+ obs = members[e.obs_ix]
72
+ keep_s = float(logits[i, e.obs_ix])
73
+ if not math.isfinite(keep_s):
74
+ continue
75
+ # from_only 先驗:字典明確不背書 observed 作為輸出(服務器/視頻/博客)。
76
+ # 這類形式在 C3 網爬語料中大量出現且被標為 keep(實測 1% 資料中
77
+ # 服務器 有 12 筆 keep、0 筆 change),模型因此學到保留。
78
+ # 字典知識在解碼層補回:保留它需要額外證據。
79
+ if fo_bonus and lb.cn_only.get(e.gid, [False] * len(members))[e.obs_ix]:
80
+ keep_s -= fo_bonus
81
+ for j, cand in enumerate(members):
82
+ if j == e.obs_ix or j >= logits.shape[1]:
83
+ continue
84
+ if j < len(e.cand_kill) and e.cand_kill[j]:
85
+ continue
86
+ if g["io"][j]: # input_only 成員不可被引入
87
+ continue
88
+ if g.get("fo", [False] * len(members))[j]:
89
+ continue # 無規則背書為輸出(視頻/軟件)
90
+ s = float(logits[i, j])
91
+ if not math.isfinite(s):
92
+ continue
93
+ rid = lb.pairs.get((obs, cand), g["r"][j])
94
+ grp = TAU_GROUP.get(lb.rules[rid]["t"], "lexical")
95
+ u = s - keep_s - tau.get(grp, 0.0)
96
+ if u > 1e-9:
97
+ options.append((e.start, e.end, u, cand, obs,
98
+ lb.rules[rid]["t"]))
99
+
100
+ if not options:
101
+ return []
102
+
103
+ n = len(lat.text)
104
+ best = np.zeros(n + 1)
105
+ back: list[tuple | None] = [None] * (n + 1)
106
+ by_end: dict[int, list] = {}
107
+ for o in options:
108
+ by_end.setdefault(o[1], []).append(o)
109
+ for opts in by_end.values():
110
+ opts.sort(key=lambda o: (o[0], -o[2])) # 固定順序 → determinism
111
+
112
+ for p in range(1, n + 1):
113
+ best[p] = best[p - 1]
114
+ back[p] = None
115
+ for o in by_end.get(p, []):
116
+ cand_score = best[o[0]] + o[2]
117
+ if cand_score > best[p] + 1e-9: # 嚴格大於:tie 傾向 keep
118
+ best[p] = cand_score
119
+ back[p] = o
120
+
121
+ edits: list[Edit] = []
122
+ p = n
123
+ while p > 0:
124
+ o = back[p]
125
+ if o is None:
126
+ p -= 1
127
+ else:
128
+ edits.append(Edit(o[0], o[1], o[3], o[4], o[2], o[5]))
129
+ p = o[0]
130
+ edits.reverse()
131
+ return edits
132
+
133
+
134
+ def splice(text: str, edits: list[Edit]) -> str:
135
+ """最小編輯:只替換編輯 span,其餘位元組原樣。"""
136
+ out, prev = [], 0
137
+ for e in edits:
138
+ out.append(text[prev:e.start])
139
+ out.append(e.replacement)
140
+ prev = e.end
141
+ out.append(text[prev:])
142
+ return "".join(out)
twlat/features.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """V3 特徵組裝:pretrain_data(離線)、train_v3(collate)、runtime_v3(線上)
2
+ 三方共用的唯一實作——訓練與推論的特徵分佈必須 bit-consistent。
3
+
4
+ 分工備忘:
5
+ - 靜態特徵(rule type/domain/freq/conf…)以**成員歸屬規則**(group["r"][ci])
6
+ 編碼進 LexTables.static;
7
+ - 語境相依特徵(clue 命中/english anchor)以 **(observed, cand) pair 規則**
8
+ 在文本上計算(site_arrays)。
9
+ 兩者的規則來源不同是刻意的:pair 規則才知道「這個轉換方向」的語意條件。
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import math
15
+ import pathlib
16
+
17
+ import numpy as np
18
+ import regex
19
+
20
+ from twlat.paths import data_file
21
+
22
+ SEQ, S_MAX, C_MAX, L_MAX = 512, 128, 8, 8
23
+ HAN_VOCAB = 4096
24
+ HASH_SPACE = 59000
25
+ FEAT_DIM = 64
26
+ CLUE_WINDOW = 40
27
+ MASK_ID = 2
28
+
29
+ HAN = regex.compile(r"\p{Han}")
30
+ LATIN = regex.compile(r"[A-Za-z]")
31
+ DIGIT = regex.compile(r"\p{Nd}")
32
+ PROTECT = regex.compile(r"https?://\S+|[\w.+-]+@[\w-]+\.[\w.]+|`[^`]+`"
33
+ r"|[A-Za-z][A-Za-z0-9_.+-]{2,}")
34
+
35
+ RULE_TYPES = ["cross_strait", "variant_char", "tw_phrase", "confusable",
36
+ "ai_filler", "translationese", "variant", "political_coloring",
37
+ "typo", "other"]
38
+ RT_IX = {t: i for i, t in enumerate(RULE_TYPES)}
39
+
40
+
41
+ def enc_char(ch: str, vocab: dict) -> int:
42
+ i = vocab.get(ch)
43
+ return i if i is not None else HAN_VOCAB + (ord(ch) % HASH_SPACE)
44
+
45
+
46
+ def text_arrays(text: str, vocab: dict) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
47
+ """→ (ids int64[n], script uint8[n], prot bool[n])"""
48
+ n = len(text)
49
+ ids = np.zeros(n, np.int64)
50
+ script = np.zeros(n, np.uint8)
51
+ prot = np.zeros(n, bool)
52
+ for i, ch in enumerate(text):
53
+ ids[i] = enc_char(ch, vocab)
54
+ script[i] = 1 if HAN.match(ch) else 2 if LATIN.match(ch) else \
55
+ 3 if DIGIT.match(ch) else 0
56
+ for m in PROTECT.finditer(text):
57
+ prot[m.start():m.end()] = True
58
+ return ids, script, prot
59
+
60
+
61
+ def site_arrays(lb, edges, text: str) -> dict[str, np.ndarray]:
62
+ """lattice edges → 站點中繼陣列(無 gold;gold 由呼叫端投影)。"""
63
+ ns = len(edges)
64
+ lowered = text.lower()
65
+ a = {"span": np.zeros((ns, 2), np.int64),
66
+ "gid": np.zeros(ns, np.int32),
67
+ "obs": np.zeros(ns, np.int64),
68
+ "maskable": np.zeros(ns, bool),
69
+ "kill": np.zeros((ns, C_MAX), bool),
70
+ "clue": np.zeros((ns, C_MAX, 2), np.uint8),
71
+ "eng": np.zeros((ns, C_MAX), bool),
72
+ "flags": np.zeros(ns, np.uint8)}
73
+ for k, e in enumerate(edges):
74
+ g = lb.groups[e.gid]
75
+ members = [lb.strings[i] for i in g["m"]]
76
+ obs = members[e.obs_ix]
77
+ a["span"][k] = (e.start, e.end)
78
+ a["gid"][k] = e.gid
79
+ a["obs"][k] = e.obs_ix
80
+ a["maskable"][k] = g["mk"][e.obs_ix]
81
+ a["kill"][k, :len(e.cand_kill)] = e.cand_kill[:C_MAX]
82
+ a["flags"][k] = int(e.word_contained) | (int(e.word_crossing) << 1)
83
+ ctx = text[max(0, e.start - CLUE_WINDOW):e.end + CLUE_WINDOW]
84
+ for ci, cand in enumerate(members[:C_MAX]):
85
+ rid = lb.pairs.get((obs, cand), g["r"][ci])
86
+ rule = lb.rules[rid]
87
+ if rule["pc"]:
88
+ a["clue"][k, ci, 0] = min(sum(1 for c in rule["pc"] if c in ctx), 5)
89
+ if rule["nc"]:
90
+ a["clue"][k, ci, 1] = min(sum(1 for c in rule["nc"] if c in ctx), 5)
91
+ if rule["en"]:
92
+ a["eng"][k, ci] = rule["en"].lower() in lowered
93
+ return a
94
+
95
+
96
+ class LexTables:
97
+ """gid → 候選 token / 靜態特徵 展開表(collate 與 runtime 共用)。"""
98
+
99
+ def __init__(self, lexicon_path=None, vocab_path=None):
100
+ lexicon_path = lexicon_path or data_file("dict/lattice_lexicon.json")
101
+ vocab_path = vocab_path or data_file("dict/char_vocab_v3.json")
102
+ lex = json.loads(pathlib.Path(lexicon_path).read_text(encoding="utf-8"))
103
+ vocab = json.loads(pathlib.Path(vocab_path).read_text(encoding="utf-8"))
104
+ self.version = lex["version"]
105
+ strings, rules, freq = lex["strings"], lex["rules"], lex["freq"]
106
+ G = len(lex["groups"])
107
+ self.tok = np.zeros((G, C_MAX, L_MAX), np.int64)
108
+ self.ncand = np.zeros(G, np.int8)
109
+ self.length = np.zeros((G, C_MAX), np.float32)
110
+ self.static = np.zeros((G, C_MAX, FEAT_DIM), np.float32)
111
+ self.fo = np.zeros((G, C_MAX), bool)
112
+ for gid, g in enumerate(lex["groups"]):
113
+ mem = [strings[i] for i in g["m"]][:C_MAX]
114
+ for ci, flag in enumerate(g.get("fo", [])[:C_MAX]):
115
+ self.fo[gid, ci] = flag
116
+ self.ncand[gid] = len(mem)
117
+ top = max(freq.get(m, 0) for m in mem)
118
+ for ci, m in enumerate(mem):
119
+ for k, ch in enumerate(m[:L_MAX]):
120
+ self.tok[gid, ci, k] = enc_char(ch, vocab)
121
+ self.length[gid, ci] = len(m)
122
+ r = rules[g["r"][ci]]
123
+ f = self.static[gid, ci]
124
+ f[1 + RT_IX.get(r["t"], RT_IX["other"])] = 1.0
125
+ for d in r["d"]:
126
+ if d < 33:
127
+ f[11 + d] = 1.0
128
+ if not r["d"]:
129
+ f[11 + 34] = 1.0
130
+ fq = freq.get(m, 0)
131
+ f[50] = math.log10(fq + 1) / 7.0
132
+ f[51] = {None: 0.5, "low": 0.0, "high": 1.0}.get(r["cf"], 0.5)
133
+ f[52] = float(fq == top)
134
+ f[53] = len(m) / 6.0
135
+ f[54] = len(mem) / 8.0
136
+ f[58] = float(g["io"][ci])
137
+
138
+
139
+ def assemble_cands(lex: LexTables, gid, obs, clue, eng, flags, kill,
140
+ reveal_observed: bool):
141
+ """→ (cand_tok, cand_mask, cand_kill, cand_feat),C 裁到本組最大候選數。"""
142
+ C = int(lex.ncand[gid].max()) if len(gid) else 1
143
+ cand_tok = lex.tok[gid][:, :C]
144
+ cand_feat = lex.static[gid][:, :C].copy()
145
+ cand_mask = np.arange(C)[None, :] < lex.ncand[gid][:, None]
146
+ cand_kill = kill[:, :C].copy()
147
+ cand_kill[~cand_mask] = False
148
+ cand_feat[:, :, 47] = clue[:, :C, 0] / 5.0
149
+ cand_feat[:, :, 48] = clue[:, :C, 1] / 5.0
150
+ cand_feat[:, :, 49] = eng[:, :C]
151
+ cand_feat[:, :, 56] = (flags & 1)[:, None]
152
+ cand_feat[:, :, 57] = ((flags >> 1) & 1)[:, None]
153
+ cand_feat[:, :, 59] = cand_kill
154
+ cand_feat[:, :, 60] = lex.fo[gid][:, :C]
155
+ if reveal_observed:
156
+ ar = np.arange(C)[None, :]
157
+ cand_feat[:, :, 0] = (ar == obs[:, None]).astype(np.float32)
158
+ obs_len = lex.length[gid, obs]
159
+ cand_feat[:, :, 55] = (lex.length[gid][:, :C] - obs_len[:, None]) / 6.0
160
+ return cand_tok, cand_mask, cand_kill, cand_feat
161
+
162
+
163
+ def make_feat(script: np.ndarray, prot: np.ndarray, spans, t: int) -> np.ndarray:
164
+ """4 通道 token 特徵:script / 在站點 span 內 / 保護段 / 詞界。"""
165
+ f = np.zeros((t, 4), np.int64)
166
+ f[:, 0] = script
167
+ for s, e in spans:
168
+ f[min(int(s), t):min(int(e), t), 1] = 1
169
+ f[:, 2] = prot
170
+ f[1:, 3] = (script[1:] != script[:-1]).astype(np.int64)
171
+ return f
twlat/lattice.py ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Conversion lattice:V3 的核心資料結構。
2
+
3
+ 對 safe_normalize 後的文本,用 lattice lexicon(dict/lattice_lexicon.json)
4
+ 建出「所有字典允許的改寫」構成的圖:
5
+
6
+ 節點 = 字元位置
7
+ 邊 = (span, confusion group),group 的每個成員是一個候選(含 keep)
8
+
9
+ 字典知識的分工(PI 指示的問題拆解):
10
+ - **確定性可判的,lattice 直接判**:exceptions 例外詞(函式庫 內不得改 函式)、
11
+ positional_clues(好|消息 不觸發 消息→訊息)、詞界穿越(商調|制度 的 調製 邊)
12
+ ——這些命中即砍邊/砍候選,模型看不到也不需要看。
13
+ - **語境相依的,交給模型**:剩下的每條邊帶 64 維字典特徵
14
+ (領域 one-hot、規則型別、正反 clue 命中、語料頻率、editorial confidence…),
15
+ 模型只回答「這個語境下哪個成員成立」。
16
+
17
+ 重疊的邊一律保留,交給 Viterbi 全域解碼(src/twlat/decoder.py)。
18
+ """
19
+ from __future__ import annotations
20
+
21
+ import json
22
+ import math
23
+ import pathlib
24
+ from dataclasses import dataclass, field
25
+
26
+ import ahocorasick
27
+ import numpy as np
28
+
29
+ from twlat.paths import data_file
30
+
31
+ LEXICON_PATH = data_file("dict/lattice_lexicon.json")
32
+
33
+ # ---- 特徵配置(改動任何索引都要 bump lexicon SCHEMA_VERSION)----
34
+ N_DOMAINS = 36 # 33 實際領域 + other + 無標記 + 保留
35
+ RULE_TYPES = ["cross_strait", "variant_char", "tw_phrase", "confusable",
36
+ "ai_filler", "translationese", "variant", "political_coloring",
37
+ "typo", "other"]
38
+ FEAT_DIM = 64
39
+ CLUE_WINDOW = 40 # clue 比對視窗(±40 字),與 V2 preprocess_r 一致
40
+ CN_ONLY_RATIO = 0.35 # 陸式專用形式的頻率比上限(見 LatticeBuilder.cn_only)
41
+
42
+ # τ 校準用的規則分組(decoder 對非 keep 邊套 per-group margin)
43
+ TAU_GROUP = {"variant_char": "variant", "variant": "variant",
44
+ "cross_strait": "lexical", "confusable": "lexical",
45
+ "tw_phrase": "lexical", "typo": "lexical",
46
+ "ai_filler": "style", "translationese": "style",
47
+ "political_coloring": "style"}
48
+
49
+
50
+ @dataclass
51
+ class Edge:
52
+ start: int
53
+ end: int
54
+ gid: int # confusion group id
55
+ obs_ix: int # observed 形式在 group 正規順序中的 index
56
+ cand_kill: list[bool] # 各成員是否被硬過濾砍除(observed 永不砍)
57
+ word_crossing: bool = False # 邊穿越詞界(軟特徵;variant_char 穿越則硬砍)
58
+ word_contained: bool = False # 邊嚴格位於某個已知詞內(軟特徵)
59
+
60
+
61
+ @dataclass
62
+ class Lattice:
63
+ text: str
64
+ edges: list[Edge] = field(default_factory=list)
65
+
66
+
67
+ class LatticeBuilder:
68
+ def __init__(self, lexicon_path: pathlib.Path = LEXICON_PATH):
69
+ lex = json.loads(pathlib.Path(lexicon_path).read_text(encoding="utf-8"))
70
+ self.version: str = lex["version"]
71
+ self.strings: list[str] = lex["strings"]
72
+ self.groups: list[dict] = lex["groups"]
73
+ self.form2group: dict[str, int] = lex["form2group"]
74
+ self.rules: list[dict] = lex["rules"]
75
+ self.pairs: dict[tuple[str, str], int] = {
76
+ tuple(k.split("\t")): v for k, v in lex["pairs"].items()}
77
+ self.freq: dict[str, int] = lex["freq"]
78
+ self.exceptions: dict[str, list[int]] = lex["exceptions"]
79
+
80
+ self._a_sites = ahocorasick.Automaton()
81
+ for f in self.form2group:
82
+ self._a_sites.add_word(f, f)
83
+ self._a_sites.make_automaton()
84
+
85
+ self._a_exc = ahocorasick.Automaton()
86
+ for s in self.exceptions:
87
+ self._a_exc.add_word(s, s)
88
+ self._a_exc.make_automaton()
89
+
90
+ self._a_words = ahocorasick.Automaton()
91
+ for w in lex["word_forms"]:
92
+ self._a_words.add_word(w, w)
93
+ self._a_words.make_automaton()
94
+
95
+ # 陸式專用詞形:字典不背書為輸出(fo)**且**臺灣語料頻率遠低於
96
+ # 組內最高(< CN_ONLY_RATIO)。單靠 fo 不夠精確——項目/提升/設備
97
+ # 也只出現在某些規則的 from 側,但它們是正常臺灣詞(頻率比 ≈ 1.0)。
98
+ # 服務器 0.115、網絡 0.151、軟件 0.190、視頻 0.295 才是真正的陸式形式。
99
+ self.cn_only: dict[int, list[bool]] = {}
100
+ for gid, g in enumerate(self.groups):
101
+ mem = [self.strings[i] for i in g["m"]]
102
+ top = max(self.freq.get(m, 0) for m in mem) or 1
103
+ self.cn_only[gid] = [
104
+ bool(fo) and self.freq.get(m, 0) / top < CN_ONLY_RATIO
105
+ for m, fo in zip(mem, g.get("fo", [False] * len(mem)))]
106
+
107
+ # ---- 建圖 ----
108
+
109
+ def build(self, text: str) -> Lattice:
110
+ lat = Lattice(text=text)
111
+
112
+ # 例外詞 span(規則相依):exception 覆蓋邊 → 砍該規則的非 keep 候選
113
+ exc_spans: list[tuple[int, int, list[int]]] = []
114
+ for end, s in self._a_exc.iter(text):
115
+ exc_spans.append((end - len(s) + 1, end + 1, self.exceptions[s]))
116
+
117
+ # 詞界證據:最長優先不重疊
118
+ word_spans = self._longest_nonoverlap(self._a_words.iter(text))
119
+
120
+ for end, form in self._a_sites.iter(text):
121
+ start = end - len(form) + 1
122
+ end = end + 1
123
+ gid = self.form2group[form]
124
+ g = self.groups[gid]
125
+ members = [self.strings[i] for i in g["m"]]
126
+ obs_ix = members.index(form)
127
+
128
+ crossing, contained = self._word_relation(start, end, word_spans)
129
+ g_type = self.rules[g["r"][obs_ix]]["t"]
130
+ if crossing and g_type == "variant_char":
131
+ continue # 字級變體穿越詞界(商調|制度 的 調製)→ 整條邊砍掉
132
+
133
+ kill = [False] * len(members)
134
+ for ci, cand in enumerate(members):
135
+ if ci == obs_ix:
136
+ continue
137
+ rid = self.pairs.get((form, cand), g["r"][ci])
138
+ rule = self.rules[rid]
139
+ if self._exception_hit(start, end, rid, exc_spans):
140
+ kill[ci] = True
141
+ elif not self._positional_ok(text, start, end, rule):
142
+ kill[ci] = True
143
+ lat.edges.append(Edge(start, end, gid, obs_ix, kill,
144
+ crossing, contained))
145
+ lat.edges.sort(key=lambda e: (e.start, -(e.end - e.start), e.gid))
146
+ return lat
147
+
148
+ @staticmethod
149
+ def _longest_nonoverlap(hits) -> list[tuple[int, int]]:
150
+ spans = sorted(((end - len(w) + 1, end + 1) for end, w in hits),
151
+ key=lambda s: (s[0], -(s[1] - s[0])))
152
+ out: list[tuple[int, int]] = []
153
+ last = -1
154
+ for s, e in spans:
155
+ if s >= last:
156
+ out.append((s, e))
157
+ last = e
158
+ return out
159
+
160
+ @staticmethod
161
+ def _word_relation(start: int, end: int,
162
+ word_spans: list[tuple[int, int]]) -> tuple[bool, bool]:
163
+ crossing = contained = False
164
+ for ws, we in word_spans:
165
+ if we <= start:
166
+ continue
167
+ if ws >= end:
168
+ break
169
+ if (ws < start < we < end) or (start < ws < end < we):
170
+ crossing = True
171
+ if ws <= start and end <= we and (ws, we) != (start, end):
172
+ contained = True
173
+ return crossing, contained
174
+
175
+ @staticmethod
176
+ def _exception_hit(start: int, end: int, rid: int,
177
+ exc_spans: list[tuple[int, int, list[int]]]) -> bool:
178
+ for xs, xe, rids in exc_spans:
179
+ if xs <= start and end <= xe and (xs, xe) != (start, end) \
180
+ and rid in rids:
181
+ return True
182
+ return False
183
+
184
+ @staticmethod
185
+ def _positional_ok(text: str, start: int, end: int, rule: dict) -> bool:
186
+ """負向 positional 是否決;正向(before/after)存在時須至少滿足一個。"""
187
+ pos_req, pos_ok = False, False
188
+ for kind, arg in rule["po"]:
189
+ if kind == "not_after" and text[max(0, start - len(arg)):start] == arg:
190
+ return False
191
+ if kind == "not_before" and text[end:end + len(arg)] == arg:
192
+ return False
193
+ if kind in ("before", "after"):
194
+ pos_req = True
195
+ if kind == "before" and text[end:end + len(arg)] == arg:
196
+ pos_ok = True
197
+ if kind == "after" and text[max(0, start - len(arg)):start] == arg:
198
+ pos_ok = True
199
+ return pos_ok if pos_req else True
200
+
201
+ # ---- 特徵 ----
202
+
203
+ def edge_features(self, lat: Lattice, edge: Edge,
204
+ reveal_observed: bool) -> np.ndarray:
205
+ """[C, FEAT_DIM]。reveal_observed=False 用於 cloze 預訓練:
206
+ observed 相依的維度(is_keep、長度差)歸零,避免標籤洩漏。"""
207
+ g = self.groups[edge.gid]
208
+ members = [self.strings[i] for i in g["m"]]
209
+ obs = members[edge.obs_ix]
210
+ lo = max(0, edge.start - CLUE_WINDOW)
211
+ ctx = lat.text[lo:edge.end + CLUE_WINDOW]
212
+ top_freq = max(self.freq.get(m, 0) for m in members)
213
+
214
+ out = np.zeros((len(members), FEAT_DIM), dtype=np.float32)
215
+ for ci, cand in enumerate(members):
216
+ rid = self.pairs.get((obs, cand), g["r"][ci])
217
+ rule = self.rules[rid]
218
+ f = out[ci]
219
+ if reveal_observed:
220
+ f[0] = float(ci == edge.obs_ix)
221
+ f[55] = (len(cand) - len(obs)) / 6.0
222
+ t_ix = RULE_TYPES.index(rule["t"]) if rule["t"] in RULE_TYPES \
223
+ else RULE_TYPES.index("other")
224
+ f[1 + t_ix] = 1.0
225
+ for d in rule["d"]:
226
+ if d < N_DOMAINS - 3:
227
+ f[11 + d] = 1.0
228
+ if not rule["d"]:
229
+ f[11 + N_DOMAINS - 2] = 1.0 # 無領域標記
230
+ f[47] = min(sum(1 for c in rule["pc"] if c in ctx), 5) / 5.0
231
+ f[48] = min(sum(1 for c in rule["nc"] if c in ctx), 5) / 5.0
232
+ f[49] = float(bool(rule["en"]) and rule["en"].lower()
233
+ in lat.text.lower())
234
+ fq = self.freq.get(cand, 0)
235
+ f[50] = math.log10(fq + 1) / 7.0
236
+ f[51] = {None: 0.5, "low": 0.0, "high": 1.0}.get(rule["cf"], 0.5)
237
+ f[52] = float(fq == top_freq)
238
+ f[53] = len(cand) / 6.0
239
+ f[54] = len(members) / 8.0
240
+ f[56] = float(edge.word_contained)
241
+ f[57] = float(edge.word_crossing)
242
+ f[58] = float(g["io"][ci])
243
+ f[59] = float(edge.cand_kill[ci])
244
+ return out
245
+
246
+ # ---- 序列化(訓練 shard 用)----
247
+
248
+ def to_arrays(self, lat: Lattice, s_max: int, c_max: int
249
+ ) -> dict[str, np.ndarray] | None:
250
+ """定長陣列。site_gold = obs_ix(真實語料上 observed 即正解)。
251
+ 溢出時依優先序裁邊:lexical 規則邊 > 可遮罩 variant > 不可遮罩 variant。"""
252
+ edges = lat.edges
253
+ if len(edges) > s_max:
254
+ def prio(e: Edge):
255
+ g = self.groups[e.gid]
256
+ t = self.rules[g["r"][e.obs_ix]]["t"]
257
+ return (0 if TAU_GROUP.get(t) != "variant" else
258
+ 1 if g["mk"][e.obs_ix] else 2)
259
+ edges = sorted(edges, key=lambda e: (prio(e), e.start))[:s_max]
260
+ edges.sort(key=lambda e: (e.start, -(e.end - e.start), e.gid))
261
+
262
+ n = len(edges)
263
+ if n == 0:
264
+ return None
265
+ arr = {
266
+ "site_span": np.zeros((s_max, 2), dtype=np.int16),
267
+ "site_gid": np.full(s_max, -1, dtype=np.int32),
268
+ "site_gold": np.zeros(s_max, dtype=np.int8),
269
+ "site_ncand": np.zeros(s_max, dtype=np.int8),
270
+ "site_kill": np.zeros((s_max, c_max), dtype=bool),
271
+ "site_maskable": np.zeros(s_max, dtype=bool),
272
+ "n_sites": np.int16(n),
273
+ }
274
+ for i, e in enumerate(edges):
275
+ g = self.groups[e.gid]
276
+ arr["site_span"][i] = (e.start, e.end)
277
+ arr["site_gid"][i] = e.gid
278
+ arr["site_gold"][i] = e.obs_ix
279
+ arr["site_ncand"][i] = min(len(g["m"]), c_max)
280
+ arr["site_kill"][i, :len(e.cand_kill)] = e.cand_kill[:c_max]
281
+ arr["site_maskable"][i] = g["mk"][e.obs_ix]
282
+ return arr
283
+
284
+
285
+ MASK_ID = 2
286
+
287
+
288
+ def build_masked_view(ids: np.ndarray, spans: np.ndarray, maskable: np.ndarray,
289
+ mask_id: int = MASK_ID
290
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
291
+ """把可遮罩站點收合成單一 MASK token 的序列視圖。
292
+
293
+ 訓練 collate 與 runtime **必須共用此函式**——遮罩政策只依 observed 形式
294
+ (maskable 是 form 的函數),兩邊分佈才一致。
295
+
296
+ 重疊站點共用 MASK:以 (start, -len) 貪婪選出不重疊的遮罩單元,
297
+ 其餘站點的 m_span 透過索引投影落在覆蓋它的 MASK 位置(可含殘餘可見字元)。
298
+
299
+ 回傳 (masked_ids, m_spans[n,2], old2new[len+1])。
300
+ """
301
+ n = len(ids)
302
+ order = sorted(range(len(spans)),
303
+ key=lambda i: (int(spans[i][0]), -(int(spans[i][1]) - int(spans[i][0]))))
304
+ units: list[tuple[int, int]] = []
305
+ last = -1
306
+ for i in order:
307
+ if not maskable[i]:
308
+ continue
309
+ s, e = int(spans[i][0]), int(spans[i][1])
310
+ if s >= last:
311
+ units.append((s, e))
312
+ last = e
313
+
314
+ old2new = np.zeros(n + 1, np.int32)
315
+ segs: list[np.ndarray] = []
316
+ prev = pos = 0
317
+ mask_tok = np.array([mask_id], dtype=ids.dtype)
318
+ for s, e in units:
319
+ for k in range(prev, s):
320
+ old2new[k] = pos + (k - prev)
321
+ pos += s - prev
322
+ segs.append(ids[prev:s])
323
+ segs.append(mask_tok)
324
+ for k in range(s, e):
325
+ old2new[k] = pos
326
+ pos += 1
327
+ prev = e
328
+ for k in range(prev, n):
329
+ old2new[k] = pos + (k - prev)
330
+ pos += n - prev
331
+ segs.append(ids[prev:n])
332
+ old2new[n] = pos
333
+ masked = np.concatenate(segs) if segs else ids[:0]
334
+
335
+ m_spans = np.zeros((len(spans), 2), np.int32)
336
+ for i, (s, e) in enumerate(spans):
337
+ a = int(old2new[int(s)])
338
+ b = max(int(old2new[int(e)]), a + 1)
339
+ m_spans[i] = (a, b)
340
+ return masked, m_spans, old2new
341
+
342
+
343
+ def density_report(builder: LatticeBuilder, texts: list[str]) -> dict:
344
+ """邊密度統計,決定 S_MAX。"""
345
+ import collections
346
+ ns, per_type = [], collections.Counter()
347
+ for t in texts:
348
+ lat = builder.build(t)
349
+ ns.append(len(lat.edges))
350
+ for e in lat.edges:
351
+ g = builder.groups[e.gid]
352
+ per_type[builder.rules[g["r"][e.obs_ix]]["t"]] += 1
353
+ ns_arr = np.array(ns)
354
+ return {"n_texts": len(texts),
355
+ "sites_mean": round(float(ns_arr.mean()), 2),
356
+ "sites_p50": int(np.percentile(ns_arr, 50)),
357
+ "sites_p95": int(np.percentile(ns_arr, 95)),
358
+ "sites_p99": int(np.percentile(ns_arr, 99)),
359
+ "sites_max": int(ns_arr.max()),
360
+ "per_type": dict(per_type.most_common())}
twlat/model_r.py ADDED
@@ -0,0 +1,479 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """TWLAT-R(V2)模型(《04 實驗設計》§4)。
2
+
3
+ 任務:對文本中每個 proposal(字典判定「這裡可能要改」)在候選集中選一個。
4
+ 候選 index 0 **永遠是「維持原樣」**,即文本中實際出現的形式。
5
+
6
+ **核心約束(V2 的全部重點)**:
7
+ 禁止任何 per-candidate / per-site 的 trainable embedding lookup。
8
+ 候選只能由「表面字串 + 數值特徵」動態編碼,且與文本共用同一份 char embedding。
9
+ 因此新增字典條目不需要新增任何參數,held-out proposal 也不是隨機向量。
10
+ (V1 的 `cand_emb = nn.Embedding(4096, 192)` 佔 13% 參數並阻斷 zero-shot,就是要修掉的。)
11
+
12
+ 結構:
13
+
14
+ char_emb(共用)──┬─→ context encoder ──→ span mean-pool ──→ h_i [B,P,D]
15
+
16
+ └─→ 候選字串 mean-pool ──→ proj ──────────→ e_c [B,P,C,D]
17
+
18
+ score = MLP([h_i ⊕ e_c ⊕ (h_i * e_c) ⊕ cand_feat]) → [B,P,C]
19
+
20
+ context encoder 可切換(`TWLATRConfig.encoder`),兩者參數量刻意對齊以便做 scaling curve:
21
+ - "tcn" :4 層 dilated depthwise separable Conv1d(dilation 1/2/4/8、kernel 5)
22
+ - "local" :4 層 local-window Transformer(window 半徑 32、RoPE、pre-LN、GELU)
23
+
24
+ batch 欄位見 `TWLATR.forward` docstring。
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ from dataclasses import dataclass
30
+ from typing import Any
31
+
32
+ import torch
33
+ import torch.nn as nn
34
+ import torch.nn.functional as F
35
+
36
+ # Loss 權重(《04》§0 的錯誤分析:73% 的錯是「改了不該改」,故 keep_bias 直接壓它)
37
+ W_CAND = 1.0
38
+ W_KEEP_BIAS = 0.3
39
+ KEEP_MARGIN = 0.5
40
+ KEEP_INDEX = 0 # 候選 0 恆為「維持原樣」
41
+
42
+ ENCODERS = ("tcn", "local")
43
+
44
+
45
+ @dataclass
46
+ class TWLATRConfig:
47
+ """TWLAT-R 配置。目標參數量 3.0M–4.5M。
48
+
49
+ 註:d_model=160 只有約 2.5M(低於下限),故預設起跳為 192;
50
+ tools/param_count_r.py 會印出兩者的對照。
51
+ """
52
+
53
+ d_model: int = 192
54
+ n_heads: int = 4
55
+ ffn_dim: int = 768
56
+ dropout: float = 0.1
57
+
58
+ # context encoder:可切換,兩種都必須可跑
59
+ encoder: str = "local"
60
+ n_layers: int = 4
61
+ local_window: int = 32 # 半徑;|i-j| <= 32 才可見
62
+ conv_kernel: int = 5
63
+ conv_dilations: tuple[int, ...] = (1, 2, 4, 8)
64
+ # depthwise 之後的 pointwise 通道擴張倍率;設 1 即教科書式 depthwise separable,
65
+ # 設 2 可讓 tcn 與 local 的 mixer 參數量幾乎相等(scaling curve 才公平)
66
+ conv_expansion: int = 2
67
+
68
+ # char embedding(文本與候選共用;無任何 per-ID 候選表)
69
+ han_vocab: int = 4000 # 常用字直接查表;id >= han_vocab 走 hash
70
+ n_hash: int = 2
71
+ hash_buckets: int = 2048
72
+ feat_dim: int = 4 # script / 是否在 proposal span 內 / 是否保護段 / 詞界
73
+ feat_vocab: tuple[int, ...] = (16, 4, 4, 4)
74
+
75
+ # proposal / candidate 形狀
76
+ max_props: int = 48 # P
77
+ max_cands: int = 8 # C
78
+ cand_len: int = 6 # L,候選表面字串的最大字元數
79
+ cand_feat_dim: int = 12 # K
80
+ score_hidden: int = 512
81
+ # 候選表徵方式:
82
+ # "dynamic" —— 由表面字串經共用 char_emb 組合而成(V2 預設,可 zero-shot)
83
+ # "id" —— per-candidate learned lookup(H-B 的對照組,複製 V1 的失敗模式)
84
+ candidate_encoder: str = "dynamic"
85
+ cand_id_vocab: int = 4096
86
+
87
+ seq_len: int = 512
88
+ rope_base: float = 10000.0
89
+
90
+ def __post_init__(self) -> None:
91
+ assert self.encoder in ENCODERS, f"encoder 必須是 {ENCODERS}"
92
+ assert self.d_model % self.n_heads == 0
93
+ assert self.d_model % 2 == 0, "hash_dim = d_model // 2,需為偶數"
94
+ assert len(self.feat_vocab) == self.feat_dim
95
+ assert self.conv_kernel % 2 == 1, "kernel 需為奇數才能等長 padding"
96
+
97
+ @property
98
+ def head_dim(self) -> int:
99
+ return self.d_model // self.n_heads
100
+
101
+ @property
102
+ def hash_dim(self) -> int:
103
+ return self.d_model // 2
104
+
105
+ def dilation_at(self, i: int) -> int:
106
+ return self.conv_dilations[i % len(self.conv_dilations)]
107
+
108
+
109
+ # --------------------------------------------------------------------------- #
110
+ # RoPE
111
+ # --------------------------------------------------------------------------- #
112
+
113
+
114
+ def build_rope_cache(
115
+ seq_len: int, head_dim: int, base: float, device, dtype
116
+ ) -> tuple[torch.Tensor, torch.Tensor]:
117
+ """回傳 [T, head_dim//2] 的 cos / sin。"""
118
+ half = head_dim // 2
119
+ inv_freq = base ** (-torch.arange(half, device=device, dtype=torch.float32) / half)
120
+ pos = torch.arange(seq_len, device=device, dtype=torch.float32)
121
+ freqs = torch.outer(pos, inv_freq)
122
+ return freqs.cos().to(dtype), freqs.sin().to(dtype)
123
+
124
+
125
+ def apply_rope(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
126
+ """x: [B, H, T, D],對相鄰兩維做旋轉。"""
127
+ x_even, x_odd = x[..., 0::2], x[..., 1::2]
128
+ cos = cos[None, None, : x.shape[-2], :]
129
+ sin = sin[None, None, : x.shape[-2], :]
130
+ out = torch.stack([x_even * cos - x_odd * sin, x_even * sin + x_odd * cos], dim=-1)
131
+ return out.flatten(-2)
132
+
133
+
134
+ # --------------------------------------------------------------------------- #
135
+ # Embedding:文本與候選共用
136
+ # --------------------------------------------------------------------------- #
137
+
138
+ _HASH_MULT = (2654435761, 40503)
139
+ _HASH_ADD = (0, 987654321)
140
+
141
+
142
+ class CharEmbedding(nn.Module):
143
+ """常用字 4000 直接查表;id >= han_vocab 的罕字用 2 組 hash(buckets 2048, dim d/2)
144
+ 串接後投影。
145
+
146
+ **文本與候選字串共用這一份**:候選只是一串字元 id,沒有自己的 embedding 表,
147
+ 所以字典新增條目不會增加任何參數,未見過的字串也落在同一個表徵空間。
148
+ """
149
+
150
+ def __init__(self, cfg: TWLATRConfig):
151
+ super().__init__()
152
+ self.cfg = cfg
153
+ self.han = nn.Embedding(cfg.han_vocab, cfg.d_model)
154
+ self.hash = nn.ModuleList(
155
+ nn.Embedding(cfg.hash_buckets, cfg.hash_dim) for _ in range(cfg.n_hash)
156
+ )
157
+ self.hash_proj = nn.Linear(cfg.n_hash * cfg.hash_dim, cfg.d_model)
158
+
159
+ def forward(self, ids: torch.Tensor) -> torch.Tensor:
160
+ """ids: 任意形狀 [...],回傳 [..., d_model]。"""
161
+ cfg = self.cfg
162
+ ids = ids.clamp(min=0)
163
+ rare = ids >= cfg.han_vocab
164
+ han = self.han(ids.clamp(max=cfg.han_vocab - 1))
165
+ parts = []
166
+ for i, emb in enumerate(self.hash):
167
+ m = _HASH_MULT[i % len(_HASH_MULT)]
168
+ a = _HASH_ADD[i % len(_HASH_ADD)]
169
+ parts.append(emb((ids * m + a) % cfg.hash_buckets))
170
+ rare_vec = self.hash_proj(torch.cat(parts, dim=-1))
171
+ return torch.where(rare.unsqueeze(-1), rare_vec, han)
172
+
173
+
174
+ class TextFeatures(nn.Module):
175
+ """文本側的 4 個離散特徵;char embedding 由外部傳入,以免共用的表被重複註冊。"""
176
+
177
+ def __init__(self, cfg: TWLATRConfig):
178
+ super().__init__()
179
+ self.cfg = cfg
180
+ self.feat = nn.ModuleList(nn.Embedding(n, cfg.d_model) for n in cfg.feat_vocab)
181
+ self.ln = nn.LayerNorm(cfg.d_model)
182
+ self.drop = nn.Dropout(cfg.dropout)
183
+
184
+ def forward(self, x: torch.Tensor, feat: torch.Tensor) -> torch.Tensor:
185
+ for i, emb in enumerate(self.feat):
186
+ x = x + emb(feat[..., i].clamp(0, self.cfg.feat_vocab[i] - 1))
187
+ return self.drop(self.ln(x))
188
+
189
+
190
+ # --------------------------------------------------------------------------- #
191
+ # Context encoder(可切換)
192
+ # --------------------------------------------------------------------------- #
193
+
194
+
195
+ class LocalAttention(nn.Module):
196
+ """local-window self-attention + RoPE;|i-j| <= local_window 才可見。"""
197
+
198
+ def __init__(self, cfg: TWLATRConfig):
199
+ super().__init__()
200
+ self.cfg = cfg
201
+ self.qkv = nn.Linear(cfg.d_model, 3 * cfg.d_model)
202
+ self.out = nn.Linear(cfg.d_model, cfg.d_model)
203
+ self.drop = nn.Dropout(cfg.dropout)
204
+
205
+ def forward(self, x, attn_mask, rope):
206
+ b, t, _ = x.shape
207
+ h, d = self.cfg.n_heads, self.cfg.head_dim
208
+ q, k, v = self.qkv(x).view(b, t, 3, h, d).permute(2, 0, 3, 1, 4).unbind(0)
209
+ q, k = apply_rope(q, *rope), apply_rope(k, *rope)
210
+ p = self.cfg.dropout if self.training else 0.0
211
+ y = F.scaled_dot_product_attention(q, k, v, attn_mask=attn_mask, dropout_p=p)
212
+ y = y.transpose(1, 2).reshape(b, t, self.cfg.d_model)
213
+ return self.drop(self.out(y))
214
+
215
+
216
+ class ConvMixer(nn.Module):
217
+ """dilated depthwise separable Conv1d:depthwise(k, dilation) → pointwise 擴張 → GELU
218
+ → pointwise 還原。padding 位置先歸零,避免 pad 洩漏進感受野。"""
219
+
220
+ def __init__(self, cfg: TWLATRConfig, dilation: int):
221
+ super().__init__()
222
+ d, k = cfg.d_model, cfg.conv_kernel
223
+ pad = dilation * (k - 1) // 2 # 等長輸出
224
+ mid = d * cfg.conv_expansion
225
+ self.dw = nn.Conv1d(d, d, k, padding=pad, dilation=dilation, groups=d)
226
+ self.pw1 = nn.Conv1d(d, mid, 1)
227
+ self.pw2 = nn.Conv1d(mid, d, 1)
228
+ self.drop = nn.Dropout(cfg.dropout)
229
+
230
+ def forward(self, x, pad_mask, rope=None):
231
+ z = (x * pad_mask.unsqueeze(-1).to(x.dtype)).transpose(1, 2)
232
+ z = self.pw2(F.gelu(self.pw1(self.dw(z))))
233
+ return self.drop(z.transpose(1, 2))
234
+
235
+
236
+ class EncoderBlock(nn.Module):
237
+ """pre-LN:mixer(local attention 或 dilated conv)+ FFN。"""
238
+
239
+ def __init__(self, cfg: TWLATRConfig, layer_idx: int):
240
+ super().__init__()
241
+ self.ln1 = nn.LayerNorm(cfg.d_model)
242
+ if cfg.encoder == "local":
243
+ self.mixer: nn.Module = LocalAttention(cfg)
244
+ else:
245
+ self.mixer = ConvMixer(cfg, cfg.dilation_at(layer_idx))
246
+ self.ln2 = nn.LayerNorm(cfg.d_model)
247
+ self.ffn = nn.Sequential(
248
+ nn.Linear(cfg.d_model, cfg.ffn_dim),
249
+ nn.GELU(),
250
+ nn.Dropout(cfg.dropout),
251
+ nn.Linear(cfg.ffn_dim, cfg.d_model),
252
+ nn.Dropout(cfg.dropout),
253
+ )
254
+
255
+ def forward(self, x, mix_arg, rope=None):
256
+ x = x + self.mixer(self.ln1(x), mix_arg, rope)
257
+ x = x + self.ffn(self.ln2(x))
258
+ return x
259
+
260
+
261
+ # --------------------------------------------------------------------------- #
262
+ # TWLAT-R
263
+ # --------------------------------------------------------------------------- #
264
+
265
+
266
+ class TWLATR(nn.Module):
267
+ def __init__(self, cfg: TWLATRConfig | None = None):
268
+ super().__init__()
269
+ self.cfg = cfg = cfg or TWLATRConfig()
270
+
271
+ self.char_emb = CharEmbedding(cfg)
272
+ self.text_feat = TextFeatures(cfg)
273
+
274
+ self.layers = nn.ModuleList(
275
+ EncoderBlock(cfg, i) for i in range(cfg.n_layers)
276
+ )
277
+ self.enc_ln = nn.LayerNorm(cfg.d_model)
278
+
279
+ # 候選側:mean-pool 後只有一個 LN + 一個線性投影,沒有任何 per-ID 參數
280
+ self.cand_ln = nn.LayerNorm(cfg.d_model)
281
+ self.cand_proj = nn.Linear(cfg.d_model, cfg.d_model)
282
+ # H-B 對照組:per-candidate learned lookup。未見過的候選只會取到
283
+ # 一列未訓練的隨機向量——這正是 V1 `cand_emb = nn.Embedding(4096, 192)`
284
+ # 的行為,用來檢驗動態編碼是否真的帶來 held-out 優勢。
285
+ if cfg.candidate_encoder == "id":
286
+ self.cand_id_emb = nn.Embedding(cfg.cand_id_vocab, cfg.d_model)
287
+
288
+ score_in = 3 * cfg.d_model + cfg.cand_feat_dim
289
+ self.score = nn.Sequential(
290
+ nn.Linear(score_in, cfg.score_hidden),
291
+ nn.GELU(),
292
+ nn.Dropout(cfg.dropout),
293
+ nn.Linear(cfg.score_hidden, 1),
294
+ )
295
+
296
+ self.apply(self._init_weights)
297
+ self._rope_cache: dict[Any, tuple[torch.Tensor, torch.Tensor]] = {}
298
+ self._window_cache: dict[Any, torch.Tensor] = {}
299
+
300
+ @staticmethod
301
+ def _init_weights(m: nn.Module) -> None:
302
+ if isinstance(m, nn.Linear):
303
+ nn.init.normal_(m.weight, std=0.02)
304
+ if m.bias is not None:
305
+ nn.init.zeros_(m.bias)
306
+ elif isinstance(m, nn.Embedding):
307
+ nn.init.normal_(m.weight, std=0.02)
308
+ elif isinstance(m, nn.Conv1d):
309
+ nn.init.normal_(m.weight, std=0.02)
310
+ if m.bias is not None:
311
+ nn.init.zeros_(m.bias)
312
+
313
+ # -- caches ------------------------------------------------------------ #
314
+
315
+ def _rope(self, t: int, device, dtype):
316
+ key = (t, str(device), dtype)
317
+ if key not in self._rope_cache:
318
+ self._rope_cache[key] = build_rope_cache(
319
+ t, self.cfg.head_dim, self.cfg.rope_base, device, dtype
320
+ )
321
+ return self._rope_cache[key]
322
+
323
+ def _window_mask(self, t: int, device) -> torch.Tensor:
324
+ key = (t, str(device))
325
+ if key not in self._window_cache:
326
+ idx = torch.arange(t, device=device)
327
+ self._window_cache[key] = (idx[:, None] - idx[None, :]).abs() <= self.cfg.local_window
328
+ return self._window_cache[key]
329
+
330
+ # -- 子步驟 ------------------------------------------------------------- #
331
+
332
+ def encode_text(self, input_ids, feat, pad_mask) -> torch.Tensor:
333
+ """[B,T] → [B,T,D]。"""
334
+ t, device = input_ids.shape[1], input_ids.device
335
+ x = self.text_feat(self.char_emb(input_ids), feat)
336
+ if self.cfg.encoder == "local":
337
+ ar = torch.arange(t, device=device)
338
+ eye = ar[:, None] == ar[None, :] # 保留對角線,避免整列被遮而產生 NaN
339
+ mask = ((self._window_mask(t, device) & pad_mask[:, None, :]) | eye).unsqueeze(1)
340
+ rope = self._rope(t, device, x.dtype)
341
+ for layer in self.layers:
342
+ x = layer(x, mask, rope)
343
+ else:
344
+ for layer in self.layers:
345
+ x = layer(x, pad_mask)
346
+ return self.enc_ln(x)
347
+
348
+ @staticmethod
349
+ def span_pool(h: torch.Tensor, spans: torch.Tensor, valid: torch.Tensor) -> torch.Tensor:
350
+ """對每個 proposal 的 [start,end) 做 mean-pool。h:[B,T,D] spans:[B,P,2] → [B,P,D]。"""
351
+ t = h.shape[1]
352
+ pos = torch.arange(t, device=h.device)
353
+ start = spans[..., 0].clamp(0, t).unsqueeze(-1)
354
+ end = spans[..., 1].clamp(0, t).unsqueeze(-1)
355
+ w = ((pos >= start) & (pos < end) & valid).to(h.dtype) # [B,P,T]
356
+ return torch.matmul(w, h) / w.sum(-1, keepdim=True).clamp(min=1.0)
357
+
358
+ def encode_cands(self, cand_tok: torch.Tensor) -> torch.Tensor:
359
+ """候選表面字串 → 向量。[B,P,C,L] → [B,P,C,D]。
360
+
361
+ 走的是與文本同一份 char_emb,且只有 mean-pool + proj:
362
+ 任何未見過的字串都能得到有限且有梯度的表徵(zero-shot 的前提)。
363
+ """
364
+ if self.cfg.candidate_encoder == "id":
365
+ # 把字元序列雜湊成單一 id:同字串 → 同 id,不同字串 → 不同 id。
366
+ # 語意上等同 per-candidate 查表,且不需要重新產生資料。
367
+ mult = torch.tensor([1, 131, 131 ** 2, 131 ** 3, 131 ** 4, 131 ** 5],
368
+ device=cand_tok.device, dtype=torch.long)
369
+ mult = mult[: cand_tok.shape[-1]]
370
+ cid = (cand_tok * mult).sum(-1) % self.cfg.cand_id_vocab
371
+ return self.cand_id_emb(cid)
372
+ valid = (cand_tok > 0).unsqueeze(-1) # id 0 = 右側 padding
373
+ e = self.char_emb(cand_tok)
374
+ e = e * valid.to(e.dtype)
375
+ pooled = e.sum(-2) / valid.sum(-2).clamp(min=1).to(e.dtype)
376
+ return self.cand_proj(self.cand_ln(pooled))
377
+
378
+ # -- forward ------------------------------------------------------------ #
379
+
380
+ def forward(self, batch: dict[str, torch.Tensor]) -> dict[str, torch.Tensor]:
381
+ """batch:
382
+ input_ids [B,T] int64 原文字元 id
383
+ feat [B,T,4] int64 script / 在 proposal span 內 / 保護段 / 詞界
384
+ pad_mask [B,T] bool (可省,缺省全 True)
385
+ prop_spans [B,P,2] int64 proposal 的 [start,end)
386
+ prop_mask [B,P] bool
387
+ cand_tok [B,P,C,L] int64 候選表面字串(右側 0 padding)
388
+ cand_mask [B,P,C] bool
389
+ cand_feat [B,P,C,K] float
390
+ 回傳 {"cand_logits": [B,P,C]},padding 候選為 -inf。
391
+ """
392
+ input_ids = batch["input_ids"]
393
+ b, t = input_ids.shape
394
+ device = input_ids.device
395
+
396
+ pad_mask = batch.get("pad_mask")
397
+ pad_mask = (
398
+ torch.ones(b, t, dtype=torch.bool, device=device)
399
+ if pad_mask is None
400
+ else pad_mask.bool()
401
+ )
402
+ prop_mask = batch["prop_mask"].bool()
403
+ cand_mask = batch["cand_mask"].bool()
404
+
405
+ h_text = self.encode_text(input_ids, batch["feat"], pad_mask)
406
+ h = self.span_pool( # [B,P,D]
407
+ h_text, batch["prop_spans"], (pad_mask[:, None, :] & prop_mask[..., None])
408
+ )
409
+ e = self.encode_cands(batch["cand_tok"]) # [B,P,C,D]
410
+
411
+ c = e.shape[2]
412
+ h_exp = h.unsqueeze(2).expand(-1, -1, c, -1)
413
+ z = torch.cat([h_exp, e, h_exp * e, batch["cand_feat"].to(e.dtype)], dim=-1)
414
+ logits = self.score(z).squeeze(-1) # [B,P,C]
415
+ return {"cand_logits": logits.masked_fill(~cand_mask, float("-inf"))}
416
+
417
+ def compute_loss(self, outputs, batch):
418
+ return compute_loss(outputs, batch)
419
+
420
+
421
+ # --------------------------------------------------------------------------- #
422
+ # Loss:L = L_cand + 0.3 · L_keep_bias
423
+ # --------------------------------------------------------------------------- #
424
+
425
+
426
+ def compute_loss(
427
+ outputs: dict[str, torch.Tensor],
428
+ batch: dict[str, torch.Tensor],
429
+ weights: dict[str, float] | None = None,
430
+ ) -> tuple[torch.Tensor, dict[str, torch.Tensor]]:
431
+ """masked cross-entropy over candidates,外加 keep_bias 正則。
432
+
433
+ keep_bias:對 gold == 0(維持原樣)的 proposal,任何非 0 候選只要分數不比
434
+ 候選 0 低 0.5 以上就受罰 —— 直接壓「改了不該改」(佔 V1 錯誤的 73%)。
435
+ """
436
+ w = {"cand": W_CAND, "keep_bias": W_KEEP_BIAS}
437
+ if weights:
438
+ w.update(weights)
439
+
440
+ logits = outputs["cand_logits"]
441
+ prop_mask = batch["prop_mask"].bool()
442
+ cand_mask = batch["cand_mask"].bool()
443
+ n_cands = logits.shape[-1]
444
+ dtype = logits.dtype
445
+
446
+ # padding 候選的 -inf 會污染算術:CE 用 finfo.min,hinge 用 0 並顯式遮罩
447
+ neg = torch.finfo(dtype).min
448
+ safe = torch.where(cand_mask, logits, torch.full_like(logits, neg))
449
+ finite = torch.where(cand_mask, logits, torch.zeros_like(logits))
450
+
451
+ gold = batch["gold_cand"].clamp(0, n_cands - 1)
452
+ prop_w = prop_mask.to(dtype)
453
+ n_prop = prop_w.sum().clamp(min=1.0)
454
+
455
+ # L_cand:每個 proposal 對候選集的 cross-entropy,padding proposal 不計
456
+ logp = torch.log_softmax(safe, dim=-1)
457
+ nll = -logp.gather(-1, gold.unsqueeze(-1)).squeeze(-1)
458
+ l_cand = (nll * prop_w).sum() / n_prop
459
+
460
+ # L_keep_bias:gold 為「維持原樣」時,對每個非 0 候選各罰一次 hinge
461
+ is_keep = (gold == KEEP_INDEX) & prop_mask
462
+ s_keep = finite[..., KEEP_INDEX : KEEP_INDEX + 1]
463
+ other = cand_mask & (
464
+ torch.arange(n_cands, device=logits.device)[None, None, :] != KEEP_INDEX
465
+ )
466
+ hinge = F.relu(finite - s_keep + KEEP_MARGIN) * other.to(dtype)
467
+ n_keep = is_keep.to(dtype).sum().clamp(min=1.0)
468
+ l_keep = (hinge.sum(-1) * is_keep.to(dtype)).sum() / n_keep
469
+
470
+ total = w["cand"] * l_cand + w["keep_bias"] * l_keep
471
+ with torch.no_grad():
472
+ acc = ((safe.argmax(-1) == gold).to(dtype) * prop_w).sum() / n_prop
473
+ return total, {
474
+ "loss": total.detach(),
475
+ "cand": l_cand.detach(),
476
+ "keep_bias": l_keep.detach(),
477
+ "acc": acc,
478
+ "n_prop": n_prop.detach(),
479
+ }
twlat/model_v3.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """TWLAT V3:lattice 上的雙 pass cloze 模型。
2
+
3
+ 任務:對 lattice 的每條邊,從 confusion group 的正規候選集中預測
4
+ 「臺灣書寫者在這個語境會寫哪個形式」。
5
+
6
+ clean pass(汙染文本原樣)──→ h_clean ─┐ 表面形式證據
7
+ masked pass(站點收合為 MASK)→ h_m ───┤ 無洩漏語境證據
8
+ 候選(共用 char_emb 動態編碼)→ e_c ───┼→ score MLP → [B,S,C]
9
+ 字典特徵(64 維 lattice 特徵)─────────┘
10
+
11
+ 與 V2 的差異:
12
+ 1. 預訓練時 observed 相依特徵歸零(collate 控制),模型無法走
13
+ 「相信表面」捷徑;finetune 才學習把表面 prior 併進來。
14
+ 2. doc 向量在中層注入:領域相依詞(程序/數據/介面)需要全文域推斷。
15
+ 3. MLM 輔助頭(tied embedding)維持表徵品質。
16
+
17
+ 參數量(d256 / 8 層 / 2 attn)≈ 8.7M,遠低於 16M 上限(D-04)。
18
+ """
19
+ from __future__ import annotations
20
+
21
+ import dataclasses
22
+ from dataclasses import dataclass
23
+ from typing import Any
24
+
25
+ import torch
26
+ import torch.nn as nn
27
+ import torch.nn.functional as F
28
+
29
+ from twlat.model_r import (CharEmbedding, ConvMixer, LocalAttention,
30
+ TextFeatures, build_rope_cache)
31
+
32
+
33
+ @dataclass
34
+ class TWLATV3Config:
35
+ d_model: int = 256
36
+ n_heads: int = 4
37
+ ffn_dim: int = 1024
38
+ dropout: float = 0.1
39
+
40
+ n_layers: int = 8
41
+ attn_layers: tuple[int, ...] = (3, 7) # 這些層用 local attention,其餘 TCN
42
+ local_window: int = 64
43
+ conv_kernel: int = 5
44
+ conv_dilations: tuple[int, ...] = (1, 2, 4, 8, 16, 32, 64, 128)
45
+ conv_expansion: int = 2
46
+ doc_layer: int = 4 # 此層之前注入 doc 向量
47
+
48
+ han_vocab: int = 4096 # 0=PAD 1=UNK 2=MASK
49
+ n_hash: int = 2
50
+ hash_buckets: int = 2048
51
+ feat_dim: int = 4 # script(含 MASK=4)/span 內/保護段/詞界
52
+ feat_vocab: tuple[int, ...] = (16, 4, 4, 4)
53
+
54
+ s_max: int = 128
55
+ c_max: int = 8
56
+ cand_len: int = 8
57
+ cand_feat_dim: int = 64
58
+ score_hidden: int = 512
59
+
60
+ seq_len: int = 512
61
+ rope_base: float = 10000.0
62
+
63
+ # loss
64
+ mlm_weight: float = 0.1
65
+ nomask_weight: float = 0.1 # 不可遮罩站點的 loss 權重
66
+ keep_margin: float = 0.5 # finetune 階段的 keep hinge
67
+
68
+ def __post_init__(self):
69
+ assert self.d_model % self.n_heads == 0 and self.d_model % 2 == 0
70
+ assert self.conv_kernel % 2 == 1
71
+
72
+ @property
73
+ def head_dim(self) -> int:
74
+ return self.d_model // self.n_heads
75
+
76
+ @property
77
+ def hash_dim(self) -> int:
78
+ return self.d_model // 2
79
+
80
+ def dilation_at(self, i: int) -> int:
81
+ return self.conv_dilations[i % len(self.conv_dilations)]
82
+
83
+
84
+ class V3Block(nn.Module):
85
+ """pre-LN block;mixer 依層選 local attention 或 dilated conv。"""
86
+
87
+ def __init__(self, cfg: TWLATV3Config, layer_idx: int):
88
+ super().__init__()
89
+ self.is_attn = layer_idx in cfg.attn_layers
90
+ self.ln1 = nn.LayerNorm(cfg.d_model)
91
+ if self.is_attn:
92
+ self.mixer: nn.Module = LocalAttention(cfg)
93
+ else:
94
+ self.mixer = ConvMixer(cfg, cfg.dilation_at(layer_idx))
95
+ self.ln2 = nn.LayerNorm(cfg.d_model)
96
+ self.ffn = nn.Sequential(
97
+ nn.Linear(cfg.d_model, cfg.ffn_dim), nn.GELU(),
98
+ nn.Dropout(cfg.dropout),
99
+ nn.Linear(cfg.ffn_dim, cfg.d_model), nn.Dropout(cfg.dropout))
100
+
101
+ def forward(self, x, attn_mask, pad_mask, rope):
102
+ if self.is_attn:
103
+ x = x + self.mixer(self.ln1(x), attn_mask, rope)
104
+ else:
105
+ x = x + self.mixer(self.ln1(x), pad_mask)
106
+ return x + self.ffn(self.ln2(x))
107
+
108
+
109
+ class TWLATV3(nn.Module):
110
+ def __init__(self, cfg: TWLATV3Config | None = None):
111
+ super().__init__()
112
+ self.cfg = cfg = cfg or TWLATV3Config()
113
+ self.char_emb = CharEmbedding(cfg)
114
+ self.text_feat = TextFeatures(cfg)
115
+ self.layers = nn.ModuleList(V3Block(cfg, i) for i in range(cfg.n_layers))
116
+ self.enc_ln = nn.LayerNorm(cfg.d_model)
117
+ self.doc_mlp = nn.Sequential(
118
+ nn.Linear(cfg.d_model, cfg.d_model), nn.GELU(),
119
+ nn.Linear(cfg.d_model, cfg.d_model))
120
+
121
+ self.cand_ln = nn.LayerNorm(cfg.d_model)
122
+ self.cand_proj = nn.Linear(cfg.d_model, cfg.d_model)
123
+
124
+ score_in = 5 * cfg.d_model + cfg.cand_feat_dim
125
+ self.score = nn.Sequential(
126
+ nn.Linear(score_in, cfg.score_hidden), nn.GELU(),
127
+ nn.Dropout(cfg.dropout),
128
+ nn.Linear(cfg.score_hidden, 1))
129
+
130
+ self.apply(self._init_weights)
131
+ self._rope_cache: dict[Any, tuple] = {}
132
+ self._window_cache: dict[Any, torch.Tensor] = {}
133
+
134
+ @staticmethod
135
+ def _init_weights(m):
136
+ if isinstance(m, (nn.Linear, nn.Conv1d)):
137
+ nn.init.normal_(m.weight, std=0.02)
138
+ if m.bias is not None:
139
+ nn.init.zeros_(m.bias)
140
+ elif isinstance(m, nn.Embedding):
141
+ nn.init.normal_(m.weight, std=0.02)
142
+
143
+ def _rope(self, t, device, dtype):
144
+ key = (t, str(device), dtype)
145
+ if key not in self._rope_cache:
146
+ self._rope_cache[key] = build_rope_cache(
147
+ t, self.cfg.head_dim, self.cfg.rope_base, device, dtype)
148
+ return self._rope_cache[key]
149
+
150
+ def _win_mask(self, t, device):
151
+ key = (t, str(device))
152
+ if key not in self._window_cache:
153
+ idx = torch.arange(t, device=device)
154
+ self._window_cache[key] = \
155
+ (idx[:, None] - idx[None, :]).abs() <= self.cfg.local_window
156
+ return self._window_cache[key]
157
+
158
+ def encode(self, ids, feat, pad_mask) -> torch.Tensor:
159
+ """[B,T] → [B,T,D],中層注入 doc mean-pool 向量(域推斷通道)。"""
160
+ t, device = ids.shape[1], ids.device
161
+ x = self.text_feat(self.char_emb(ids), feat)
162
+ ar = torch.arange(t, device=device)
163
+ eye = ar[:, None] == ar[None, :]
164
+ attn_mask = ((self._win_mask(t, device) & pad_mask[:, None, :]) | eye
165
+ ).unsqueeze(1)
166
+ rope = self._rope(t, device, x.dtype)
167
+ pw = pad_mask.unsqueeze(-1).to(x.dtype)
168
+ for i, layer in enumerate(self.layers):
169
+ if i == self.cfg.doc_layer:
170
+ doc = (x * pw).sum(1) / pw.sum(1).clamp(min=1.0)
171
+ x = x + self.doc_mlp(doc).unsqueeze(1)
172
+ x = layer(x, attn_mask, pad_mask, rope)
173
+ return self.enc_ln(x)
174
+
175
+ @staticmethod
176
+ def span_pool(h, spans, valid):
177
+ t = h.shape[1]
178
+ pos = torch.arange(t, device=h.device)
179
+ start = spans[..., 0].clamp(0, t).unsqueeze(-1)
180
+ end = spans[..., 1].clamp(0, t).unsqueeze(-1)
181
+ w = ((pos >= start) & (pos < end) & valid).to(h.dtype)
182
+ return torch.matmul(w, h) / w.sum(-1, keepdim=True).clamp(min=1.0)
183
+
184
+ def encode_cands(self, cand_tok) -> torch.Tensor:
185
+ """[B,S,C,L] → [B,S,C,D];共用 char_emb,零 per-ID 參數(熱更新前提)。"""
186
+ valid = (cand_tok > 0).unsqueeze(-1)
187
+ e = self.char_emb(cand_tok) * valid.to(self.char_emb.han.weight.dtype)
188
+ pooled = e.sum(-2) / valid.sum(-2).clamp(min=1).to(e.dtype)
189
+ return self.cand_proj(self.cand_ln(pooled))
190
+
191
+ def mlm_logits(self, h) -> torch.Tensor:
192
+ """tied 到 han embedding(只覆蓋常用字表)。"""
193
+ return h @ self.char_emb.han.weight.t()
194
+
195
+ def forward(self, batch: dict[str, torch.Tensor]) -> dict[str, torch.Tensor]:
196
+ """batch 欄位:
197
+ ids/feat/pad clean 序列 [B,T]…
198
+ mids/mfeat/mpad masked 序列 [B,Tm]…
199
+ c_span/m_span [B,S,2] 兩序列座標
200
+ site_mask [B,S] cand_tok [B,S,C,L] cand_mask/cand_kill [B,S,C]
201
+ cand_feat [B,S,C,K]
202
+ (訓練另有 gold/site_w/mlm_pos/mlm_gold)
203
+ """
204
+ site_mask = batch["site_mask"].bool()
205
+ cand_ok = batch["cand_mask"].bool() & ~batch["cand_kill"].bool()
206
+
207
+ h_c = self.encode(batch["ids"], batch["feat"], batch["pad"].bool())
208
+ h_m = self.encode(batch["mids"], batch["mfeat"], batch["mpad"].bool())
209
+
210
+ vc = batch["pad"].bool()[:, None, :] & site_mask[..., None]
211
+ vm = batch["mpad"].bool()[:, None, :] & site_mask[..., None]
212
+ hc = self.span_pool(h_c, batch["c_span"], vc) # [B,S,D]
213
+ hm = self.span_pool(h_m, batch["m_span"], vm)
214
+ e = self.encode_cands(batch["cand_tok"]) # [B,S,C,D]
215
+
216
+ c = e.shape[2]
217
+ hce = hc.unsqueeze(2).expand(-1, -1, c, -1)
218
+ hme = hm.unsqueeze(2).expand(-1, -1, c, -1)
219
+ z = torch.cat([hme, hce, e, hme * e, hce * e,
220
+ batch["cand_feat"].to(e.dtype)], dim=-1)
221
+ logits = self.score(z).squeeze(-1)
222
+ return {"cand_logits": logits.masked_fill(~cand_ok, float("-inf")),
223
+ "h_m": h_m}
224
+
225
+
226
+ def compute_loss_v3(model: TWLATV3, out, batch, phase: str = "pretrain"):
227
+ cfg = model.cfg
228
+ logits = out["cand_logits"]
229
+ dtype = logits.dtype
230
+ gold = batch["gold"].clamp(min=0)
231
+ # gold 候選被硬過濾砍掉的位點(例外詞/positional 與真實用法衝突):
232
+ # 模型無從答對,排除於 loss——這是硬過濾的固有代價,由 gold_killed 計數監控
233
+ selectable = batch["cand_mask"].bool() & ~batch["cand_kill"].bool()
234
+ gold_ok = selectable.gather(-1, gold.unsqueeze(-1)).squeeze(-1)
235
+ site_mask = batch["site_mask"].bool() & (batch["gold"] >= 0) & gold_ok
236
+ w = batch["site_w"].to(dtype) * site_mask.to(dtype)
237
+ n = w.sum().clamp(min=1.0)
238
+
239
+ neg = torch.finfo(dtype).min
240
+ safe = torch.where(torch.isinf(logits), torch.full_like(logits, neg), logits)
241
+ logp = torch.log_softmax(safe, -1)
242
+ nll = -logp.gather(-1, gold.unsqueeze(-1)).squeeze(-1)
243
+ l_cloze = (nll * w).sum() / n
244
+
245
+ total = l_cloze
246
+ parts = {"cloze": l_cloze.detach()}
247
+
248
+ if "mlm_pos" in batch and batch["mlm_pos"].any():
249
+ ml = model.mlm_logits(out["h_m"])
250
+ pos = batch["mlm_pos"].bool()
251
+ l_mlm = F.cross_entropy(ml[pos], batch["mlm_gold"][pos].clamp(min=0))
252
+ total = total + cfg.mlm_weight * l_mlm
253
+ parts["mlm"] = l_mlm.detach()
254
+
255
+ if phase == "finetune":
256
+ # keep hinge:gold==observed 時,其他候選高過 s_obs−margin 即受罰
257
+ obs = batch["obs"].long().clamp(min=0)
258
+ is_keep = site_mask & (batch["gold"] == batch["obs"])
259
+ finite = torch.where(torch.isinf(logits), torch.zeros_like(logits), logits)
260
+ s_obs = finite.gather(-1, obs.unsqueeze(-1))
261
+ others = batch["cand_mask"].bool() & ~batch["cand_kill"].bool() & \
262
+ (torch.arange(logits.shape[-1], device=logits.device)[None, None, :]
263
+ != obs.unsqueeze(-1))
264
+ hinge = F.relu(finite - s_obs + cfg.keep_margin) * others.to(dtype)
265
+ nk = is_keep.to(dtype).sum().clamp(min=1.0)
266
+ l_keep = (hinge.sum(-1) * is_keep.to(dtype)).sum() / nk
267
+ total = total + 0.15 * l_keep
268
+ parts["keep"] = l_keep.detach()
269
+
270
+ with torch.no_grad():
271
+ pred = safe.argmax(-1)
272
+ ok = (pred == gold) & site_mask
273
+ keepm = site_mask & (batch["gold"] == batch["obs"])
274
+ chgm = site_mask & (batch["gold"] != batch["obs"])
275
+ parts.update(
276
+ acc=ok.float().sum() / site_mask.float().sum().clamp(min=1.0),
277
+ keep_acc=(ok & keepm).float().sum() / keepm.float().sum().clamp(min=1.0),
278
+ chg_acc=(ok & chgm).float().sum() / chgm.float().sum().clamp(min=1.0),
279
+ n_sites=site_mask.float().sum(),
280
+ gold_killed=(batch["site_mask"].bool() & (batch["gold"] >= 0)
281
+ & ~gold_ok).float().sum())
282
+ parts["loss"] = total.detach()
283
+ return total, parts
284
+
285
+
286
+ def make_config(**over) -> TWLATV3Config:
287
+ fields = {f.name for f in dataclasses.fields(TWLATV3Config)}
288
+ return TWLATV3Config(**{k: (tuple(v) if isinstance(v, list) else v)
289
+ for k, v in over.items() if k in fields})
twlat/normalize.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Safe normalization:只做**無歧義**的確定性轉換(TWLAT-R 的 deterministic layer)。
2
+
3
+ 與 V1 的差別,以及為什麼要換掉 zhtw-mcp 的 fixer:
4
+
5
+ V1 直接用 `zhtw-mcp convert` 當 deterministic layer。實測它會製造三類錯誤,
6
+ 而且模型無權修正(因為錯誤發生在模型看到文字之前):
7
+ 1. 引號配對會刪除字元(『稲亭物怪録』→ 稲亭物怪録)
8
+ 2. casing 規則改動 inline code 內的識別字(`typescript` → `TypeScript`)
9
+ 3. 詞表做了語境相依的決策(商调制度 → 商調製度、十姑娘 → 十姑孃)
10
+
11
+ 本模組只做「任何語境下都對」的轉換,其餘一律交給模型當 proposal:
12
+ - 引號正規化(自行實作,不刪字元)
13
+ - **單候選**簡→繁字元轉換(一簡多繁一律不碰,交給模型)
14
+ - CJK 相鄰的半形→全形標點
15
+ - CJK 與拉丁/數字之間補空格
16
+
17
+ zhtw-mcp 仍然是**字典來源**(1,853 條規則的語意條件),這是它真正的價值;
18
+ 但它的 fixer 不再位於資料路徑上。
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import pathlib
24
+
25
+ import regex
26
+
27
+ from twlat import quotes
28
+ from twlat.paths import data_file
29
+
30
+ HAN = regex.compile(r"\p{Han}")
31
+ CJK = regex.compile(r"[\p{Han}\p{Hiragana}\p{Katakana}\p{Hangul}]")
32
+ LATIN_NUM = regex.compile(r"[A-Za-z0-9]")
33
+
34
+
35
+ # 一簡多繁的預設值改以**臺灣語料頻率**排序,取代 OpenCC 的任意順序。
36
+ # 實測 OpenCC 第一候選在 36/239 個字上是錯的:
37
+ # 里→裏(語料 12,333 vs 里 274,290)、吃→喫(326 vs 68,673)、
38
+ # 朴→樸(2,401 vs 6,223,害「朴正熙」變「樸正熙」)、咸→鹹(咸豐帝變鹹豐帝)
39
+ # 由 tools/rank_variants.py 產生。
40
+ _RANK_P = data_file("dict/variant_rank.json")
41
+ VARIANT_ORDER: dict[str, list[str]] = (
42
+ json.loads(_RANK_P.read_text(encoding="utf-8"))["order"]
43
+ if _RANK_P.exists() else {})
44
+ # D-12 政策例外:台/臺 沿用 zhtw-mcp strict 的規範,不依頻率。
45
+ POLICY_OVERRIDE = {"台": "臺"}
46
+
47
+
48
+ def _load_s2t() -> dict[str, str]:
49
+ """簡→繁字元表。
50
+
51
+ 一簡多繁**也要轉**,取 OpenCC 的第一候選(最常見)——因為留著簡體字
52
+ 比選錯繁體更糟(zhtw-mcp 就是選擇留簡體,實測「復置」被輸出成「复置」,
53
+ 比純 OpenCC 還差)。真正的選擇留給 proposal:該位置會被提出候選集,
54
+ 由模型依語境決定要不要改成別的候選。
55
+ """
56
+ m: dict[str, str] = {}
57
+ p = data_file("dict/rules/st_characters.tsv")
58
+ for line in p.read_text(encoding="utf-8").splitlines():
59
+ if not line.strip():
60
+ continue
61
+ parts = line.split("\t")
62
+ if len(parts) != 2:
63
+ continue
64
+ src, cands = parts[0], parts[1].split()
65
+ if len(src) != 1 or not cands or len(cands[0]) != 1:
66
+ continue
67
+ if src == cands[0]:
68
+ continue
69
+ m[src] = cands[0]
70
+ # 以語料頻率覆寫一簡多繁的預設值
71
+ for s, order in VARIANT_ORDER.items():
72
+ if len(s) == 1 and order and s in m:
73
+ m[s] = order[0]
74
+ m.update(POLICY_OVERRIDE)
75
+ return m
76
+
77
+
78
+ S2T_CHAR = _load_s2t()
79
+
80
+
81
+ def _load_twv() -> dict[str, str]:
82
+ """OpenCC TWVariants 39 條臺標變體(裏→裡、着→著、喫→吃)。
83
+
84
+ V3 專用(do_twv=True):確保 base 文本與 cloze 預訓練語料都是臺標形。
85
+ V1/V2 預設關閉——它們的模型與已發表數字是在無此正規化下訓練/評測的,
86
+ 改變共用預設會靜默移動凍結的 baseline。
87
+ """
88
+ m: dict[str, str] = {}
89
+ p = data_file("dict/rules/tw_variants.tsv")
90
+ for line in p.read_text(encoding="utf-8").splitlines():
91
+ parts = line.split("\t")
92
+ if len(parts) == 2 and len(parts[0]) == 1:
93
+ m[parts[0]] = parts[1].split()[0]
94
+ return m
95
+
96
+
97
+ TWV_CHAR = _load_twv()
98
+ # S2T 輸出值一併臺標化(st_characters 第一候選可能是 裏 這類非臺標形)
99
+ S2T_TW = {k: "".join(TWV_CHAR.get(c, c) for c in v) for k, v in S2T_CHAR.items()}
100
+
101
+ # V3.1:**常用**的自候選歧義字不做預轉換——選擇完全交給 lattice+模型。
102
+ # V3.0 的教訓(bench 錯誤解剖):
103
+ # 1. POLICY_OVERRIDE 台→臺 與真實語料寫法衝突,獨佔 40% 的 keep 錯誤;
104
+ # 2. 頻率預設會翻轉正確輸入(核准→核準),製造本不存在的 change 任務。
105
+ # 判準:該字是自己的候選之一(st_characters 行含自身,如 里→裏 里)
106
+ # **且**臺灣語料頻率 ≥ 500(排除 广/厂 這類 OpenCC 視為罕見繁體、
107
+ # 實際上留著就是簡體殘留的字——广 頻率 30 vs 台 399,155)。
108
+ _VR_FREQ: dict[str, int] = json.loads(
109
+ data_file("dict/variant_rank.json").read_text(encoding="utf-8"))["freq"]
110
+ _SELF_OK: set[str] = set()
111
+ for _line in data_file("dict/rules/st_characters.tsv").read_text(
112
+ encoding="utf-8").splitlines():
113
+ _p = _line.split("\t")
114
+ if len(_p) == 2 and _p[0] in _p[1].split() \
115
+ and _VR_FREQ.get(_p[0], 0) >= 500:
116
+ _SELF_OK.add(_p[0])
117
+ S2T_TW_V3 = {k: v for k, v in S2T_TW.items() if k not in _SELF_OK}
118
+
119
+ HALF_FULL = {",": ",", ";": ";", ":": ":", "!": "!", "?": "?",
120
+ "(": "(", ")": ")"}
121
+
122
+
123
+ def _punct(text: str) -> str:
124
+ """CJK 相鄰的半形標點轉全形。句點另外處理(避免動到小數與副檔名)。"""
125
+ out = list(text)
126
+ n = len(text)
127
+ for i, ch in enumerate(text):
128
+ if ch not in HALF_FULL and ch != ".":
129
+ continue
130
+ prev = text[i - 1] if i else ""
131
+ nxt = text[i + 1] if i + 1 < n else ""
132
+ if ch == ".":
133
+ # 只在前一字是 CJK 且下一字非數字時轉句號
134
+ if CJK.match(prev or " ") and not (nxt and nxt.isdigit()):
135
+ out[i] = "。"
136
+ continue
137
+ if CJK.match(prev or " ") or CJK.match(nxt or " "):
138
+ out[i] = HALF_FULL[ch]
139
+ # 轉全形後要吃掉緊跟的空格,否則會留下「, 」這種贅格
140
+ if nxt == " ":
141
+ out[i + 1] = ""
142
+ return "".join(out)
143
+
144
+
145
+ def _spacing(text: str) -> str:
146
+ """CJK 與拉丁/數字之間補一個半形空格;已有空白則不重複。"""
147
+ out = []
148
+ for i, ch in enumerate(text):
149
+ if i:
150
+ a, b = text[i - 1], ch
151
+ need = (CJK.match(a) and LATIN_NUM.match(b)) or \
152
+ (LATIN_NUM.match(a) and CJK.match(b))
153
+ if need:
154
+ out.append(" ")
155
+ out.append(ch)
156
+ return "".join(out)
157
+
158
+
159
+ def safe_normalize(text: str, do_quotes: bool = True, do_s2t: bool = True,
160
+ do_punct: bool = True, do_spacing: bool = True,
161
+ do_twv: bool = False) -> str:
162
+ """只套用無歧義轉換。各步驟可關閉以做消融。do_twv 見 _load_twv 註解。"""
163
+ t = text
164
+ if do_quotes:
165
+ t = quotes.normalize(t)
166
+ if do_s2t:
167
+ s2t = S2T_TW_V3 if do_twv else S2T_CHAR
168
+ t = "".join(s2t.get(c, c) for c in t)
169
+ if do_twv:
170
+ t = "".join(TWV_CHAR.get(c, c) for c in t)
171
+ if do_punct:
172
+ t = _punct(t)
173
+ if do_spacing:
174
+ t = _spacing(t)
175
+ return t
176
+
177
+
178
+ def stats() -> dict:
179
+ return {"unambiguous_s2t_chars": len(S2T_CHAR)}
180
+
181
+
182
+ if __name__ == "__main__":
183
+ print(stats())
184
+ for s in ["这个程序有bug,请在服务器上部署。",
185
+ "现行公务人员指名商调制度",
186
+ "十姑娘的香港法律顾问",
187
+ "他问:“老师,‘有条不紊’的‘紊’是什么意思?”",
188
+ "版本 v1.2.3 已发布,请访问 https://a.b/c 。"]:
189
+ print(f"\nIN : {s}\nOUT: {safe_normalize(s)}")
twlat/paths.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """資料檔的位置解析——讓套件可以在 repo 之外執行(Hugging Face、pip 安裝)。
2
+
3
+ 解析順序:
4
+ 1. 環境變數 `TWLAT_HOME`(指向含 `dict/`、`model/` 的目錄)
5
+ 2. 套件旁的 `_data/`(wheel 打包或 HF snapshot 會放這裡)
6
+ 3. 開發用的 repo 根目錄
7
+
8
+ 模型權重不在此解析範圍:由 `Converter(ckpt=...)` 明確指定,
9
+ 或由 `twlat.hub.load()` 從 Hugging Face 下載。
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import os
14
+ import pathlib
15
+
16
+ _PKG = pathlib.Path(__file__).resolve().parent
17
+ _REPO = _PKG.parents[1]
18
+
19
+
20
+ def data_root() -> pathlib.Path:
21
+ env = os.environ.get("TWLAT_HOME")
22
+ if env:
23
+ return pathlib.Path(env).expanduser()
24
+ bundled = _PKG / "_data"
25
+ if (bundled / "dict").exists():
26
+ return bundled
27
+ return _REPO
28
+
29
+
30
+ def data_file(rel: str) -> pathlib.Path:
31
+ """rel 例:'dict/lattice_lexicon.json'。"""
32
+ return data_root() / rel
twlat/protect.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """保護段:把必須 byte-exact 保留的片段換成 PUA 佔位符,最後再還原。
2
+
3
+ 由 V1 的 runtime.py 抽出成獨立模組,讓 V3 推論路徑不必匯入 V1
4
+ (V1 需要 yaml、sites.yaml、model.py,在 pip/HF 環境是多餘的相依)。
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import re as _re
9
+
10
+ # URL 的字元集必須明列,不能用 \S+:中文後面沒有空白分隔,
11
+ # \S+ 會把「…id=972,最后浏览日期…」整段吞進 copy buffer,
12
+ # 那段中文就完全繞過後續處理、簡體原樣輸出(實測過的真實 bug)。
13
+ COPY_EXACT = _re.compile(
14
+ r"https?://[A-Za-z0-9\-._~:/?#\[\]@!$&'()*+;=%]+"
15
+ r"|[A-Za-z0-9][\w.+-]*@[\w-]+(?:\.[\w-]+)*\.[A-Za-z]{2,}" # Email
16
+ r"|`[^`]+`" # inline code
17
+ r"|```[\s\S]*?```" # code fence
18
+ r"|\bv?\d+\.\d+(?:\.\d+)*(?:-[\w.]+)?\b" # 版本號
19
+ r"|\bgit@[\w.-]+:[\w./-]+" # git remote
20
+ )
21
+ PUA_BASE = 0xE000
22
+ PUA_MAX = 0xF8FF
23
+
24
+
25
+ def protect(text: str) -> tuple[str, list[str]]:
26
+ saved: list[str] = []
27
+
28
+ def sub(m):
29
+ if len(saved) >= PUA_MAX - PUA_BASE:
30
+ return m.group(0)
31
+ saved.append(m.group(0))
32
+ return chr(PUA_BASE + len(saved) - 1)
33
+
34
+ return COPY_EXACT.sub(sub, text), saved
35
+
36
+
37
+ def restore(text: str, saved: list[str]) -> str:
38
+ if not saved:
39
+ return text
40
+ return "".join(
41
+ saved[ord(c) - PUA_BASE] if PUA_BASE <= ord(c) < PUA_BASE + len(saved)
42
+ else c for c in text)
twlat/quotes.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """引號正規化(繞過 zhtw-mcp 的 quote-pairing 缺陷)。
2
+
3
+ zhtw-mcp `convert` 的引號重指派會**刪除字元**(見
4
+ reports/upstream-issue-zhtw-mcp-quotes.md):
5
+
6
+ 『稲亭物怪録』。 → 稲亭物怪録。 ← 正確的括號被刪
7
+ „Ich bin deutsche“。 → „Ich bin deutsche。← 德文引號被刪
8
+
9
+ 實測這是 TWLAT 輸出中最大的單一錯誤來源(佔錯誤編輯 37.2%、
10
+ 涉及 31/298 題)。因此本模組自行做**確定性**的引號轉換,
11
+ 再把結果遮罩起來讓規則層碰不到。
12
+
13
+ 規則(依《重訂標點符號手冊》):
14
+ 最外層 「」,內層 『』,再內層回到 「」,以此類推。
15
+ 只轉換與 CJK 相鄰的 CN 彎引號;英文縮寫(it's)、德文引號(„…“)不動。
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import regex
20
+
21
+ # 只認漢字/假名/諺文,**不含 CJK 標點**:否則 „Ich bin deutsche“。 的 “
22
+ # 會因為後面接了「。」而被誤判為中文語境。
23
+ CJK = regex.compile(r"[\p{Han}\p{Hiragana}\p{Katakana}\p{Hangul}]")
24
+ OPEN_CN = {"“": 0, "‘": 1} # “ ‘
25
+ CLOSE_CN = {"”": 0, "’": 1} # ” ’
26
+ PAIRS = [("「", "」"), ("『", "』")] # 「」 『』
27
+ ALL_QUOTES = "“”‘’「」『』"
28
+
29
+
30
+ def _cjk_near(text: str, i: int) -> bool:
31
+ """該引號是否處於 CJK 語境(前後任一側 2 字元內有 CJK)。"""
32
+ for j in (i - 2, i - 1, i + 1, i + 2):
33
+ if 0 <= j < len(text) and CJK.match(text[j]):
34
+ return True
35
+ return False
36
+
37
+
38
+ def normalize(text: str) -> str:
39
+ """把 CN 彎引號轉為臺灣規範引號,維持巢狀層級,且**不刪除任何字元**。"""
40
+ out = list(text)
41
+ depth = 0
42
+ for i, ch in enumerate(text):
43
+ if ch in OPEN_CN:
44
+ if not _cjk_near(text, i):
45
+ continue # 英文/德文語境 → 不動
46
+ out[i] = PAIRS[depth % 2][0]
47
+ depth += 1
48
+ elif ch in CLOSE_CN:
49
+ if not _cjk_near(text, i):
50
+ continue
51
+ depth = max(0, depth - 1)
52
+ out[i] = PAIRS[depth % 2][1]
53
+ return "".join(out)
54
+
55
+
56
+ def mask(text: str, base: int = 0xE800):
57
+ """把所有引號字元換成 PUA 佔位符,讓規則層碰不到。回傳 (masked, saved)。"""
58
+ saved: list[str] = []
59
+ buf = []
60
+ for ch in text:
61
+ if ch in ALL_QUOTES and len(saved) < 0xF8FF - base:
62
+ buf.append(chr(base + len(saved)))
63
+ saved.append(ch)
64
+ else:
65
+ buf.append(ch)
66
+ return "".join(buf), saved
67
+
68
+
69
+ def unmask(text: str, saved: list[str], base: int = 0xE800) -> str:
70
+ if not saved:
71
+ return text
72
+ return "".join(saved[ord(c) - base] if base <= ord(c) < base + len(saved) else c
73
+ for c in text)
twlat/runtime_v3.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """TWLAT V3 推論管線。
2
+
3
+ 輸入 → protect(PUA 遮罩保護段)→ safe_normalize(twv)
4
+ → lattice(字典硬過濾在此發生)→ 無邊 → fast path
5
+ → clean/masked 雙 pass forward → Viterbi + τ → 最小 splice
6
+ → restore → 輸出
7
+
8
+ 超長輸入:滑動視窗(stride 384),每條邊由「它最居中」的視窗評分——
9
+ 不再有 V2 的 INPUT_TOO_LONG 降級路徑。
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import pathlib
14
+ from dataclasses import dataclass, field
15
+
16
+ import numpy as np
17
+ import torch
18
+
19
+
20
+ from twlat import decoder # noqa: E402
21
+ from twlat.features import (FEAT_DIM, L_MAX, LexTables, # noqa: E402
22
+ assemble_cands, make_feat, site_arrays,
23
+ text_arrays)
24
+ from twlat.lattice import LatticeBuilder, build_masked_view # noqa: E402
25
+ from twlat.model_v3 import TWLATV3, make_config # noqa: E402
26
+ from twlat.normalize import safe_normalize # noqa: E402
27
+ from twlat.paths import data_file # noqa: E402
28
+ from twlat.protect import protect, restore # noqa: E402
29
+
30
+ import json # noqa: E402
31
+
32
+ WIN, STRIDE = 512, 384
33
+
34
+
35
+ @dataclass
36
+ class ResultV3:
37
+ output: str
38
+ decisions: list = field(default_factory=list)
39
+ fast_path: bool = False
40
+ error: str | None = None
41
+
42
+
43
+ class TWLATV3Runtime:
44
+ def __init__(self, ckpt: str, device: str | None = None,
45
+ tau: dict[str, float] | None = None,
46
+ lexicon_path=None, fo_bonus: float = 0.0):
47
+ lex_p = lexicon_path or data_file("dict/lattice_lexicon.json")
48
+ self.lb = LatticeBuilder(lex_p)
49
+ self.lex = LexTables(lex_p)
50
+ self.vocab = json.loads(
51
+ data_file("dict/char_vocab_v3.json").read_text(encoding="utf-8"))
52
+ self.fo_bonus = fo_bonus
53
+ tp = data_file("model/tau.json")
54
+ self.tau = tau if tau is not None else (
55
+ json.loads(tp.read_text()) if tp.exists() else decoder.DEFAULT_TAU)
56
+ self.device = torch.device(
57
+ device or ("cuda" if torch.cuda.is_available()
58
+ else "mps" if torch.backends.mps.is_available() else "cpu"))
59
+ ck = torch.load(ckpt, map_location="cpu", weights_only=False)
60
+ self.model = TWLATV3(make_config(**ck["mcfg"]))
61
+ self.model.load_state_dict(ck["model"])
62
+ self.model.eval().to(self.device)
63
+ # observed 相依特徵(is_keep/長度差)只有 finetune 階段見過;
64
+ # 對 pretrain-only checkpoint 餵入會是分佈外輸入
65
+ self.reveal = ck.get("phase") == "finetune"
66
+ ck_lex = ck.get("lexicon_version")
67
+ if ck_lex and ck_lex != self.lb.version:
68
+ # 熱更新是功能不是錯誤:記錄但不擋(held-out 評測依賴此路徑)
69
+ self.lexicon_mismatch = (ck_lex, self.lb.version)
70
+ else:
71
+ self.lexicon_mismatch = None
72
+
73
+ # ------------------------------------------------------------------ #
74
+
75
+ @torch.no_grad()
76
+ def score_batch(self, texts: list[str], batch_size: int = 32):
77
+ """評分階段:→ list[(base, sv, lat, logits[n_edges,C] | None)]。
78
+ τ 校準重用此結果做多組解碼,不必重跑模型。"""
79
+ stages = []
80
+ jobs = []
81
+ for ti, t in enumerate(texts):
82
+ q, sv = protect(t)
83
+ base = safe_normalize(q, do_twv=True)
84
+ lat = self.lb.build(base)
85
+ stages.append([base, sv, lat, None])
86
+ if not lat.edges:
87
+ continue
88
+ wins = self._windows(len(base))
89
+ assign = self._assign(lat, wins)
90
+ for wi, (ws, we) in enumerate(wins):
91
+ eixs = assign[wi]
92
+ if not eixs:
93
+ continue
94
+ jobs.append(self._make_job(ti, base[ws:we], ws,
95
+ [lat.edges[i] for i in eixs], eixs))
96
+
97
+ logit_map: dict[int, dict[int, np.ndarray]] = {}
98
+ jobs.sort(key=lambda j: len(j["text"]))
99
+ for s in range(0, len(jobs), batch_size):
100
+ chunk = jobs[s:s + batch_size]
101
+ out = self.model(self._stack(chunk))
102
+ lg = out["cand_logits"].float().cpu().numpy()
103
+ for bi, j in enumerate(chunk):
104
+ m = logit_map.setdefault(j["ti"], {})
105
+ for k, eix in enumerate(j["eixs"]):
106
+ m[eix] = lg[bi, k]
107
+
108
+ for ti, st in enumerate(stages):
109
+ lat = st[2]
110
+ if not lat.edges:
111
+ continue
112
+ lm = logit_map.get(ti, {})
113
+ cmax = max((v.shape[0] for v in lm.values()), default=1)
114
+ logits = np.full((len(lat.edges), cmax), -np.inf, np.float32)
115
+ for eix, row in lm.items():
116
+ logits[eix, :len(row)] = row
117
+ for i, e in enumerate(lat.edges):
118
+ if i not in lm: # 不應發生:未覆蓋 → keep
119
+ logits[i, e.obs_ix] = 0.0
120
+ st[3] = logits
121
+ return stages
122
+
123
+ def decode_stage(self, stage, tau=None) -> ResultV3:
124
+ base, sv, lat, logits = stage
125
+ if logits is None:
126
+ return ResultV3(output=restore(base, sv), fast_path=True)
127
+ edits = decoder.decode(self.lb, lat, logits,
128
+ self.tau if tau is None else tau,
129
+ fo_bonus=self.fo_bonus)
130
+ return ResultV3(
131
+ output=restore(decoder.splice(base, edits), sv),
132
+ decisions=[{"span": [e.start, e.end], "from": e.observed,
133
+ "to": e.replacement, "utility": round(e.utility, 4),
134
+ "rule_type": e.rule_type} for e in edits])
135
+
136
+ @torch.no_grad()
137
+ def convert_batch(self, texts: list[str], batch_size: int = 32
138
+ ) -> list[ResultV3]:
139
+ return [self.decode_stage(s)
140
+ for s in self.score_batch(texts, batch_size)]
141
+
142
+ # ------------------------------------------------------------------ #
143
+
144
+ @staticmethod
145
+ def _windows(n: int) -> list[tuple[int, int]]:
146
+ if n <= WIN:
147
+ return [(0, n)]
148
+ wins, s = [], 0
149
+ while True:
150
+ wins.append((s, min(s + WIN, n)))
151
+ if s + WIN >= n:
152
+ return wins
153
+ s += STRIDE
154
+
155
+ @staticmethod
156
+ def _assign(lat, wins) -> dict[int, list[int]]:
157
+ """每條邊 → 它最居中的視窗。"""
158
+ out: dict[int, list[int]] = {wi: [] for wi in range(len(wins))}
159
+ for i, e in enumerate(lat.edges):
160
+ best_wi, best_d = None, None
161
+ for wi, (ws, we) in enumerate(wins):
162
+ if e.start >= ws and e.end <= we:
163
+ c = (ws + we) / 2
164
+ d = abs((e.start + e.end) / 2 - c)
165
+ if best_d is None or d < best_d:
166
+ best_wi, best_d = wi, d
167
+ if best_wi is not None:
168
+ out[best_wi].append(i)
169
+ return out
170
+
171
+ def _make_job(self, ti, text, offset, edges, eixs):
172
+ ids, script, prot = text_arrays(text, self.vocab)
173
+ # 邊座標平移到視窗座標
174
+ shifted = []
175
+ for e in edges:
176
+ se = type(e)(e.start - offset, e.end - offset, e.gid, e.obs_ix,
177
+ e.cand_kill, e.word_crossing, e.word_contained)
178
+ shifted.append(se)
179
+ sa = site_arrays(self.lb, shifted, text)
180
+ mids, m_span, _ = build_masked_view(ids, sa["span"], sa["maskable"])
181
+ mscript, _, _ = build_masked_view(script, sa["span"], sa["maskable"],
182
+ mask_id=4)
183
+ mprot, _, _ = build_masked_view(prot.astype(np.uint8), sa["span"],
184
+ sa["maskable"], mask_id=0)
185
+ cand_tok, cand_mask, cand_kill, cand_feat = assemble_cands(
186
+ self.lex, sa["gid"], sa["obs"], sa["clue"], sa["eng"],
187
+ sa["flags"], sa["kill"], reveal_observed=self.reveal)
188
+ return {"ti": ti, "eixs": eixs, "text": text,
189
+ "ids": ids, "script": script, "prot": prot,
190
+ "feat": make_feat(script, prot, sa["span"], len(text)),
191
+ "mids": mids, "m_span": m_span.astype(np.int64),
192
+ "mfeat": make_feat(mscript, mprot, m_span, len(mids)),
193
+ "c_span": sa["span"], "obs": sa["obs"],
194
+ "cand_tok": cand_tok, "cand_mask": cand_mask,
195
+ "cand_kill": cand_kill, "cand_feat": cand_feat}
196
+
197
+ def _stack(self, jobs):
198
+ B = len(jobs)
199
+ T = max(len(j["ids"]) for j in jobs)
200
+ Tm = max(len(j["mids"]) for j in jobs)
201
+ S = max(len(j["c_span"]) for j in jobs)
202
+ C = max(j["cand_tok"].shape[1] for j in jobs)
203
+ out = {
204
+ "ids": np.zeros((B, T), np.int64),
205
+ "feat": np.zeros((B, T, 4), np.int64),
206
+ "pad": np.zeros((B, T), bool),
207
+ "mids": np.zeros((B, Tm), np.int64),
208
+ "mfeat": np.zeros((B, Tm, 4), np.int64),
209
+ "mpad": np.zeros((B, Tm), bool),
210
+ "c_span": np.zeros((B, S, 2), np.int64),
211
+ "m_span": np.zeros((B, S, 2), np.int64),
212
+ "site_mask": np.zeros((B, S), bool),
213
+ "cand_tok": np.zeros((B, S, C, L_MAX), np.int64),
214
+ "cand_mask": np.zeros((B, S, C), bool),
215
+ "cand_kill": np.zeros((B, S, C), bool),
216
+ "cand_feat": np.zeros((B, S, C, FEAT_DIM), np.float32),
217
+ }
218
+ for b, j in enumerate(jobs):
219
+ n, tm = len(j["ids"]), len(j["mids"])
220
+ ns, c = len(j["c_span"]), j["cand_tok"].shape[1]
221
+ out["ids"][b, :n] = j["ids"]
222
+ out["feat"][b, :n] = j["feat"]
223
+ out["pad"][b, :n] = True
224
+ out["mids"][b, :tm] = j["mids"]
225
+ out["mfeat"][b, :tm] = j["mfeat"]
226
+ out["mpad"][b, :tm] = True
227
+ out["c_span"][b, :ns] = j["c_span"]
228
+ out["m_span"][b, :ns] = j["m_span"]
229
+ out["site_mask"][b, :ns] = True
230
+ out["cand_tok"][b, :ns, :c] = j["cand_tok"]
231
+ out["cand_mask"][b, :ns, :c] = j["cand_mask"]
232
+ out["cand_kill"][b, :ns, :c] = j["cand_kill"]
233
+ out["cand_feat"][b, :ns, :c] = j["cand_feat"]
234
+ return {k: torch.from_numpy(v).to(self.device) for k, v in out.items()}