Prechádzať zdrojové kódy

merge: 合并branch 'feat/pinyin'分支

zengeshuai 2 mesiacov pred
rodič
commit
a4c5ad2f6d

+ 187 - 0
components/pinyin/binding/luat_lib_pinyin.c

@@ -0,0 +1,187 @@
+/*
+@module  pinyin
+@summary 拼音输入法核心库
+@version 1.0
+@date    2025.01
+@tag     LUAT_USE_PINYIN
+@usage
+-- 查询拼音对应的候选字
+local pinyin = require "pinyin"
+local codes = pinyin.query("zhong")
+-- codes = {0x4E2D, 0x949F, ...}  -- Unicode码点数组
+*/
+
+#include "luat_base.h"
+#include "luat_pinyin.h"
+
+#define LUAT_LOG_TAG "pinyin"
+#include "luat_log.h"
+
+// codepoint_to_utf8 函数已移至 luat_pinyin.h 作为内联函数
+
+/*
+查询拼音对应的候选字Unicode码点数组
+@api pinyin.query(pinyin_string)
+@string pinyin_string 拼音字符串,如 "zhong"
+@return table Unicode码点数组,如 {0x4E2D, 0x949F, ...},如果无匹配返回空表 {}
+@usage
+local codes = pinyin.query("zhong")
+-- codes = {0x4E2D, 0x949F, ...}  -- "中"、"钟"等
+*/
+static int l_pinyin_query(lua_State *L)
+{
+    size_t len = 0;
+    const char *pinyin = luaL_checklstring(L, 1, &len);
+    
+    if (!pinyin || len == 0) {
+        lua_newtable(L);  // 返回空表
+        return 1;
+    }
+    
+    const uint32_t *codepoints = NULL;
+    uint16_t count = 0;
+    
+    int ret = luat_pinyin_query(pinyin, &codepoints, &count);
+    
+    if (ret != 0 || !codepoints || count == 0) {
+        lua_newtable(L);  // 返回空表
+        return 1;
+    }
+    
+    // 返回码点数组
+    lua_newtable(L);
+    for (uint16_t i = 0; i < count; i++) {
+        lua_pushinteger(L, codepoints[i]);
+        lua_rawseti(L, -2, i + 1);
+    }
+    
+    return 1;
+}
+
+/*
+查询拼音对应的候选字UTF-8字符串数组
+@api pinyin.queryUtf8(pinyin_string)
+@string pinyin_string 拼音字符串,如 "zhong"
+@return table UTF-8字符串数组,如 {"中", "钟", ...},如果无匹配返回空表 {}
+@usage
+local chars = pinyin.queryUtf8("zhong")
+-- chars = {"中", "钟", ...}  -- 直接返回UTF-8字符串数组
+*/
+static int l_pinyin_query_utf8(lua_State *L)
+{
+    size_t len = 0;
+    const char *pinyin = luaL_checklstring(L, 1, &len);
+    
+    if (!pinyin || len == 0) {
+        lua_newtable(L);  // 返回空表
+        return 1;
+    }
+    
+    // 查询码点
+    const uint32_t *codepoints = NULL;
+    uint16_t codepoint_count = 0;
+    
+    int ret = luat_pinyin_query(pinyin, &codepoints, &codepoint_count);
+    
+    if (ret != 0 || !codepoints || codepoint_count == 0) {
+        lua_newtable(L);  // 返回空表
+        return 1;
+    }
+    
+    // 分配临时缓冲区存储UTF-8字符串(每个字符最多5字节)
+    char utf8_buf[5];
+    
+    // 返回UTF-8字符串数组
+    lua_newtable(L);
+    for (uint16_t i = 0; i < codepoint_count; i++) {
+        // 将码点转换为UTF-8字符串
+        int utf8_len = luat_pinyin_codepoint_to_utf8(codepoints[i], utf8_buf);
+        if (utf8_len > 0) {
+            lua_pushlstring(L, utf8_buf, utf8_len);
+            lua_rawseti(L, -2, i + 1);
+        }
+    }
+    
+    return 1;
+}
+
+/*
+查询按键序列对应的音节列表(9键输入法)
+@api pinyin.querySyllables(key_sequence)
+@table key_sequence 按键序列,每个元素为1-8的数字(对应ABC-WXYZ)
+@return table 音节字符串数组,按常用度排序,如 {"zhong", "zong", ...}
+@usage
+local pinyin = require "pinyin"
+local syllables = pinyin.querySyllables({8, 3, 5, 5, 3})  -- WXYZ, GHI, MNO, MNO, GHI
+-- 返回: {"zhong", "zong", ...}
+*/
+static int l_pinyin_query_syllables(lua_State *L)
+{
+    // 获取按键序列表
+    if (!lua_istable(L, 1)) {
+        luaL_argerror(L, 1, "expected table");
+        lua_newtable(L);
+        return 1;
+    }
+    
+    int table_len = (int)luaL_len(L, 1);
+    if (table_len == 0 || table_len > 5) {
+        lua_newtable(L);  // 返回空表
+        return 1;
+    }
+    
+    // 读取按键序列
+    uint8_t key_sequence[5];
+    for (int i = 1; i <= table_len; i++) {
+        lua_rawgeti(L, 1, i);
+        int key_id = (int)lua_tointeger(L, -1);
+        lua_pop(L, 1);
+        
+        if (key_id < 1 || key_id > 8) {
+            lua_newtable(L);  // 无效按键ID,返回空表
+            return 1;
+        }
+        key_sequence[i - 1] = (uint8_t)key_id;
+    }
+    
+    // 分配缓冲区存储音节(最多100个音节)
+    char syllables[100][8];
+    uint16_t actual_count = 0;
+    
+    int ret = luat_pinyin_query_syllables_by_keys(
+        key_sequence,
+        (uint8_t)table_len,
+        syllables,
+        100,
+        &actual_count
+    );
+    
+    if (ret != 0 || actual_count == 0) {
+        lua_newtable(L);  // 返回空表
+        return 1;
+    }
+    
+    // 返回音节字符串数组
+    lua_newtable(L);
+    for (uint16_t i = 0; i < actual_count; i++) {
+        lua_pushstring(L, syllables[i]);
+        lua_rawseti(L, -2, i + 1);
+    }
+    
+    return 1;
+}
+
+static const rotable_Reg_t reg_pinyin[] =
+{
+    {"query", ROREG_FUNC(l_pinyin_query)},
+    {"queryUtf8", ROREG_FUNC(l_pinyin_query_utf8)},
+    {"querySyllables", ROREG_FUNC(l_pinyin_query_syllables)},
+    {NULL, ROREG_INT(0)}
+};
+
+LUAMOD_API int luaopen_pinyin(lua_State *L)
+{
+    luat_newlib2(L, reg_pinyin);
+    return 1;
+}
+

+ 72 - 0
components/pinyin/inc/luat_pinyin.h

@@ -0,0 +1,72 @@
+#ifndef LUAT_PINYIN_H
+#define LUAT_PINYIN_H
+
+#include "luat_base.h"
+#include <stdint.h>
+
+/**
+ * @brief 将Unicode码点转换为UTF-8字符串
+ * @param codepoint Unicode码点
+ * @param utf8_buf 输出缓冲区(至少5字节)
+ * @return UTF-8字节数,失败返回0
+ */
+int luat_pinyin_codepoint_to_utf8(uint32_t codepoint, char *utf8_buf);
+
+/**
+ * @brief 初始化pinyin库(预留接口,当前无需初始化)
+ * @return 0表示成功
+ */
+int luat_pinyin_init(void);
+
+/**
+ * @brief 查询拼音对应的候选字Unicode码点数组
+ * @param pinyin 拼音字符串(小写,无声调)
+ * @param codepoints 输出参数:码点数组指针
+ * @param count 输出参数:候选字数量
+ * @return 0表示找到,-1表示未找到
+ */
+int luat_pinyin_query(const char *pinyin, const uint32_t **codepoints, uint16_t *count);
+
+/**
+ * @brief 查询拼音对应的候选字UTF-8字符串数组
+ * @param pinyin 拼音字符串(小写,无声调)
+ * @param utf8_strings 输出参数:UTF-8字符串数组,每个字符串最多5字节(4字节UTF-8 + '\0')
+ * @param max_count 最大字符串数量(数组大小)
+ * @param count 输出参数:实际返回的字符串数量
+ * @return 0表示成功,-1表示失败
+ */
+int luat_pinyin_query_utf8(const char *pinyin, char (*utf8_strings)[5], uint16_t max_count, uint16_t *count);
+
+/**
+ * @brief 根据按键序列查询可能的音节列表(9键输入法)
+ * @param key_sequence 按键序列数组,每个元素为按键ID(1-8对应ABC-WXYZ)
+ * @param key_count 按键序列长度(最多5个)
+ * @param syllables 输出参数:音节字符串数组(调用者需要分配内存)
+ * @param max_syllable_count 最大音节数量(数组大小)
+ * @param actual_count 输出参数:实际返回的音节数量
+ * @return 0表示成功,-1表示失败
+ * 
+ * 按键ID映射:
+ * 1 → ABC   (a, b, c)
+ * 2 → DEF   (d, e, f)
+ * 3 → GHI   (g, h, i)
+ * 4 → JKL   (j, k, l)
+ * 5 → MNO   (m, n, o)
+ * 6 → PQRS  (p, q, r, s)
+ * 7 → TUV   (t, u, v)
+ * 8 → WXYZ  (w, x, y, z)
+ * 
+ * 示例:
+ * 输入:key_sequence = [8, 3, 5, 5, 3] (对应 WXYZ, GHI, MNO, MNO, GHI)
+ * 输出:可能的音节:["zhong", "zong", ...](按常用度排序)
+ */
+int luat_pinyin_query_syllables_by_keys(
+    const uint8_t *key_sequence, 
+    uint8_t key_count,
+    char (*syllables)[8],  // 每个音节最多7个字母+'\0'
+    uint16_t max_syllable_count,
+    uint16_t *actual_count
+);
+
+#endif /* LUAT_PINYIN_H */
+

+ 2480 - 0
components/pinyin/inc/pinyin_dict.h

@@ -0,0 +1,2480 @@
+/* Generated by gb2312_pinyin_c.py */
+#ifndef PINYIN_DICT_H
+#define PINYIN_DICT_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct {
+    const char *pinyin;
+    const uint32_t *codepoints;
+    uint16_t count;
+} pinyin_entry_t;
+
+static const uint32_t pinyin_a_codepoints[] = {
+    0x554A, 0x963F, 0x5475
+};
+
+static const uint32_t pinyin_ai_codepoints[] = {
+    0x57C3, 0x6328, 0x54CE, 0x5509, 0x54C0, 0x7691, 0x764C, 0x853C,
+    0x77EE, 0x827E, 0x788D, 0x7231, 0x9698, 0x5446, 0x4E43, 0x5947
+};
+
+static const uint32_t pinyin_an_codepoints[] = {
+    0x978D, 0x6C28, 0x5B89, 0x4FFA, 0x6309, 0x6697, 0x5CB8, 0x80FA,
+    0x6848, 0x5382, 0x5E72, 0x5E7F, 0x76D2
+};
+
+static const uint32_t pinyin_ang_codepoints[] = {
+    0x80AE, 0x6602, 0x76CE, 0x4EF0
+};
+
+static const uint32_t pinyin_ao_codepoints[] = {
+    0x51F9, 0x6556, 0x71AC, 0x7FF1, 0x8884, 0x50B2, 0x5965, 0x61CA,
+    0x6FB3, 0x68CD, 0x56A3
+};
+
+static const uint32_t pinyin_ba_codepoints[] = {
+    0x82AD, 0x634C, 0x6252, 0x53ED, 0x5427, 0x7B06, 0x516B, 0x75A4,
+    0x5DF4, 0x62D4, 0x8DCB, 0x9776, 0x628A, 0x8019, 0x575D, 0x9738,
+    0x7F62, 0x7238, 0x4F2F, 0x6E43
+};
+
+static const uint32_t pinyin_bai_codepoints[] = {
+    0x6252, 0x767D, 0x67CF, 0x767E, 0x6446, 0x4F70, 0x8D25, 0x62DC,
+    0x7A17, 0x4F2F, 0x5561, 0x6392, 0x6D3E
+};
+
+static const uint32_t pinyin_ban_codepoints[] = {
+    0x6591, 0x73ED, 0x642C, 0x6273, 0x822C, 0x9881, 0x677F, 0x7248,
+    0x626E, 0x62CC, 0x4F34, 0x74E3, 0x534A, 0x529E, 0x7ECA, 0x5351,
+    0x8FA8, 0x5F6C
+};
+
+static const uint32_t pinyin_bang_codepoints[] = {
+    0x90A6, 0x5E2E, 0x6886, 0x699C, 0x8180, 0x7ED1, 0x68D2, 0x78C5,
+    0x868C, 0x9551, 0x508D, 0x8C24, 0x65C1, 0x5F6D
+};
+
+static const uint32_t pinyin_bao_codepoints[] = {
+    0x82DE, 0x80DE, 0x5305, 0x8912, 0x5265, 0x8584, 0x96F9, 0x4FDD,
+    0x5821, 0x9971, 0x5B9D, 0x62B1, 0x62A5, 0x66B4, 0x8C79, 0x9C8D,
+    0x7206, 0x5446, 0x5228, 0x70AE, 0x888D, 0x66DD, 0x7011
+};
+
+static const uint32_t pinyin_bei_codepoints[] = {
+    0x62D4, 0x8DCB, 0x676F, 0x7891, 0x60B2, 0x5351, 0x5317, 0x8F88,
+    0x80CC, 0x8D1D, 0x94A1, 0x500D, 0x72C8, 0x5907, 0x60EB, 0x7119,
+    0x88AB, 0x81C2, 0x6CE2, 0x8461, 0x83E9
+};
+
+static const uint32_t pinyin_ben_codepoints[] = {
+    0x5954, 0x82EF, 0x672C, 0x7B28, 0x592F, 0x4F53
+};
+
+static const uint32_t pinyin_beng_codepoints[] = {
+    0x699C, 0x868C, 0x508D, 0x5D29, 0x7EF7, 0x752D, 0x6CF5, 0x8E66,
+    0x8FF8, 0x65C1, 0x62A8, 0x5E73
+};
+
+static const uint32_t pinyin_bi_codepoints[] = {
+    0x5351, 0x88AB, 0x903C, 0x9F3B, 0x6BD4, 0x9119, 0x7B14, 0x5F7C,
+    0x78A7, 0x84D6, 0x853D, 0x6BD5, 0x6BD9, 0x6BD6, 0x5E01, 0x5E87,
+    0x75F9, 0x95ED, 0x655D, 0x5F0A, 0x5FC5, 0x8F9F, 0x58C1, 0x81C2,
+    0x907F, 0x965B, 0x6CE2, 0x80A5, 0x4F5B, 0x62C2, 0x5E45, 0x670D,
+    0x8651, 0x79D8, 0x6CCC, 0x813E, 0x77A5
+};
+
+static const uint32_t pinyin_bian_codepoints[] = {
+    0x97AD, 0x8FB9, 0x7F16, 0x8D2C, 0x6241, 0x4FBF, 0x53D8, 0x535E,
+    0x8FA8, 0x8FA9, 0x8FAB, 0x904D, 0x5C01
+};
+
+static const uint32_t pinyin_biao_codepoints[] = {
+    0x82DE, 0x6807, 0x5F6A, 0x8198, 0x8868, 0x6F02
+};
+
+static const uint32_t pinyin_bie_codepoints[] = {
+    0x634C, 0x6252, 0x62D4, 0x853D, 0x9CD6, 0x618B, 0x522B, 0x762A,
+    0x79D8, 0x6487
+};
+
+static const uint32_t pinyin_bin_codepoints[] = {
+    0x5F6C, 0x658C, 0x6FD2, 0x6EE8, 0x5BBE, 0x6448, 0x4EFD
+};
+
+static const uint32_t pinyin_bing_codepoints[] = {
+    0x5175, 0x51B0, 0x67C4, 0x4E19, 0x79C9, 0x997C, 0x70B3, 0x75C5,
+    0x5E76, 0x62FC, 0x5E73, 0x5C4F
+};
+
+static const uint32_t pinyin_bo_codepoints[] = {
+    0x62D4, 0x767D, 0x67CF, 0x767E, 0x822C, 0x5265, 0x8584, 0x66B4,
+    0x7206, 0x73BB, 0x83E0, 0x64AD, 0x62E8, 0x94B5, 0x6CE2, 0x535A,
+    0x52C3, 0x640F, 0x94C2, 0x7B94, 0x4F2F, 0x5E1B, 0x8236, 0x8116,
+    0x818A, 0x6E24, 0x6CCA, 0x9A73, 0x535C, 0x7C3F, 0x756A, 0x4F5B,
+    0x670D, 0x52DF, 0x6015, 0x62CD, 0x6F58, 0x8DD1, 0x9B44, 0x83E9,
+    0x84B2, 0x7011
+};
+
+static const uint32_t pinyin_bu_codepoints[] = {
+    0x8584, 0x5821, 0x6355, 0x535C, 0x54FA, 0x8865, 0x57E0, 0x4E0D,
+    0x5E03, 0x6B65, 0x7C3F, 0x90E8, 0x6016, 0x9644, 0x57D4
+};
+
+static const uint32_t pinyin_ca_codepoints[] = {
+    0x64E6, 0x8521, 0x62C6
+};
+
+static const uint32_t pinyin_cai_codepoints[] = {
+    0x731C, 0x88C1, 0x6750, 0x624D, 0x8D22, 0x776C, 0x8E29, 0x91C7,
+    0x5F69, 0x83DC, 0x8521
+};
+
+static const uint32_t pinyin_can_codepoints[] = {
+    0x9910, 0x53C2, 0x8695, 0x6B8B, 0x60ED, 0x60E8, 0x707F, 0x63BA
+};
+
+static const uint32_t pinyin_cang_codepoints[] = {
+    0x82CD, 0x8231, 0x4ED3, 0x6CA7, 0x85CF
+};
+
+static const uint32_t pinyin_cao_codepoints[] = {
+    0x64CD, 0x7CD9, 0x69FD, 0x66F9, 0x8349, 0x6FA1, 0x9020
+};
+
+static const uint32_t pinyin_ce_codepoints[] = {
+    0x5395, 0x7B56, 0x4FA7, 0x518C, 0x6D4B, 0x8D66, 0x6805
+};
+
+static const uint32_t pinyin_cen_codepoints[] = {
+    0x53C2
+};
+
+static const uint32_t pinyin_ceng_codepoints[] = {
+    0x5C42, 0x8E6D, 0x50E7, 0x589E, 0x66FE
+};
+
+static const uint32_t pinyin_cha_codepoints[] = {
+    0x63D2, 0x53C9, 0x832C, 0x8336, 0x67E5, 0x78B4, 0x643D, 0x5BDF,
+    0x5C94, 0x5DEE, 0x8BE7, 0x63A5, 0x6377, 0x5239, 0x571F, 0x659C,
+    0x55B3
+};
+
+static const uint32_t pinyin_chai_codepoints[] = {
+    0x67E5, 0x5DEE, 0x62C6, 0x67F4, 0x8C7A, 0x6413
+};
+
+static const uint32_t pinyin_chan_codepoints[] = {
+    0x6400, 0x63BA, 0x8749, 0x998B, 0x8C17, 0x7F20, 0x94F2, 0x4EA7,
+    0x9610, 0x98A4, 0x5355, 0x5398, 0x82EB, 0x5154, 0x6CBE
+};
+
+static const uint32_t pinyin_chang_codepoints[] = {
+    0x660C, 0x7316, 0x573A, 0x5C1D, 0x5E38, 0x957F, 0x507F, 0x80A0,
+    0x5382, 0x655E, 0x7545, 0x5531, 0x5021, 0x5C1A, 0x88F3, 0x5018,
+    0x6DCC
+};
+
+static const uint32_t pinyin_chao_codepoints[] = {
+    0x8D85, 0x6284, 0x949E, 0x671D, 0x5632, 0x6F6E, 0x5DE2, 0x5435,
+    0x7092, 0x7EF0, 0x527F
+};
+
+static const uint32_t pinyin_che_codepoints[] = {
+    0x62C6, 0x8F66, 0x626F, 0x64A4, 0x63A3, 0x5F7B, 0x6F88, 0x6C60,
+    0x5C3A, 0x65A5, 0x5B85
+};
+
+static const uint32_t pinyin_chen_codepoints[] = {
+    0x90F4, 0x81E3, 0x8FB0, 0x5C18, 0x6668, 0x5FF1, 0x6C89, 0x9648,
+    0x8D81, 0x886C, 0x79F0, 0x6A59, 0x582A, 0x5E18, 0x6C88, 0x586B,
+    0x6E5B, 0x6795, 0x75B9
+};
+
+static const uint32_t pinyin_cheng_codepoints[] = {
+    0x655E, 0x6491, 0x79F0, 0x57CE, 0x6A59, 0x6210, 0x5448, 0x4E58,
+    0x7A0B, 0x60E9, 0x6F84, 0x8BDA, 0x627F, 0x901E, 0x9A8B, 0x79E4,
+    0x76EF, 0x51C0, 0x68F1, 0x76DB, 0x8D9F, 0x9192
+};
+
+static const uint32_t pinyin_chi_codepoints[] = {
+    0x832C, 0x62C6, 0x5403, 0x75F4, 0x6301, 0x5319, 0x6C60, 0x8FDF,
+    0x5F1B, 0x9A70, 0x803B, 0x9F7F, 0x4F88, 0x5C3A, 0x8D64, 0x7FC5,
+    0x65A5, 0x70BD, 0x54C6, 0x79BB, 0x8389, 0x86C7, 0x5979, 0x62AC,
+    0x63D0, 0x62D6, 0x559C, 0x79FB, 0x6CBB
+};
+
+static const uint32_t pinyin_chong_codepoints[] = {
+    0x5145, 0x51B2, 0x866B, 0x5D07, 0x5BA0, 0x8327, 0x916E, 0x6D8C,
+    0x76C5, 0x79CD, 0x91CD, 0x70DB
+};
+
+static const uint32_t pinyin_chou_codepoints[] = {
+    0x62BD, 0x916C, 0x7574, 0x8E0C, 0x7A20, 0x6101, 0x7B79, 0x4EC7,
+    0x7EF8, 0x7785, 0x4E11, 0x81ED, 0x626D
+};
+
+static const uint32_t pinyin_chu_codepoints[] = {
+    0x521D, 0x51FA, 0x6A71, 0x53A8, 0x8E87, 0x9504, 0x96CF, 0x6EC1,
+    0x9664, 0x695A, 0x7840, 0x50A8, 0x77D7, 0x6410, 0x89E6, 0x5904,
+    0x786B, 0x67E0, 0x6DD1, 0x6D82, 0x755C, 0x7D6E, 0x8457, 0x52A9,
+    0x795D
+};
+
+static const uint32_t pinyin_chua_codepoints[] = {
+    0x64AE
+};
+
+static const uint32_t pinyin_chuai_codepoints[] = {
+    0x63E3
+};
+
+static const uint32_t pinyin_chuan_codepoints[] = {
+    0x5DDD, 0x7A7F, 0x693D, 0x4F20, 0x8239, 0x5598, 0x4E32
+};
+
+static const uint32_t pinyin_chuang_codepoints[] = {
+    0x75AE, 0x7A97, 0x5E62, 0x5E8A, 0x95EF, 0x521B, 0x8471, 0x56F1
+};
+
+static const uint32_t pinyin_chui_codepoints[] = {
+    0x5439, 0x708A, 0x6376, 0x9524, 0x5782, 0x690E
+};
+
+static const uint32_t pinyin_chun_codepoints[] = {
+    0x6625, 0x693F, 0x9187, 0x5507, 0x6DF3, 0x7EAF, 0x8822
+};
+
+static const uint32_t pinyin_chuo_codepoints[] = {
+    0x8E87, 0x6233, 0x7EF0, 0x7C07, 0x4FC3, 0x6DD6, 0x919B
+};
+
+static const uint32_t pinyin_ci_codepoints[] = {
+    0x5DEE, 0x67F4, 0x75B5, 0x8328, 0x78C1, 0x96CC, 0x8F9E, 0x6148,
+    0x74F7, 0x8BCD, 0x6B64, 0x523A, 0x8D50, 0x6B21, 0x63AA, 0x53F8,
+    0x4F3A, 0x5179, 0x6ECB
+};
+
+static const uint32_t pinyin_cong_codepoints[] = {
+    0x7A97, 0x806A, 0x8471, 0x56F1, 0x5306, 0x4ECE, 0x4E1B
+};
+
+static const uint32_t pinyin_cou_codepoints[] = {
+    0x51D1, 0x7C07, 0x8DA3, 0x594F, 0x63CD, 0x65CF
+};
+
+static const uint32_t pinyin_cu_codepoints[] = {
+    0x7C97, 0x918B, 0x7C07, 0x4FC3, 0x621A, 0x4E14, 0x8DA3, 0x5352
+};
+
+static const uint32_t pinyin_cuan_codepoints[] = {
+    0x8E7F, 0x7BE1, 0x7A9C, 0x8E72, 0x6512
+};
+
+static const uint32_t pinyin_cui_codepoints[] = {
+    0x5BDF, 0x6467, 0x5D14, 0x50AC, 0x8106, 0x7601, 0x7CB9, 0x6DEC,
+    0x7FE0, 0x6D12, 0x8870, 0x4F53, 0x5352
+};
+
+static const uint32_t pinyin_cun_codepoints[] = {
+    0x6751, 0x5B58, 0x5BF8, 0x8E72, 0x6D5A
+};
+
+static const uint32_t pinyin_cuo_codepoints[] = {
+    0x5DEE, 0x6467, 0x78CB, 0x64AE, 0x6413, 0x63AA, 0x632B, 0x9519,
+    0x6614, 0x6700
+};
+
+static const uint32_t pinyin_da_codepoints[] = {
+    0x642D, 0x8FBE, 0x7B54, 0x7629, 0x6253, 0x5927, 0x80C6, 0x8FED,
+    0x584C, 0x5854
+};
+
+static const uint32_t pinyin_dai_codepoints[] = {
+    0x5927, 0x5446, 0x6B79, 0x50A3, 0x6234, 0x5E26, 0x6B86, 0x4EE3,
+    0x8D37, 0x888B, 0x5F85, 0x902E, 0x6020, 0x6BD2, 0x96B6
+};
+
+static const uint32_t pinyin_dan_codepoints[] = {
+    0x5FF1, 0x803D, 0x62C5, 0x4E39, 0x5355, 0x90F8, 0x63B8, 0x80C6,
+    0x65E6, 0x6C2E, 0x4F46, 0x60EE, 0x6DE1, 0x8BDE, 0x5F39, 0x86CB,
+    0x61BE, 0x5189, 0x77F3, 0x6F6D, 0x8712, 0x8A79, 0x6E5B
+};
+
+static const uint32_t pinyin_dang_codepoints[] = {
+    0x5F53, 0x6321, 0x515A, 0x8361, 0x6863
+};
+
+static const uint32_t pinyin_dao_codepoints[] = {
+    0x5200, 0x6363, 0x8E48, 0x5012, 0x5C9B, 0x7977, 0x5BFC, 0x5230,
+    0x7A3B, 0x60BC, 0x9053, 0x76D7, 0x6566, 0x53D7, 0x9676
+};
+
+static const uint32_t pinyin_de_codepoints[] = {
+    0x5FB7, 0x5F97, 0x7684, 0x767B, 0x5E95, 0x5730
+};
+
+static const uint32_t pinyin_dei_codepoints[] = {
+    0x5F97
+};
+
+static const uint32_t pinyin_deng_codepoints[] = {
+    0x6A59, 0x6F84, 0x8E6C, 0x706F, 0x767B, 0x7B49, 0x77AA, 0x51F3,
+    0x9093
+};
+
+static const uint32_t pinyin_di_codepoints[] = {
+    0x902E, 0x7684, 0x5824, 0x4F4E, 0x6EF4, 0x8FEA, 0x654C, 0x7B1B,
+    0x72C4, 0x6DA4, 0x7FDF, 0x5AE1, 0x62B5, 0x5E95, 0x5730, 0x8482,
+    0x7B2C, 0x5E1D, 0x5F1F, 0x9012, 0x7F14, 0x96B6, 0x828D, 0x52FA,
+    0x63D0, 0x8E44, 0x9010
+};
+
+static const uint32_t pinyin_dian_codepoints[] = {
+    0x98A0, 0x6382, 0x6EC7, 0x7898, 0x70B9, 0x5178, 0x975B, 0x57AB,
+    0x7535, 0x4F43, 0x7538, 0x5E97, 0x60E6, 0x5960, 0x6DC0, 0x6BBF,
+    0x62C8, 0x6D8E, 0x6CBE
+};
+
+static const uint32_t pinyin_diao_codepoints[] = {
+    0x7A20, 0x5200, 0x7889, 0x53FC, 0x96D5, 0x51CB, 0x5201, 0x6389,
+    0x540A, 0x9493, 0x8C03, 0x6566, 0x9E1F, 0x6311, 0x8DF3
+};
+
+static const uint32_t pinyin_die_codepoints[] = {
+    0x8DCC, 0x7239, 0x789F, 0x8776, 0x8FED, 0x8C0D, 0x53E0, 0x54C6,
+    0x6D89, 0x8E22, 0x81F3, 0x7A92
+};
+
+static const uint32_t pinyin_ding_codepoints[] = {
+    0x706F, 0x5960, 0x4E01, 0x76EF, 0x53EE, 0x9489, 0x9876, 0x9F0E,
+    0x952D, 0x5B9A, 0x8BA2, 0x6C40
+};
+
+static const uint32_t pinyin_diu_codepoints[] = {
+    0x4E22
+};
+
+static const uint32_t pinyin_dong_codepoints[] = {
+    0x4E1C, 0x51AC, 0x8463, 0x61C2, 0x52A8, 0x680B, 0x4F97, 0x606B,
+    0x51BB, 0x6D1E, 0x6850, 0x916E, 0x7B52
+};
+
+static const uint32_t pinyin_dou_codepoints[] = {
+    0x515C, 0x6296, 0x6597, 0x9661, 0x8C46, 0x9017, 0x75D8, 0x90FD,
+    0x8BFB, 0x6295, 0x903E
+};
+
+static const uint32_t pinyin_du_codepoints[] = {
+    0x90FD, 0x7763, 0x6BD2, 0x728A, 0x72EC, 0x8BFB, 0x5835, 0x7779,
+    0x8D4C, 0x675C, 0x9540, 0x809A, 0x5EA6, 0x6E21, 0x5992, 0x987F,
+    0x571F, 0x5B85
+};
+
+static const uint32_t pinyin_duan_codepoints[] = {
+    0x7AEF, 0x77ED, 0x953B, 0x6BB5, 0x65AD, 0x7F0E
+};
+
+static const uint32_t pinyin_dui_codepoints[] = {
+    0x5806, 0x5151, 0x961F, 0x5BF9, 0x6566, 0x8FFD
+};
+
+static const uint32_t pinyin_dun_codepoints[] = {
+    0x58A9, 0x5428, 0x8E72, 0x6566, 0x987F, 0x56E4, 0x949D, 0x76FE,
+    0x9041, 0x4FCA
+};
+
+static const uint32_t pinyin_duo_codepoints[] = {
+    0x63E3, 0x6376, 0x5EA6, 0x5151, 0x6387, 0x54C6, 0x591A, 0x593A,
+    0x579B, 0x8EB2, 0x6735, 0x8DFA, 0x8235, 0x5241, 0x60F0, 0x5815,
+    0x968B, 0x9640, 0x9A6E, 0x6742
+};
+
+static const uint32_t pinyin_e_codepoints[] = {
+    0x554A, 0x963F, 0x9698, 0x80FA, 0x6B79, 0x86FE, 0x5CE8, 0x9E45,
+    0x4FC4, 0x989D, 0x8BB9, 0x5A25, 0x6076, 0x5384, 0x627C, 0x904F,
+    0x9102, 0x997F, 0x86E4, 0x54E6, 0x9091
+};
+
+static const uint32_t pinyin_en_codepoints[] = {
+    0x6069
+};
+
+static const uint32_t pinyin_er_codepoints[] = {
+    0x800C, 0x513F, 0x8033, 0x5C14, 0x9975, 0x6D31, 0x4E8C, 0x8D30
+};
+
+static const uint32_t pinyin_fa_codepoints[] = {
+    0x62D4, 0x53D1, 0x7F5A, 0x7B4F, 0x4F10, 0x4E4F, 0x9600, 0x6CD5,
+    0x73D0, 0x6CDB
+};
+
+static const uint32_t pinyin_fan_codepoints[] = {
+    0x85E9, 0x5E06, 0x756A, 0x7FFB, 0x6A0A, 0x77FE, 0x9492, 0x7E41,
+    0x51E1, 0x70E6, 0x53CD, 0x8FD4, 0x8303, 0x8D29, 0x72AF, 0x996D,
+    0x6CDB, 0x6F58
+};
+
+static const uint32_t pinyin_fang_codepoints[] = {
+    0x574A, 0x82B3, 0x65B9, 0x80AA, 0x623F, 0x9632, 0x59A8, 0x4EFF,
+    0x8BBF, 0x7EBA, 0x653E
+};
+
+static const uint32_t pinyin_fei_codepoints[] = {
+    0x83F2, 0x975E, 0x5561, 0x98DE, 0x80A5, 0x532A, 0x8BFD, 0x5420,
+    0x80BA, 0x5E9F, 0x6CB8, 0x8D39, 0x62C2, 0x88F4
+};
+
+static const uint32_t pinyin_fen_codepoints[] = {
+    0x626E, 0x5954, 0x532A, 0x82AC, 0x915A, 0x5429, 0x6C1B, 0x5206,
+    0x7EB7, 0x575F, 0x711A, 0x6C7E, 0x7C89, 0x594B, 0x4EFD, 0x5FFF,
+    0x6124, 0x7CAA, 0x76FC
+};
+
+static const uint32_t pinyin_feng_codepoints[] = {
+    0x868C, 0x6CDB, 0x65B9, 0x4E30, 0x5C01, 0x67AB, 0x8702, 0x5CF0,
+    0x950B, 0x98CE, 0x75AF, 0x70FD, 0x9022, 0x51AF, 0x7F1D, 0x8BBD,
+    0x5949, 0x51E4, 0x6367
+};
+
+static const uint32_t pinyin_fo_codepoints[] = {
+    0x4F5B
+};
+
+static const uint32_t pinyin_fou_codepoints[] = {
+    0x4E0D, 0x5426
+};
+
+static const uint32_t pinyin_fu_codepoints[] = {
+    0x5305, 0x54FA, 0x4E0D, 0x6CB8, 0x4F5B, 0x592B, 0x6577, 0x80A4,
+    0x5B75, 0x6276, 0x62C2, 0x8F90, 0x5E45, 0x6C1F, 0x7B26, 0x4F0F,
+    0x4FD8, 0x670D, 0x6D6E, 0x6DAA, 0x798F, 0x88B1, 0x5F17, 0x752B,
+    0x629A, 0x8F85, 0x4FEF, 0x91DC, 0x65A7, 0x812F, 0x8151, 0x5E9C,
+    0x8150, 0x8D74, 0x526F, 0x8986, 0x8D4B, 0x590D, 0x5085, 0x4ED8,
+    0x961C, 0x7236, 0x8179, 0x8D1F, 0x5BCC, 0x8BA3, 0x9644, 0x5987,
+    0x7F1A, 0x5490, 0x6000, 0x8FD8, 0x4EC5, 0x8386, 0x5E02
+};
+
+static const uint32_t pinyin_ga_codepoints[] = {
+    0x5676, 0x560E, 0x80F3, 0x5939, 0x5496, 0x8F67
+};
+
+static const uint32_t pinyin_gai_codepoints[] = {
+    0x8BE5, 0x6539, 0x6982, 0x9499, 0x76D6, 0x6E89, 0x9AB8, 0x6838,
+    0x82A5, 0x54B3, 0x6C7D
+};
+
+static const uint32_t pinyin_gan_codepoints[] = {
+    0x5E72, 0x7518, 0x6746, 0x67D1, 0x7AFF, 0x809D, 0x8D76, 0x611F,
+    0x79C6, 0x6562, 0x8D63, 0x4E2A, 0x634D, 0x6C57, 0x5978, 0x4E7E
+};
+
+static const uint32_t pinyin_gang_codepoints[] = {
+    0x80AE, 0x5188, 0x521A, 0x94A2, 0x7F38, 0x809B, 0x7EB2, 0x5C97,
+    0x6E2F, 0x6760, 0x625B, 0x6297, 0x4EA2
+};
+
+static const uint32_t pinyin_gao_codepoints[] = {
+    0x7BD9, 0x768B, 0x9AD8, 0x818F, 0x7F94, 0x7CD5, 0x641E, 0x9550,
+    0x7A3F, 0x544A, 0x6D69, 0x548E
+};
+
+static const uint32_t pinyin_ge_codepoints[] = {
+    0x5676, 0x76D6, 0x54E5, 0x6B4C, 0x6401, 0x6208, 0x9E3D, 0x80F3,
+    0x7599, 0x5272, 0x9769, 0x845B, 0x683C, 0x86E4, 0x9601, 0x9694,
+    0x94EC, 0x4E2A, 0x5404, 0x6D69, 0x83CF, 0x5408, 0x5047, 0x4ECB,
+    0x54AF, 0x53EF, 0x5C79
+};
+
+static const uint32_t pinyin_gei_codepoints[] = {
+    0x7ED9
+};
+
+static const uint32_t pinyin_gen_codepoints[] = {
+    0x6839, 0x8DDF, 0x75D5
+};
+
+static const uint32_t pinyin_geng_codepoints[] = {
+    0x8015, 0x66F4, 0x5E9A, 0x7FB9, 0x57C2, 0x803F, 0x6897, 0x9888,
+    0x4EA2, 0x90A2, 0x786C
+};
+
+static const uint32_t pinyin_gong_codepoints[] = {
+    0x6760, 0x5DE5, 0x653B, 0x529F, 0x606D, 0x9F9A, 0x4F9B, 0x8EAC,
+    0x516C, 0x5BAB, 0x5F13, 0x5DE9, 0x6C5E, 0x62F1, 0x8D21, 0x5171,
+    0x8679, 0x7EA2, 0x78FA
+};
+
+static const uint32_t pinyin_gou_codepoints[] = {
+    0x94A9, 0x52FE, 0x6C9F, 0x82DF, 0x72D7, 0x57A2, 0x6784, 0x8D2D,
+    0x591F, 0x62D8, 0x53E5
+};
+
+static const uint32_t pinyin_gu_codepoints[] = {
+    0x768B, 0x544A, 0x8F9C, 0x83C7, 0x5495, 0x7B8D, 0x4F30, 0x6CBD,
+    0x5B64, 0x59D1, 0x9F13, 0x53E4, 0x86CA, 0x9AA8, 0x8C37, 0x80A1,
+    0x6545, 0x987E, 0x56FA, 0x96C7, 0x6ED1, 0x5BB6, 0x8D3E, 0x89D2,
+    0x67AF, 0x82E6
+};
+
+static const uint32_t pinyin_gua_codepoints[] = {
+    0x522E, 0x74DC, 0x5250, 0x5BE1, 0x6302, 0x8902, 0x62EC, 0x820C
+};
+
+static const uint32_t pinyin_guai_codepoints[] = {
+    0x4E56, 0x62D0, 0x602A
+};
+
+static const uint32_t pinyin_guan_codepoints[] = {
+    0x4E32, 0x68FA, 0x5173, 0x5B98, 0x51A0, 0x89C2, 0x7BA1, 0x9986,
+    0x7F50, 0x60EF, 0x704C, 0x8D2F, 0x679C, 0x7EB6, 0x65A1
+};
+
+static const uint32_t pinyin_guang_codepoints[] = {
+    0x5149, 0x5E7F, 0x901B, 0x6A2A, 0x604D
+};
+
+static const uint32_t pinyin_gui_codepoints[] = {
+    0x6982, 0x7470, 0x89C4, 0x572D, 0x7845, 0x5F52, 0x9F9F, 0x95FA,
+    0x8F68, 0x9B3C, 0x8BE1, 0x7678, 0x6842, 0x67DC, 0x8DEA, 0x8D35,
+    0x523D, 0x6485, 0x5080, 0x7948, 0x7094, 0x54C7, 0x6D3C, 0x5A03,
+    0x6845
+};
+
+static const uint32_t pinyin_gun_codepoints[] = {
+    0x8F8A, 0x6EDA, 0x68CD, 0x6DF7, 0x5377
+};
+
+static const uint32_t pinyin_guo_codepoints[] = {
+    0x9505, 0x90ED, 0x56FD, 0x679C, 0x88F9, 0x8FC7, 0x552C, 0x5212,
+    0x6D3B, 0x6DA1
+};
+
+static const uint32_t pinyin_ha_codepoints[] = {
+    0x86E4, 0x54C8, 0x5475, 0x867E, 0x5413
+};
+
+static const uint32_t pinyin_hai_codepoints[] = {
+    0x9AB8, 0x5B69, 0x6D77, 0x6C26, 0x4EA5, 0x5BB3, 0x9A87, 0x8FD8,
+    0x54B3
+};
+
+static const uint32_t pinyin_han_codepoints[] = {
+    0x5382, 0x7518, 0x611F, 0x9163, 0x61A8, 0x90AF, 0x97E9, 0x542B,
+    0x6DB5, 0x5BD2, 0x51FD, 0x558A, 0x7F55, 0x7FF0, 0x64BC, 0x634D,
+    0x65F1, 0x61BE, 0x608D, 0x710A, 0x6C57, 0x6C49, 0x5D4C
+};
+
+static const uint32_t pinyin_hang_codepoints[] = {
+    0x80AE, 0x592F, 0x676D, 0x822A, 0x72E0, 0x7095, 0x542D, 0x72FC,
+    0x5DF7, 0x884C
+};
+
+static const uint32_t pinyin_hao_codepoints[] = {
+    0x768B, 0x9550, 0x58D5, 0x568E, 0x8C6A, 0x6BEB, 0x90DD, 0x597D,
+    0x8017, 0x53F7, 0x6D69, 0x8C89, 0x552C
+};
+
+static const uint32_t pinyin_he_codepoints[] = {
+    0x683C, 0x7845, 0x54C8, 0x5BB3, 0x5475, 0x559D, 0x8377, 0x83CF,
+    0x6838, 0x79BE, 0x548C, 0x4F55, 0x5408, 0x76D2, 0x8C89, 0x9602,
+    0x6CB3, 0x6DB8, 0x8D6B, 0x8910, 0x9E64, 0x8D3A, 0x547C, 0x970D,
+    0x63ED, 0x82DB, 0x6E34, 0x6D3D, 0x5413, 0x874E
+};
+
+static const uint32_t pinyin_hei_codepoints[] = {
+    0x563F, 0x9ED1
+};
+
+static const uint32_t pinyin_hen_codepoints[] = {
+    0x75D5, 0x5F88, 0x72E0, 0x6068, 0x6380
+};
+
+static const uint32_t pinyin_heng_codepoints[] = {
+    0x54FC, 0x4EA8, 0x6A2A, 0x8861, 0x6052, 0x884C
+};
+
+static const uint32_t pinyin_hng_codepoints[] = {
+    0x54FC
+};
+
+static const uint32_t pinyin_hong_codepoints[] = {
+    0x6E2F, 0x5171, 0x8F70, 0x54C4, 0x70D8, 0x8679, 0x9E3F, 0x6D2A,
+    0x5B8F, 0x5F18, 0x7EA2, 0x6C6A
+};
+
+static const uint32_t pinyin_hou_codepoints[] = {
+    0x5589, 0x4FAF, 0x7334, 0x543C, 0x539A, 0x5019, 0x540E
+};
+
+static const uint32_t pinyin_hu_codepoints[] = {
+    0x96C7, 0x6838, 0x548C, 0x547C, 0x4E4E, 0x5FFD, 0x745A, 0x58F6,
+    0x846B, 0x80E1, 0x8774, 0x72D0, 0x7CCA, 0x6E56, 0x5F27, 0x864E,
+    0x552C, 0x62A4, 0x4E92, 0x6CAA, 0x6237, 0x82E6, 0x82A6, 0x620F,
+    0x8BB8, 0x7FBD
+};
+
+static const uint32_t pinyin_hua_codepoints[] = {
+    0x654C, 0x82B1, 0x54D7, 0x534E, 0x733E, 0x6ED1, 0x753B, 0x5212,
+    0x5316, 0x8BDD, 0x8C41, 0x54C7, 0x627E
+};
+
+static const uint32_t pinyin_huai_codepoints[] = {
+    0x5212, 0x69D0, 0x5F8A, 0x6000, 0x6DEE, 0x574F, 0x576F
+};
+
+static const uint32_t pinyin_huan_codepoints[] = {
+    0x704C, 0x6B22, 0x73AF, 0x6853, 0x8FD8, 0x7F13, 0x6362, 0x60A3,
+    0x5524, 0x75EA, 0x8C62, 0x7115, 0x6DA3, 0x5BA6, 0x5E7B, 0x7696,
+    0x7729, 0x63F4
+};
+
+static const uint32_t pinyin_huang_codepoints[] = {
+    0x6A2A, 0x8352, 0x614C, 0x9EC4, 0x78FA, 0x8757, 0x7C27, 0x7687,
+    0x51F0, 0x60F6, 0x714C, 0x6643, 0x5E4C, 0x604D, 0x8C0E, 0x8292,
+    0x832B
+};
+
+static const uint32_t pinyin_hui_codepoints[] = {
+    0x866B, 0x5815, 0x5F8A, 0x6DA3, 0x7070, 0x6325, 0x8F89, 0x5FBD,
+    0x6062, 0x86D4, 0x56DE, 0x6BC1, 0x6094, 0x6167, 0x5349, 0x60E0,
+    0x6666, 0x8D3F, 0x79FD, 0x4F1A, 0x70E9, 0x6C47, 0x8BB3, 0x8BF2,
+    0x7ED8, 0x6E83
+};
+
+static const uint32_t pinyin_hun_codepoints[] = {
+    0x68CD, 0x8364, 0x660F, 0x5A5A, 0x9B42, 0x6D51, 0x6DF7, 0x6606,
+    0x6346
+};
+
+static const uint32_t pinyin_huo_codepoints[] = {
+    0x626E, 0x5475, 0x548C, 0x5316, 0x8C41, 0x6D3B, 0x4F19, 0x706B,
+    0x83B7, 0x6216, 0x60D1, 0x970D, 0x8D27, 0x7978, 0x8D8A
+};
+
+static const uint32_t pinyin_ji_codepoints[] = {
+    0x75B5, 0x9769, 0x9694, 0x7ED9, 0x51FB, 0x573E, 0x57FA, 0x673A,
+    0x7578, 0x7A3D, 0x79EF, 0x7B95, 0x808C, 0x9965, 0x8FF9, 0x6FC0,
+    0x8BA5, 0x9E21, 0x59EC, 0x7EE9, 0x7F09, 0x5409, 0x6781, 0x68D8,
+    0x8F91, 0x7C4D, 0x96C6, 0x53CA, 0x6025, 0x75BE, 0x6C72, 0x5373,
+    0x5AC9, 0x7EA7, 0x6324, 0x51E0, 0x810A, 0x5DF1, 0x84DF, 0x6280,
+    0x5180, 0x5B63, 0x4F0E, 0x796D, 0x5242, 0x60B8, 0x6D4E, 0x5BC4,
+    0x5BC2, 0x8BA1, 0x8BB0, 0x65E2, 0x5FCC, 0x9645, 0x5993, 0x7EE7,
+    0x7EAA, 0x79F8, 0x6D01, 0x85C9, 0x5C45, 0x8721, 0x671F, 0x5176,
+    0x68CB, 0x5947, 0x9F50, 0x7CFB, 0x63D6, 0x501A
+};
+
+static const uint32_t pinyin_jia_codepoints[] = {
+    0x5609, 0x67B7, 0x5939, 0x4F73, 0x5BB6, 0x52A0, 0x835A, 0x988A,
+    0x8D3E, 0x7532, 0x94BE, 0x5047, 0x7A3C, 0x4EF7, 0x67B6, 0x9A7E,
+    0x5AC1, 0x5496, 0x63E9, 0x8304, 0x6687, 0x590F, 0x631F, 0x62BC
+};
+
+static const uint32_t pinyin_jian_codepoints[] = {
+    0x558A, 0x6B7C, 0x76D1, 0x575A, 0x5C16, 0x7B3A, 0x95F4, 0x714E,
+    0x517C, 0x80A9, 0x8270, 0x5978, 0x7F04, 0x8327, 0x68C0, 0x67EC,
+    0x78B1, 0x7877, 0x62E3, 0x6361, 0x7B80, 0x4FED, 0x526A, 0x51CF,
+    0x8350, 0x69DB, 0x9274, 0x8DF5, 0x8D31, 0x89C1, 0x952E, 0x7BAD,
+    0x4EF6, 0x5065, 0x8230, 0x5251, 0x996F, 0x6E10, 0x6E85, 0x6DA7,
+    0x5EFA, 0x6CAE, 0x524D, 0x6D45, 0x54B8
+};
+
+static const uint32_t pinyin_jiang_codepoints[] = {
+    0x8679, 0x50F5, 0x59DC, 0x5C06, 0x6D46, 0x6C5F, 0x7586, 0x848B,
+    0x6868, 0x5956, 0x8BB2, 0x5320, 0x9171, 0x964D, 0x5F3A
+};
+
+static const uint32_t pinyin_jiao_codepoints[] = {
+    0x6FC0, 0x8549, 0x6912, 0x7901, 0x7126, 0x80F6, 0x4EA4, 0x90CA,
+    0x6D47, 0x9A84, 0x5A07, 0x56BC, 0x6405, 0x94F0, 0x77EB, 0x4FA5,
+    0x811A, 0x72E1, 0x89D2, 0x997A, 0x7F34, 0x7EDE, 0x527F, 0x6559,
+    0x9175, 0x8F7F, 0x8F83, 0x53EB, 0x7A96, 0x89C9, 0x6821, 0x5996,
+    0x54AC
+};
+
+static const uint32_t pinyin_jie_codepoints[] = {
+    0x5DEE, 0x62C5, 0x6982, 0x4EA5, 0x573E, 0x7C4D, 0x5BB6, 0x5047,
+    0x4EF7, 0x63ED, 0x63A5, 0x7686, 0x79F8, 0x8857, 0x9636, 0x622A,
+    0x52AB, 0x8282, 0x6854, 0x6770, 0x6377, 0x776B, 0x7AED, 0x6D01,
+    0x7ED3, 0x89E3, 0x59D0, 0x6212, 0x85C9, 0x82A5, 0x754C, 0x501F,
+    0x4ECB, 0x75A5, 0x8BEB, 0x5C4A, 0x6977, 0x6E34, 0x5951, 0x62FE,
+    0x5979, 0x7956
+};
+
+static const uint32_t pinyin_jin_codepoints[] = {
+    0x5DFE, 0x7B4B, 0x65A4, 0x91D1, 0x4ECA, 0x6D25, 0x895F, 0x7D27,
+    0x9526, 0x4EC5, 0x8C28, 0x8FDB, 0x9773, 0x664B, 0x7981, 0x8FD1,
+    0x70EC, 0x6D78, 0x5C3D, 0x52B2, 0x808B, 0x541F, 0x6E5B
+};
+
+static const uint32_t pinyin_jing_codepoints[] = {
+    0x52B2, 0x8346, 0x5162, 0x830E, 0x775B, 0x6676, 0x9CB8, 0x4EAC,
+    0x60CA, 0x7CBE, 0x7CB3, 0x7ECF, 0x4E95, 0x8B66, 0x666F, 0x9888,
+    0x9759, 0x5883, 0x656C, 0x955C, 0x5F84, 0x75C9, 0x9756, 0x7ADF,
+    0x7ADE, 0x51C0, 0x9752, 0x6C0F, 0x9192
+};
+
+static const uint32_t pinyin_jiong_codepoints[] = {
+    0x70AF, 0x7A98, 0x5777
+};
+
+static const uint32_t pinyin_jiu_codepoints[] = {
+    0x6101, 0x63EA, 0x7A76, 0x7EA0, 0x7396, 0x97ED, 0x4E45, 0x7078,
+    0x4E5D, 0x9152, 0x53A9, 0x6551, 0x65E7, 0x81FC, 0x8205, 0x548E,
+    0x5C31, 0x759A
+};
+
+static const uint32_t pinyin_ju_codepoints[] = {
+    0x8F66, 0x4EC7, 0x544A, 0x62F1, 0x67DC, 0x6854, 0x59D0, 0x97A0,
+    0x62D8, 0x72D9, 0x75BD, 0x5C45, 0x9A79, 0x83CA, 0x5C40, 0x5480,
+    0x77E9, 0x4E3E, 0x6CAE, 0x805A, 0x62D2, 0x636E, 0x5DE8, 0x5177,
+    0x8DDD, 0x8E1E, 0x952F, 0x4FF1, 0x53E5, 0x60E7, 0x70AC, 0x5267,
+    0x4E14, 0x86C6, 0x5C48, 0x6E20, 0x5A36, 0x79DF, 0x8DB3
+};
+
+static const uint32_t pinyin_juan_codepoints[] = {
+    0x6350, 0x9E43, 0x5A1F, 0x5026, 0x7737, 0x5377, 0x7EE2, 0x5708,
+    0x854A, 0x8EAB, 0x7729, 0x7504
+};
+
+static const uint32_t pinyin_jue_codepoints[] = {
+    0x56BC, 0x811A, 0x89D2, 0x6485, 0x652B, 0x6289, 0x6398, 0x5014,
+    0x7235, 0x89C9, 0x51B3, 0x8BC0, 0x7EDD, 0x72C2, 0x5C48, 0x86D9,
+    0x7A74, 0x4E59
+};
+
+static const uint32_t pinyin_jun_codepoints[] = {
+    0x9F9F, 0x5377, 0x5747, 0x83CC, 0x94A7, 0x519B, 0x541B, 0x5CFB,
+    0x4FCA, 0x7AE3, 0x6D5A, 0x90E1, 0x9A8F, 0x65EC, 0x5300
+};
+
+static const uint32_t pinyin_ka_codepoints[] = {
+    0x5580, 0x5496, 0x5361, 0x54AF
+};
+
+static const uint32_t pinyin_kai_codepoints[] = {
+    0x559D, 0x6838, 0x5F00, 0x63E9, 0x6977, 0x51EF, 0x6168, 0x6E34,
+    0x5C82
+};
+
+static const uint32_t pinyin_kan_codepoints[] = {
+    0x558A, 0x69DB, 0x520A, 0x582A, 0x52D8, 0x574E, 0x780D, 0x770B,
+    0x5D4C
+};
+
+static const uint32_t pinyin_kang_codepoints[] = {
+    0x594B, 0x676D, 0x8352, 0x5EB7, 0x6177, 0x7CE0, 0x625B, 0x6297,
+    0x4EA2, 0x7095, 0x5751
+};
+
+static const uint32_t pinyin_kao_codepoints[] = {
+    0x641E, 0x8003, 0x62F7, 0x70E4, 0x9760
+};
+
+static const uint32_t pinyin_ke_codepoints[] = {
+    0x5475, 0x5580, 0x5777, 0x82DB, 0x67EF, 0x68F5, 0x78D5, 0x9897,
+    0x79D1, 0x58F3, 0x54B3, 0x53EF, 0x6E34, 0x514B, 0x523B, 0x5BA2,
+    0x8BFE
+};
+
+static const uint32_t pinyin_kei_codepoints[] = {
+    0x523B
+};
+
+static const uint32_t pinyin_ken_codepoints[] = {
+    0x72E0, 0x80AF, 0x5543, 0x57A6, 0x6073
+};
+
+static const uint32_t pinyin_keng_codepoints[] = {
+    0x5751, 0x542D
+};
+
+static const uint32_t pinyin_kong_codepoints[] = {
+    0x7A7A, 0x6050, 0x5B54, 0x63A7, 0x8154
+};
+
+static const uint32_t pinyin_kou_codepoints[] = {
+    0x62A0, 0x53E3, 0x6263, 0x5BC7, 0x630E
+};
+
+static const uint32_t pinyin_ku_codepoints[] = {
+    0x53E4, 0x6398, 0x67AF, 0x54ED, 0x7A9F, 0x82E6, 0x9177, 0x5E93,
+    0x88E4, 0x630E, 0x8DE8, 0x5723
+};
+
+static const uint32_t pinyin_kua_codepoints[] = {
+    0x5938, 0x57AE, 0x630E, 0x8DE8, 0x80EF
+};
+
+static const uint32_t pinyin_kuai_codepoints[] = {
+    0x4F1A, 0x5757, 0x7B77, 0x4FA9, 0x5FEB, 0x9B41, 0x5080
+};
+
+static const uint32_t pinyin_kuan_codepoints[] = {
+    0x68F5, 0x5BBD, 0x6B3E, 0x5B8C
+};
+
+static const uint32_t pinyin_kuang_codepoints[] = {
+    0x5448, 0x901B, 0x78FA, 0x5321, 0x7B50, 0x72C2, 0x6846, 0x77FF,
+    0x7736, 0x65F7, 0x51B5, 0x6789, 0x5144
+};
+
+static const uint32_t pinyin_kui_codepoints[] = {
+    0x8E29, 0x4E8F, 0x76D4, 0x5CBF, 0x7AA5, 0x8475, 0x594E, 0x9B41,
+    0x5080, 0x9988, 0x6127, 0x6E83, 0x7F3A
+};
+
+static const uint32_t pinyin_kun_codepoints[] = {
+    0x6DF7, 0x5764, 0x6606, 0x6346, 0x56F0, 0x5375
+};
+
+static const uint32_t pinyin_kuo_codepoints[] = {
+    0x62EC, 0x6269, 0x5ED3, 0x9614, 0x9002
+};
+
+static const uint32_t pinyin_la_codepoints[] = {
+    0x5783, 0x62C9, 0x5587, 0x8721, 0x814A, 0x8FA3, 0x5566, 0x84DD,
+    0x843D
+};
+
+static const uint32_t pinyin_lai_codepoints[] = {
+    0x83B1, 0x6765, 0x8D56
+};
+
+static const uint32_t pinyin_lan_codepoints[] = {
+    0x90F4, 0x84DD, 0x5A6A, 0x680F, 0x62E6, 0x7BEE, 0x9611, 0x5170,
+    0x6F9C, 0x8C30, 0x63FD, 0x89C8, 0x61D2, 0x7F06, 0x70C2, 0x6EE5
+};
+
+static const uint32_t pinyin_lang_codepoints[] = {
+    0x7FB9, 0x7405, 0x6994, 0x72FC, 0x5ECA, 0x90CE, 0x6717, 0x6D6A
+};
+
+static const uint32_t pinyin_lao_codepoints[] = {
+    0x635E, 0x52B3, 0x7262, 0x8001, 0x4F6C, 0x59E5, 0x916A, 0x70D9,
+    0x6D9D, 0x64A9, 0x50DA, 0x6F66, 0x843D, 0x7EDC
+};
+
+static const uint32_t pinyin_le_codepoints[] = {
+    0x52D2, 0x4E50, 0x808B, 0x4E86
+};
+
+static const uint32_t pinyin_lei_codepoints[] = {
+    0x52D2, 0x96F7, 0x956D, 0x857E, 0x78CA, 0x7D2F, 0x5121, 0x5792,
+    0x64C2, 0x808B, 0x7C7B, 0x6CEA
+};
+
+static const uint32_t pinyin_leng_codepoints[] = {
+    0x68F1, 0x695E, 0x51B7
+};
+
+static const uint32_t pinyin_li_codepoints[] = {
+    0x5398, 0x68A8, 0x7281, 0x9ECE, 0x7BF1, 0x72F8, 0x79BB, 0x6F13,
+    0x7406, 0x674E, 0x91CC, 0x9CA4, 0x793C, 0x8389, 0x8354, 0x540F,
+    0x6817, 0x4E3D, 0x5389, 0x52B1, 0x783E, 0x5386, 0x5229, 0x5088,
+    0x4F8B, 0x4FD0, 0x75E2, 0x7ACB, 0x7C92, 0x6CA5, 0x96B6, 0x529B,
+    0x7483, 0x54E9, 0x5217, 0x6CE3, 0x4F4D
+};
+
+static const uint32_t pinyin_lia_codepoints[] = {
+    0x4FE9
+};
+
+static const uint32_t pinyin_lian_codepoints[] = {
+    0x8054, 0x83B2, 0x8FDE, 0x9570, 0x5EC9, 0x601C, 0x6D9F, 0x5E18,
+    0x655B, 0x8138, 0x94FE, 0x604B, 0x70BC, 0x7EC3, 0x96F6, 0x4EE4
+};
+
+static const uint32_t pinyin_liang_codepoints[] = {
+    0x60CA, 0x4FE9, 0x7CAE, 0x51C9, 0x6881, 0x7CB1, 0x826F, 0x4E24,
+    0x8F86, 0x91CF, 0x667E, 0x4EAE, 0x8C05
+};
+
+static const uint32_t pinyin_liao_codepoints[] = {
+    0x4F6C, 0x64A9, 0x804A, 0x50DA, 0x7597, 0x71CE, 0x5BE5, 0x8FBD,
+    0x6F66, 0x4E86, 0x6482, 0x9563, 0x5ED6, 0x6599
+};
+
+static const uint32_t pinyin_lie_codepoints[] = {
+    0x818A, 0x7D2F, 0x6817, 0x4F8B, 0x5217, 0x88C2, 0x70C8, 0x52A3,
+    0x730E
+};
+
+static const uint32_t pinyin_lin_codepoints[] = {
+    0x7433, 0x6797, 0x78F7, 0x9716, 0x4E34, 0x90BB, 0x9CDE, 0x6DCB,
+    0x51DB, 0x8D41, 0x541D, 0x62CE, 0x4EFB
+};
+
+static const uint32_t pinyin_ling_codepoints[] = {
+    0x68F1, 0x51B7, 0x601C, 0x78F7, 0x62CE, 0x73B2, 0x83F1, 0x96F6,
+    0x9F84, 0x94C3, 0x4F36, 0x7F9A, 0x51CC, 0x7075, 0x9675, 0x5CAD,
+    0x9886, 0x53E6, 0x4EE4
+};
+
+static const uint32_t pinyin_liu_codepoints[] = {
+    0x6CF5, 0x804A, 0x6E9C, 0x7409, 0x69B4, 0x786B, 0x998F, 0x7559,
+    0x5218, 0x7624, 0x6D41, 0x67F3, 0x516D, 0x788C, 0x9646, 0x6E38
+};
+
+static const uint32_t pinyin_lo_codepoints[] = {
+    0x54AF
+};
+
+static const uint32_t pinyin_long_codepoints[] = {
+    0x9F99, 0x804B, 0x5499, 0x7B3C, 0x7ABF, 0x9686, 0x5784, 0x62E2,
+    0x9647, 0x5F04
+};
+
+static const uint32_t pinyin_lou_codepoints[] = {
+    0x7262, 0x697C, 0x5A04, 0x6402, 0x7BD3, 0x6F0F, 0x964B, 0x9732
+};
+
+static const uint32_t pinyin_lu_codepoints[] = {
+    0x8C37, 0x89D2, 0x916A, 0x516D, 0x82A6, 0x5362, 0x9885, 0x5E90,
+    0x7089, 0x63B3, 0x5364, 0x864F, 0x9C81, 0x9E93, 0x788C, 0x9732,
+    0x8DEF, 0x8D42, 0x9E7F, 0x6F5E, 0x7984, 0x5F55, 0x9646, 0x622E,
+    0x7EFF
+};
+
+static const uint32_t pinyin_luan_codepoints[] = {
+    0x5CE6, 0x631B, 0x5B6A, 0x6EE6, 0x5375, 0x4E71
+};
+
+static const uint32_t pinyin_lun_codepoints[] = {
+    0x62A1, 0x8F6E, 0x4F26, 0x4ED1, 0x6CA6, 0x7EB6, 0x8BBA
+};
+
+static const uint32_t pinyin_luo_codepoints[] = {
+    0x683C, 0x679C, 0x54AF, 0x916A, 0x70D9, 0x788C, 0x8DEF, 0x841D,
+    0x87BA, 0x7F57, 0x903B, 0x9523, 0x7BA9, 0x9AA1, 0x88F8, 0x843D,
+    0x6D1B, 0x9A86, 0x7EDC
+};
+
+static const uint32_t pinyin_lv_codepoints[] = {
+    0x7D2F, 0x9E7F, 0x9A74, 0x5415, 0x94DD, 0x4FA3, 0x65C5, 0x5C65,
+    0x5C61, 0x7F15, 0x8651, 0x6C2F, 0x5F8B, 0x7387, 0x6EE4, 0x7EFF
+};
+
+static const uint32_t pinyin_lve_codepoints[] = {
+    0x7387, 0x63A0, 0x7565
+};
+
+static const uint32_t pinyin_ma_codepoints[] = {
+    0x8C89, 0x5988, 0x9EBB, 0x739B, 0x7801, 0x8682, 0x9A6C, 0x9A82,
+    0x561B, 0x5417, 0x4E48, 0x9761, 0x6469, 0x62B9
+};
+
+static const uint32_t pinyin_mai_codepoints[] = {
+    0x54E9, 0x57CB, 0x4E70, 0x9EA6, 0x5356, 0x8FC8, 0x8109, 0x6D3E
+};
+
+static const uint32_t pinyin_man_codepoints[] = {
+    0x57CB, 0x7792, 0x9992, 0x86EE, 0x6EE1, 0x8513, 0x66FC, 0x6162,
+    0x6F2B, 0x8C29, 0x5E55
+};
+
+static const uint32_t pinyin_mang_codepoints[] = {
+    0x8292, 0x832B, 0x76F2, 0x6C13, 0x5FD9, 0x83BD
+};
+
+static const uint32_t pinyin_mao_codepoints[] = {
+    0x8017, 0x732B, 0x8305, 0x951A, 0x6BDB, 0x77DB, 0x94C6, 0x536F,
+    0x8302, 0x5192, 0x5E3D, 0x8C8C, 0x8D38, 0x63CF, 0x725F
+};
+
+static const uint32_t pinyin_me_codepoints[] = {
+    0x4E48, 0x6CA1, 0x672B
+};
+
+static const uint32_t pinyin_mei_codepoints[] = {
+    0x73AB, 0x679A, 0x6885, 0x9176, 0x9709, 0x7164, 0x6CA1, 0x7709,
+    0x5A92, 0x9541, 0x6BCF, 0x7F8E, 0x6627, 0x5BD0, 0x59B9, 0x5A9A,
+    0x7CDC, 0x8C1C, 0x58A8, 0x67D0, 0x5473
+};
+
+static const uint32_t pinyin_men_codepoints[] = {
+    0x95E8, 0x95F7, 0x4EEC
+};
+
+static const uint32_t pinyin_meng_codepoints[] = {
+    0x6C13, 0x840C, 0x8499, 0x6AAC, 0x76DF, 0x9530, 0x731B, 0x68A6,
+    0x5B5F, 0x660E
+};
+
+static const uint32_t pinyin_mi_codepoints[] = {
+    0x8F9F, 0x772F, 0x919A, 0x9761, 0x7CDC, 0x8FF7, 0x8C1C, 0x5F25,
+    0x7C73, 0x79D8, 0x89C5, 0x6CCC, 0x871C, 0x5BC6, 0x5E42, 0x6469
+};
+
+static const uint32_t pinyin_mian_codepoints[] = {
+    0x68C9, 0x7720, 0x7EF5, 0x5195, 0x514D, 0x52C9, 0x5A29, 0x7F05,
+    0x9762
+};
+
+static const uint32_t pinyin_miao_codepoints[] = {
+    0x5435, 0x732B, 0x82D7, 0x63CF, 0x7784, 0x85D0, 0x79D2, 0x6E3A,
+    0x5E99, 0x5999
+};
+
+static const uint32_t pinyin_mie_codepoints[] = {
+    0x8511, 0x706D
+};
+
+static const uint32_t pinyin_min_codepoints[] = {
+    0x7720, 0x6C11, 0x62BF, 0x76BF, 0x654F, 0x60AF, 0x95FD
+};
+
+static const uint32_t pinyin_ming_codepoints[] = {
+    0x840C, 0x76DF, 0x76BF, 0x660E, 0x879F, 0x9E23, 0x94ED, 0x540D,
+    0x547D
+};
+
+static const uint32_t pinyin_miu_codepoints[] = {
+    0x8C2C
+};
+
+static const uint32_t pinyin_mo_codepoints[] = {
+    0x767E, 0x4F70, 0x4F2F, 0x8C89, 0x563F, 0x8109, 0x5192, 0x8C8C,
+    0x4E48, 0x6CA1, 0x6627, 0x85D0, 0x6478, 0x6479, 0x8611, 0x6A21,
+    0x819C, 0x78E8, 0x6469, 0x9B54, 0x62B9, 0x672B, 0x83AB, 0x58A8,
+    0x9ED8, 0x6CAB, 0x6F20, 0x5BDE, 0x964C, 0x5E15, 0x889C, 0x4E07,
+    0x65E0, 0x52FF
+};
+
+static const uint32_t pinyin_mou_codepoints[] = {
+    0x4EF6, 0x8C0B, 0x725F, 0x67D0, 0x6BCB
+};
+
+static const uint32_t pinyin_mu_codepoints[] = {
+    0x563F, 0x59E5, 0x6A21, 0x83AB, 0x725F, 0x62C7, 0x7261, 0x4EA9,
+    0x59C6, 0x6BCD, 0x5893, 0x66AE, 0x5E55, 0x52DF, 0x6155, 0x6728,
+    0x76EE, 0x7766, 0x7267, 0x7A46
+};
+
+static const uint32_t pinyin_na_codepoints[] = {
+    0x62FF, 0x54EA, 0x5450, 0x94A0, 0x90A3, 0x5A1C, 0x7EB3, 0x5357,
+    0x5185, 0x7D6E
+};
+
+static const uint32_t pinyin_nai_codepoints[] = {
+    0x54EA, 0x90A3, 0x6C16, 0x4E43, 0x5976, 0x8010, 0x5948, 0x80FD
+};
+
+static const uint32_t pinyin_nan_codepoints[] = {
+    0x5357, 0x7537, 0x96BE, 0x5189
+};
+
+static const uint32_t pinyin_nang_codepoints[] = {
+    0x56CA
+};
+
+static const uint32_t pinyin_nao_codepoints[] = {
+    0x6320, 0x8111, 0x607C, 0x95F9, 0x6DD6
+};
+
+static const uint32_t pinyin_ne_codepoints[] = {
+    0x54EA, 0x5450, 0x90A3, 0x5462
+};
+
+static const uint32_t pinyin_nei_codepoints[] = {
+    0x54EA, 0x90A3, 0x9981, 0x5185
+};
+
+static const uint32_t pinyin_nen_codepoints[] = {
+    0x5AE9
+};
+
+static const uint32_t pinyin_neng_codepoints[] = {
+    0x800C, 0x8010, 0x80FD
+};
+
+static const uint32_t pinyin_ni_codepoints[] = {
+    0x5462, 0x59AE, 0x9713, 0x502A, 0x6CE5, 0x5C3C, 0x62DF, 0x4F60,
+    0x533F, 0x817B, 0x9006, 0x6EBA
+};
+
+static const uint32_t pinyin_nian_codepoints[] = {
+    0x8D81, 0x852B, 0x62C8, 0x5E74, 0x78BE, 0x64B5, 0x637B, 0x5FF5,
+    0x7C98, 0x8F97
+};
+
+static const uint32_t pinyin_niang_codepoints[] = {
+    0x5A18, 0x917F
+};
+
+static const uint32_t pinyin_niao_codepoints[] = {
+    0x6EBA, 0x9E1F, 0x5C3F
+};
+
+static const uint32_t pinyin_nie_codepoints[] = {
+    0x54EA, 0x502A, 0x6CE5, 0x637B, 0x634F, 0x8042, 0x5B7D, 0x556E,
+    0x954A, 0x954D, 0x6D85, 0x5E78
+};
+
+static const uint32_t pinyin_nin_codepoints[] = {
+    0x60A8
+};
+
+static const uint32_t pinyin_ning_codepoints[] = {
+    0x51B0, 0x6CE5, 0x5E74, 0x67E0, 0x72DE, 0x51DD, 0x5B81, 0x62E7,
+    0x6CDE, 0x6518, 0x7591
+};
+
+static const uint32_t pinyin_niu_codepoints[] = {
+    0x725B, 0x626D, 0x94AE, 0x7EBD
+};
+
+static const uint32_t pinyin_nong_codepoints[] = {
+    0x8113, 0x6D53, 0x519C, 0x5F04
+};
+
+static const uint32_t pinyin_nu_codepoints[] = {
+    0x4EC5, 0x5974, 0x52AA, 0x6012, 0x8925
+};
+
+static const uint32_t pinyin_nuan_codepoints[] = {
+    0x6696
+};
+
+static const uint32_t pinyin_nuo_codepoints[] = {
+    0x6389, 0x54EA, 0x5450, 0x90A3, 0x5A1C, 0x632A, 0x61E6, 0x7CEF,
+    0x8BFA, 0x9700
+};
+
+static const uint32_t pinyin_nv_codepoints[] = {
+    0x5973, 0x7D6E
+};
+
+static const uint32_t pinyin_nve_codepoints[] = {
+    0x8650, 0x759F
+};
+
+static const uint32_t pinyin_o_codepoints[] = {
+    0x54E6
+};
+
+static const uint32_t pinyin_ou_codepoints[] = {
+    0x6B27, 0x9E25, 0x6BB4, 0x85D5, 0x5455, 0x5076, 0x6CA4, 0x533A,
+    0x63E1, 0x9047
+};
+
+static const uint32_t pinyin_pa_codepoints[] = {
+    0x82AD, 0x6252, 0x53ED, 0x5427, 0x628A, 0x8019, 0x556A, 0x8DB4,
+    0x722C, 0x5E15, 0x6015, 0x7436, 0x6D3E
+};
+
+static const uint32_t pinyin_pai_codepoints[] = {
+    0x5561, 0x62CD, 0x6392, 0x724C, 0x5F98, 0x6E43, 0x6D3E, 0x813E,
+    0x8FEB
+};
+
+static const uint32_t pinyin_pan_codepoints[] = {
+    0x6273, 0x822C, 0x62CC, 0x4F34, 0x534A, 0x535E, 0x756A, 0x7E41,
+    0x6500, 0x6F58, 0x76D8, 0x78D0, 0x76FC, 0x7554, 0x5224, 0x53DB,
+    0x80D6, 0x7247, 0x5F66
+};
+
+static const uint32_t pinyin_pang_codepoints[] = {
+    0x699C, 0x8180, 0x78C5, 0x508D, 0x65B9, 0x623F, 0x4EFF, 0x9022,
+    0x4E53, 0x5E9E, 0x65C1, 0x802A, 0x80D6, 0x5F6D
+};
+
+static const uint32_t pinyin_pao_codepoints[] = {
+    0x82DE, 0x80DE, 0x5305, 0x62B1, 0x629B, 0x5486, 0x5228, 0x70AE,
+    0x888D, 0x8DD1, 0x6CE1
+};
+
+static const uint32_t pinyin_pei_codepoints[] = {
+    0x500D, 0x5561, 0x80BA, 0x574F, 0x5478, 0x80DA, 0x57F9, 0x88F4,
+    0x8D54, 0x966A, 0x914D, 0x4F69, 0x6C9B
+};
+
+static const uint32_t pinyin_pen_codepoints[] = {
+    0x5429, 0x6C7E, 0x55B7, 0x76C6
+};
+
+static const uint32_t pinyin_peng_codepoints[] = {
+    0x699C, 0x508D, 0x9022, 0x4EA8, 0x65C1, 0x7830, 0x62A8, 0x70F9,
+    0x6F8E, 0x5F6D, 0x84EC, 0x68DA, 0x787C, 0x7BF7, 0x81A8, 0x670B,
+    0x9E4F, 0x6367, 0x78B0, 0x82F9, 0x5E84
+};
+
+static const uint32_t pinyin_pi_codepoints[] = {
+    0x868C, 0x5351, 0x88AB, 0x6BD4, 0x5E87, 0x8F9F, 0x756A, 0x5426,
+    0x62C2, 0x526F, 0x574F, 0x57F9, 0x576F, 0x7812, 0x9739, 0x6279,
+    0x62AB, 0x5288, 0x7435, 0x6BD7, 0x5564, 0x813E, 0x75B2, 0x76AE,
+    0x5339, 0x75DE, 0x50FB, 0x5C41, 0x8B6C, 0x6251
+};
+
+static const uint32_t pinyin_pian_codepoints[] = {
+    0x6241, 0x4FBF, 0x8FA8, 0x7BC7, 0x504F, 0x7247, 0x9A97, 0x5E73
+};
+
+static const uint32_t pinyin_piao_codepoints[] = {
+    0x8198, 0x98D8, 0x6F02, 0x74E2, 0x7968, 0x6734
+};
+
+static const uint32_t pinyin_pie_codepoints[] = {
+    0x853D, 0x6487, 0x77A5
+};
+
+static const uint32_t pinyin_pin_codepoints[] = {
+    0x6CF5, 0x62FC, 0x9891, 0x8D2B, 0x54C1, 0x8058
+};
+
+static const uint32_t pinyin_ping_codepoints[] = {
+    0x79E4, 0x51AF, 0x7830, 0x8058, 0x4E52, 0x576A, 0x82F9, 0x840D,
+    0x5E73, 0x51ED, 0x74F6, 0x8BC4, 0x5C4F
+};
+
+static const uint32_t pinyin_po_codepoints[] = {
+    0x9738, 0x818A, 0x6CCA, 0x756A, 0x7E41, 0x5761, 0x6CFC, 0x9887,
+    0x5A46, 0x7834, 0x9B44, 0x8FEB, 0x7C95, 0x5256, 0x6734
+};
+
+static const uint32_t pinyin_pou_codepoints[] = {
+    0x62B1, 0x90E8, 0x6DAA, 0x57F9, 0x5256
+};
+
+static const uint32_t pinyin_pu_codepoints[] = {
+    0x5265, 0x5821, 0x66B4, 0x535C, 0x6276, 0x752B, 0x812F, 0x6251,
+    0x94FA, 0x4EC6, 0x8386, 0x8461, 0x83E9, 0x84B2, 0x57D4, 0x6734,
+    0x5703, 0x666E, 0x6D66, 0x8C31, 0x66DD, 0x7011
+};
+
+static const uint32_t pinyin_qi_codepoints[] = {
+    0x752D, 0x5403, 0x523A, 0x62B5, 0x9017, 0x7578, 0x7A3D, 0x7F09,
+    0x5DF1, 0x6280, 0x4F0E, 0x63ED, 0x671F, 0x6B3A, 0x6816, 0x621A,
+    0x59BB, 0x4E03, 0x51C4, 0x6F06, 0x67D2, 0x6C8F, 0x5176, 0x68CB,
+    0x5947, 0x6B67, 0x7566, 0x5D0E, 0x8110, 0x9F50, 0x65D7, 0x7948,
+    0x7941, 0x9A91, 0x8D77, 0x5C82, 0x4E5E, 0x4F01, 0x542F, 0x5951,
+    0x780C, 0x5668, 0x6C14, 0x8FC4, 0x5F03, 0x6C7D, 0x6CE3, 0x8BAB,
+    0x5207, 0x52E4, 0x793A, 0x5BBF, 0x6EAA, 0x679D, 0x652F, 0x5431
+};
+
+static const uint32_t pinyin_qia_codepoints[] = {
+    0x5361, 0x5BA2, 0x6390, 0x6070, 0x6D3D
+};
+
+static const uint32_t pinyin_qian_codepoints[] = {
+    0x67D1, 0x8D76, 0x7B4B, 0x7275, 0x6266, 0x948E, 0x94C5, 0x5343,
+    0x8FC1, 0x7B7E, 0x4EDF, 0x8C26, 0x4E7E, 0x9ED4, 0x94B1, 0x94B3,
+    0x524D, 0x6F5C, 0x9063, 0x6D45, 0x8C34, 0x5811, 0x5D4C, 0x6B20,
+    0x6B49, 0x7EA4, 0x5BE8
+};
+
+static const uint32_t pinyin_qiang_codepoints[] = {
+    0x5C06, 0x63A7, 0x67AA, 0x545B, 0x8154, 0x7F8C, 0x5899, 0x8537,
+    0x5F3A, 0x62A2
+};
+
+static const uint32_t pinyin_qiao_codepoints[] = {
+    0x6101, 0x641E, 0x8549, 0x7126, 0x58F3, 0x6A47, 0x9539, 0x6572,
+    0x6084, 0x6865, 0x77A7, 0x4E54, 0x4FA8, 0x5DE7, 0x9798, 0x64AC,
+    0x7FD8, 0x5CED, 0x4FCF, 0x7A8D, 0x96C0, 0x634E, 0x785D, 0x524A,
+    0x6821, 0x62DB
+};
+
+static const uint32_t pinyin_qie_codepoints[] = {
+    0x6377, 0x6F06, 0x6C8F, 0x5951, 0x780C, 0x5207, 0x8304, 0x4E14,
+    0x602F, 0x7A83
+};
+
+static const uint32_t pinyin_qin_codepoints[] = {
+    0x6D78, 0x94A6, 0x4FB5, 0x4EB2, 0x79E6, 0x7434, 0x52E4, 0x82B9,
+    0x64D2, 0x79BD, 0x5BDD, 0x6C81
+};
+
+static const uint32_t pinyin_qing_codepoints[] = {
+    0x7CBE, 0x4EB2, 0x9752, 0x8F7B, 0x6C22, 0x503E, 0x537F, 0x6E05,
+    0x64CE, 0x6674, 0x6C30, 0x60C5, 0x9877, 0x8BF7, 0x5E86, 0x58F0,
+    0x80DC
+};
+
+static const uint32_t pinyin_qiong_codepoints[] = {
+    0x97A0, 0x743C, 0x7A77
+};
+
+static const uint32_t pinyin_qiu_codepoints[] = {
+    0x4EC7, 0x9F9F, 0x79CB, 0x4E18, 0x90B1, 0x7403, 0x6C42, 0x56DA,
+    0x914B, 0x6CC5, 0x56E2
+};
+
+static const uint32_t pinyin_qu_codepoints[] = {
+    0x97A0, 0x5DE8, 0x53E5, 0x8721, 0x8D8B, 0x533A, 0x86C6, 0x66F2,
+    0x8EAF, 0x5C48, 0x9A71, 0x6E20, 0x53D6, 0x5A36, 0x9F8B, 0x8DA3,
+    0x53BB, 0x620C
+};
+
+static const uint32_t pinyin_quan_codepoints[] = {
+    0x4E32, 0x5377, 0x5708, 0x98A7, 0x6743, 0x919B, 0x6CC9, 0x5168,
+    0x75CA, 0x62F3, 0x72AC, 0x5238, 0x529D, 0x6813, 0x62F4
+};
+
+static const uint32_t pinyin_que_codepoints[] = {
+    0x730E, 0x5C48, 0x7F3A, 0x7094, 0x7638, 0x5374, 0x9E4A, 0x69B7,
+    0x786E, 0x96C0, 0x828D
+};
+
+static const uint32_t pinyin_qun_codepoints[] = {
+    0x8E72, 0x9041, 0x88D9, 0x7FA4
+};
+
+static const uint32_t pinyin_ran_codepoints[] = {
+    0x7136, 0x71C3, 0x5189, 0x67D3
+};
+
+static const uint32_t pinyin_rang_codepoints[] = {
+    0x74E4, 0x58E4, 0x6518, 0x56B7, 0x8BA9
+};
+
+static const uint32_t pinyin_rao_codepoints[] = {
+    0x9976, 0x6270, 0x7ED5
+};
+
+static const uint32_t pinyin_re_codepoints[] = {
+    0x60F9, 0x70ED, 0x82E5
+};
+
+static const uint32_t pinyin_ren_codepoints[] = {
+    0x513F, 0x58EC, 0x4EC1, 0x4EBA, 0x5FCD, 0x97E7, 0x4EFB, 0x8BA4,
+    0x5203, 0x598A, 0x7EAB
+};
+
+static const uint32_t pinyin_reng_codepoints[] = {
+    0x8033, 0x6254, 0x4ECD, 0x620E
+};
+
+static const uint32_t pinyin_ri_codepoints[] = {
+    0x65E5
+};
+
+static const uint32_t pinyin_rong_codepoints[] = {
+    0x9694, 0x620E, 0x8338, 0x84C9, 0x8363, 0x878D, 0x7194, 0x6EB6,
+    0x5BB9, 0x7ED2, 0x5197
+};
+
+static const uint32_t pinyin_rou_codepoints[] = {
+    0x63C9, 0x67D4, 0x8089
+};
+
+static const uint32_t pinyin_ru_codepoints[] = {
+    0x5973, 0x8089, 0x8339, 0x8815, 0x5112, 0x5B7A, 0x5982, 0x8FB1,
+    0x4E73, 0x6C5D, 0x5165, 0x8925, 0x9700, 0x6708
+};
+
+static const uint32_t pinyin_ruan_codepoints[] = {
+    0x8F6F, 0x962E, 0x9700
+};
+
+static const uint32_t pinyin_rui_codepoints[] = {
+    0x5151, 0x5185, 0x854A, 0x745E, 0x9510
+};
+
+static const uint32_t pinyin_run_codepoints[] = {
+    0x95F0, 0x6DA6
+};
+
+static const uint32_t pinyin_ruo_codepoints[] = {
+    0x6EBA, 0x60F9, 0x82E5, 0x5F31
+};
+
+static const uint32_t pinyin_sa_codepoints[] = {
+    0x8521, 0x6492, 0x6D12, 0x8428
+};
+
+static const uint32_t pinyin_sai_codepoints[] = {
+    0x816E, 0x9CC3, 0x585E, 0x8D5B, 0x601D
+};
+
+static const uint32_t pinyin_san_codepoints[] = {
+    0x4E09, 0x53C1, 0x4F1E, 0x6563
+};
+
+static const uint32_t pinyin_sang_codepoints[] = {
+    0x6851, 0x55D3, 0x4E27
+};
+
+static const uint32_t pinyin_sao_codepoints[] = {
+    0x6414, 0x9A9A, 0x626B, 0x5AC2, 0x68A2, 0x54E8, 0x71E5
+};
+
+static const uint32_t pinyin_se_codepoints[] = {
+    0x6CE3, 0x585E, 0x745F, 0x8272, 0x6DA9, 0x5BE8
+};
+
+static const uint32_t pinyin_sen_codepoints[] = {
+    0x6D12, 0x68EE
+};
+
+static const uint32_t pinyin_seng_codepoints[] = {
+    0x50E7
+};
+
+static const uint32_t pinyin_sha_codepoints[] = {
+    0x54C8, 0x63A5, 0x838E, 0x7802, 0x6740, 0x5239, 0x6C99, 0x7EB1,
+    0x50BB, 0x5565, 0x715E, 0x6749, 0x53A6, 0x564E
+};
+
+static const uint32_t pinyin_shai_codepoints[] = {
+    0x8272, 0x7B5B, 0x6652
+};
+
+static const uint32_t pinyin_shan_codepoints[] = {
+    0x63BA, 0x5355, 0x63B8, 0x9093, 0x73CA, 0x82EB, 0x6749, 0x5C71,
+    0x5220, 0x717D, 0x886B, 0x95EA, 0x9655, 0x64C5, 0x8D61, 0x81B3,
+    0x5584, 0x6C55, 0x6247, 0x7F2E, 0x6A80, 0x6805
+};
+
+static const uint32_t pinyin_shang_codepoints[] = {
+    0x5892, 0x4F24, 0x5546, 0x8D4F, 0x664C, 0x4E0A, 0x5C1A, 0x88F3,
+    0x6C64
+};
+
+static const uint32_t pinyin_shao_codepoints[] = {
+    0x9798, 0x68A2, 0x634E, 0x7A0D, 0x70E7, 0x828D, 0x52FA, 0x97F6,
+    0x5C11, 0x54E8, 0x90B5, 0x7ECD, 0x641C, 0x524A, 0x62DB, 0x53EC
+};
+
+static const uint32_t pinyin_she_codepoints[] = {
+    0x789F, 0x776B, 0x5962, 0x8D4A, 0x86C7, 0x820C, 0x820D, 0x8D66,
+    0x6444, 0x5C04, 0x6151, 0x6D89, 0x793E, 0x8BBE, 0x62FE, 0x90AA,
+    0x6298
+};
+
+static const uint32_t pinyin_shei_codepoints[] = {
+    0x8C01
+};
+
+static const uint32_t pinyin_shen_codepoints[] = {
+    0x53C2, 0x7837, 0x7533, 0x547B, 0x4F38, 0x8EAB, 0x6DF1, 0x5A20,
+    0x7EC5, 0x795E, 0x6C88, 0x5BA1, 0x5A76, 0x751A, 0x80BE, 0x614E,
+    0x6E17, 0x4EC0, 0x4FE1, 0x6E5B, 0x9707
+};
+
+static const uint32_t pinyin_sheng_codepoints[] = {
+    0x4E58, 0x7538, 0x58F0, 0x751F, 0x7525, 0x7272, 0x5347, 0x7EF3,
+    0x7701, 0x76DB, 0x5269, 0x80DC, 0x5723, 0x59D3
+};
+
+static const uint32_t pinyin_shi_codepoints[] = {
+    0x5319, 0x5824, 0x90DD, 0x8D6B, 0x820D, 0x5E08, 0x5931, 0x72EE,
+    0x65BD, 0x6E7F, 0x8BD7, 0x5C38, 0x8671, 0x5341, 0x77F3, 0x62FE,
+    0x65F6, 0x4EC0, 0x98DF, 0x8680, 0x5B9E, 0x8BC6, 0x53F2, 0x77E2,
+    0x4F7F, 0x5C4E, 0x9A76, 0x59CB, 0x5F0F, 0x793A, 0x58EB, 0x4E16,
+    0x67FF, 0x4E8B, 0x62ED, 0x8A93, 0x901D, 0x52BF, 0x662F, 0x55DC,
+    0x566C, 0x9002, 0x4ED5, 0x4F8D, 0x91CA, 0x9970, 0x6C0F, 0x5E02,
+    0x6043, 0x5BA4, 0x89C6, 0x8BD5, 0x65AF, 0x5BFA, 0x4F3C, 0x63D0,
+    0x5618, 0x6DB2, 0x80A2, 0x6C41, 0x6B96, 0x5CD9
+};
+
+static const uint32_t pinyin_shou_codepoints[] = {
+    0x6536, 0x624B, 0x9996, 0x5B88, 0x5BFF, 0x6388, 0x552E, 0x53D7,
+    0x7626, 0x517D, 0x719F
+};
+
+static const uint32_t pinyin_shu_codepoints[] = {
+    0x9664, 0x5A36, 0x552E, 0x852C, 0x67A2, 0x68B3, 0x6B8A, 0x6292,
+    0x8F93, 0x53D4, 0x8212, 0x6DD1, 0x758F, 0x4E66, 0x8D4E, 0x5B70,
+    0x719F, 0x85AF, 0x6691, 0x66D9, 0x7F72, 0x8700, 0x9ECD, 0x9F20,
+    0x5C5E, 0x672F, 0x8FF0, 0x6811, 0x675F, 0x620D, 0x7AD6, 0x5885,
+    0x5EB6, 0x6570, 0x6F31, 0x6055, 0x55FD, 0x900F, 0x91CE, 0x4FDE,
+    0x8C6B, 0x6731
+};
+
+static const uint32_t pinyin_shua_codepoints[] = {
+    0x5237, 0x800D, 0x5506
+};
+
+static const uint32_t pinyin_shuai_codepoints[] = {
+    0x7387, 0x6454, 0x8870, 0x7529, 0x5E05
+};
+
+static const uint32_t pinyin_shuan_codepoints[] = {
+    0x6C55, 0x6813, 0x62F4
+};
+
+static const uint32_t pinyin_shuang_codepoints[] = {
+    0x971C, 0x53CC, 0x723D
+};
+
+static const uint32_t pinyin_shui_codepoints[] = {
+    0x8C01, 0x6C34, 0x7761, 0x7A0E, 0x8BF4
+};
+
+static const uint32_t pinyin_shun_codepoints[] = {
+    0x76FE, 0x4FCA, 0x542E, 0x77AC, 0x987A, 0x821C, 0x5DE1
+};
+
+static const uint32_t pinyin_shuo_codepoints[] = {
+    0x52FA, 0x6570, 0x8BF4, 0x7855, 0x6714, 0x70C1, 0x55FD, 0x6EAF
+};
+
+static const uint32_t pinyin_si_codepoints[] = {
+    0x5395, 0x98DF, 0x65AF, 0x6495, 0x5636, 0x601D, 0x79C1, 0x53F8,
+    0x4E1D, 0x6B7B, 0x8086, 0x5BFA, 0x55E3, 0x56DB, 0x4F3A, 0x4F3C,
+    0x9972, 0x5DF3, 0x53F0, 0x6790, 0x5DF2, 0x4EE5, 0x8084
+};
+
+static const uint32_t pinyin_song_codepoints[] = {
+    0x677E, 0x8038, 0x6002, 0x9882, 0x9001, 0x5B8B, 0x8BBC, 0x8BF5
+};
+
+static const uint32_t pinyin_sou_codepoints[] = {
+    0x641C, 0x8258, 0x64DE, 0x55FD, 0x65CF
+};
+
+static const uint32_t pinyin_su_codepoints[] = {
+    0x642C, 0x82CF, 0x9165, 0x4FD7, 0x7D20, 0x901F, 0x7C9F, 0x50F3,
+    0x5851, 0x6EAF, 0x5BBF, 0x8BC9, 0x8083, 0x7F29
+};
+
+static const uint32_t pinyin_suan_codepoints[] = {
+    0x9178, 0x849C, 0x7B97, 0x64B0
+};
+
+static const uint32_t pinyin_sui_codepoints[] = {
+    0x7CB9, 0x5C3F, 0x838E, 0x867D, 0x968B, 0x968F, 0x7EE5, 0x9AD3,
+    0x788E, 0x5C81, 0x7A57, 0x9042, 0x96A7, 0x795F, 0x84D1
+};
+
+static const uint32_t pinyin_sun_codepoints[] = {
+    0x9910, 0x5B59, 0x635F, 0x7B0B
+};
+
+static const uint32_t pinyin_suo_codepoints[] = {
+    0x6284, 0x970D, 0x838E, 0x6C99, 0x8870, 0x84D1, 0x68AD, 0x5506,
+    0x7F29, 0x7410, 0x7D22, 0x9501, 0x6240, 0x4E9B
+};
+
+static const uint32_t pinyin_ta_codepoints[] = {
+    0x642D, 0x8FBE, 0x54C8, 0x584C, 0x4ED6, 0x5B83, 0x5979, 0x5854,
+    0x736D, 0x631E, 0x8E4B, 0x8E0F, 0x592A, 0x62D3
+};
+
+static const uint32_t pinyin_tai_codepoints[] = {
+    0x5927, 0x80FD, 0x80CE, 0x82D4, 0x62AC, 0x53F0, 0x6CF0, 0x915E,
+    0x592A, 0x6001, 0x6C70
+};
+
+static const uint32_t pinyin_tan_codepoints[] = {
+    0x80C6, 0x4F46, 0x6DE1, 0x5F39, 0x6C88, 0x574D, 0x644A, 0x8D2A,
+    0x762B, 0x6EE9, 0x575B, 0x6A80, 0x75F0, 0x6F6D, 0x8C2D, 0x8C08,
+    0x5766, 0x6BEF, 0x8892, 0x78B3, 0x63A2, 0x53F9, 0x70AD, 0x8214,
+    0x708E, 0x6E5B
+};
+
+static const uint32_t pinyin_tang_codepoints[] = {
+    0x6C64, 0x5858, 0x642A, 0x5802, 0x68E0, 0x819B, 0x5510, 0x7CD6,
+    0x5018, 0x8EBA, 0x6DCC, 0x8D9F, 0x70EB
+};
+
+static const uint32_t pinyin_tao_codepoints[] = {
+    0x638F, 0x6D9B, 0x6ED4, 0x7EE6, 0x8404, 0x6843, 0x9003, 0x6DD8,
+    0x9676, 0x8BA8, 0x5957, 0x6311, 0x8DF3, 0x59DA
+};
+
+static const uint32_t pinyin_te_codepoints[] = {
+    0x533F, 0x5F0F, 0x7279
+};
+
+static const uint32_t pinyin_teng_codepoints[] = {
+    0x85E4, 0x817E, 0x75BC, 0x8A8A
+};
+
+static const uint32_t pinyin_ti_codepoints[] = {
+    0x8FBE, 0x5824, 0x72C4, 0x5F1F, 0x662F, 0x8086, 0x68AF, 0x5254,
+    0x8E22, 0x9511, 0x63D0, 0x9898, 0x8E44, 0x557C, 0x4F53, 0x66FF,
+    0x568F, 0x60D5, 0x6D95, 0x5243, 0x5C49, 0x6298
+};
+
+static const uint32_t pinyin_tian_codepoints[] = {
+    0x8695, 0x6EC7, 0x5178, 0x4F43, 0x7538, 0x82EB, 0x5929, 0x6DFB,
+    0x586B, 0x7530, 0x751C, 0x606C, 0x8214, 0x8146, 0x541E, 0x6CBE
+};
+
+static const uint32_t pinyin_tiao_codepoints[] = {
+    0x8D85, 0x7A20, 0x8C03, 0x6843, 0x6311, 0x6761, 0x8FE2, 0x773A,
+    0x8DF3, 0x59DA
+};
+
+static const uint32_t pinyin_tie_codepoints[] = {
+    0x8776, 0x8D34, 0x94C1, 0x5E16, 0x5360
+};
+
+static const uint32_t pinyin_ting_codepoints[] = {
+    0x5960, 0x5385, 0x542C, 0x70C3, 0x6C40, 0x5EF7, 0x505C, 0x4EAD,
+    0x5EAD, 0x633A, 0x8247
+};
+
+static const uint32_t pinyin_tong_codepoints[] = {
+    0x4F97, 0x606B, 0x6D1E, 0x901A, 0x6850, 0x916E, 0x77B3, 0x540C,
+    0x94DC, 0x5F64, 0x7AE5, 0x6876, 0x6345, 0x7B52, 0x7EDF, 0x75DB,
+    0x607F, 0x91CD
+};
+
+static const uint32_t pinyin_tou_codepoints[] = {
+    0x9017, 0x5077, 0x6295, 0x5934, 0x900F, 0x6109
+};
+
+static const uint32_t pinyin_tu_codepoints[] = {
+    0x8DCC, 0x675C, 0x51F8, 0x79C3, 0x7A81, 0x56FE, 0x5F92, 0x9014,
+    0x6D82, 0x5C60, 0x571F, 0x5410, 0x5154, 0x4F59
+};
+
+static const uint32_t pinyin_tuan_codepoints[] = {
+    0x63E3, 0x6566, 0x75EA, 0x7A0E, 0x6E4D, 0x56E2
+};
+
+static const uint32_t pinyin_tui_codepoints[] = {
+    0x5F1F, 0x7A0E, 0x63A8, 0x9893, 0x817F, 0x8715, 0x892A, 0x9000,
+    0x8131, 0x8FFD
+};
+
+static const uint32_t pinyin_tun_codepoints[] = {
+    0x5428, 0x6566, 0x56E4, 0x892A, 0x541E, 0x5C6F, 0x81C0, 0x5434,
+    0x9010
+};
+
+static const uint32_t pinyin_tuo_codepoints[] = {
+    0x6C60, 0x60F0, 0x9B44, 0x86C7, 0x7A0E, 0x968B, 0x4ED6, 0x5B83,
+    0x62D6, 0x6258, 0x8131, 0x9E35, 0x9640, 0x9A6E, 0x9A7C, 0x692D,
+    0x59A5, 0x62D3, 0x553E
+};
+
+static const uint32_t pinyin_wa_codepoints[] = {
+    0x51F9, 0x6316, 0x54C7, 0x86D9, 0x6D3C, 0x5A03, 0x74E6, 0x889C,
+    0x978B
+};
+
+static const uint32_t pinyin_wai_codepoints[] = {
+    0x6B6A, 0x5916
+};
+
+static const uint32_t pinyin_wan_codepoints[] = {
+    0x8513, 0x514D, 0x5A29, 0x8C4C, 0x5F2F, 0x6E7E, 0x73A9, 0x987D,
+    0x4E38, 0x70F7, 0x5B8C, 0x7897, 0x633D, 0x665A, 0x7696, 0x60CB,
+    0x5B9B, 0x5A49, 0x4E07, 0x8155, 0x56ED
+};
+
+static const uint32_t pinyin_wang_codepoints[] = {
+    0x65B9, 0x7687, 0x5321, 0x8292, 0x6C6A, 0x738B, 0x4EA1, 0x6789,
+    0x7F51, 0x5F80, 0x65FA, 0x671B, 0x5FD8, 0x5984
+};
+
+static const uint32_t pinyin_wei_codepoints[] = {
+    0x5824, 0x673A, 0x7ACB, 0x5A01, 0x5DCD, 0x5FAE, 0x5371, 0x97E6,
+    0x8FDD, 0x6845, 0x56F4, 0x552F, 0x60DF, 0x4E3A, 0x6F4D, 0x7EF4,
+    0x82C7, 0x840E, 0x59D4, 0x4F1F, 0x4F2A, 0x5C3E, 0x7EAC, 0x672A,
+    0x851A, 0x5473, 0x754F, 0x80C3, 0x5582, 0x9B4F, 0x4F4D, 0x6E2D,
+    0x8C13, 0x5C09, 0x6170, 0x536B, 0x9057, 0x6709, 0x4E8E
+};
+
+static const uint32_t pinyin_wen_codepoints[] = {
+    0x6627, 0x514D, 0x5A29, 0x761F, 0x6E29, 0x868A, 0x6587, 0x95FB,
+    0x7EB9, 0x543B, 0x7A33, 0x7D0A, 0x95EE, 0x9650, 0x773C
+};
+
+static const uint32_t pinyin_weng_codepoints[] = {
+    0x55E1, 0x7FC1, 0x74EE
+};
+
+static const uint32_t pinyin_wo_codepoints[] = {
+    0x761F, 0x631D, 0x8717, 0x6DA1, 0x7A9D, 0x6211, 0x65A1, 0x5367,
+    0x63E1, 0x6C83
+};
+
+static const uint32_t pinyin_wu_codepoints[] = {
+    0x6076, 0x6BCD, 0x4EA1, 0x5DEB, 0x545C, 0x94A8, 0x4E4C, 0x6C61,
+    0x8BEC, 0x5C4B, 0x65E0, 0x829C, 0x68A7, 0x543E, 0x5434, 0x6BCB,
+    0x6B66, 0x4E94, 0x6342, 0x5348, 0x821E, 0x4F0D, 0x4FAE, 0x575E,
+    0x620A, 0x96FE, 0x6664, 0x7269, 0x52FF, 0x52A1, 0x609F, 0x8BEF
+};
+
+static const uint32_t pinyin_xi_codepoints[] = {
+    0x65E2, 0x814A, 0x730E, 0x5364, 0x6816, 0x6D12, 0x5C4E, 0x6495,
+    0x6614, 0x7199, 0x6790, 0x897F, 0x7852, 0x77FD, 0x6670, 0x563B,
+    0x5438, 0x9521, 0x727A, 0x7A00, 0x606F, 0x5E0C, 0x6089, 0x819D,
+    0x5915, 0x60DC, 0x7184, 0x70EF, 0x6EAA, 0x6C50, 0x7280, 0x6A84,
+    0x88AD, 0x5E2D, 0x4E60, 0x5AB3, 0x559C, 0x94E3, 0x6D17, 0x7CFB,
+    0x9699, 0x620F, 0x7EC6
+};
+
+static const uint32_t pinyin_xia_codepoints[] = {
+    0x547C, 0x552C, 0x5047, 0x778E, 0x867E, 0x5323, 0x971E, 0x8F96,
+    0x6687, 0x5CE1, 0x4FA0, 0x72ED, 0x4E0B, 0x53A6, 0x590F, 0x5413,
+    0x659C, 0x62BC, 0x5440
+};
+
+static const uint32_t pinyin_xian_codepoints[] = {
+    0x634D, 0x80A9, 0x78B1, 0x89C1, 0x6D12, 0x7701, 0x63A2, 0x94E3,
+    0x6D17, 0x6380, 0x9528, 0x5148, 0x4ED9, 0x9C9C, 0x7EA4, 0x54B8,
+    0x8D24, 0x8854, 0x8237, 0x95F2, 0x6D8E, 0x5F26, 0x5ACC, 0x663E,
+    0x9669, 0x73B0, 0x732E, 0x53BF, 0x817A, 0x9985, 0x7FA1, 0x5BAA,
+    0x9677, 0x9650, 0x7EBF, 0x77E3
+};
+
+static const uint32_t pinyin_xiang_codepoints[] = {
+    0x4EA8, 0x964D, 0x6518, 0x76F8, 0x53A2, 0x9576, 0x9999, 0x7BB1,
+    0x8944, 0x6E58, 0x4E61, 0x7FD4, 0x7965, 0x8BE6, 0x60F3, 0x54CD,
+    0x4EAB, 0x9879, 0x5DF7, 0x6A61, 0x50CF, 0x5411, 0x8C61, 0x6D0B
+};
+
+static const uint32_t pinyin_xiao_codepoints[] = {
+    0x53F7, 0x547C, 0x552C, 0x80F6, 0x72E1, 0x4FCF, 0x68A2, 0x634E,
+    0x828D, 0x54E8, 0x641C, 0x8427, 0x785D, 0x9704, 0x524A, 0x54EE,
+    0x56A3, 0x9500, 0x6D88, 0x5BB5, 0x6DC6, 0x6653, 0x5C0F, 0x5B5D,
+    0x6821, 0x8096, 0x5578, 0x7B11, 0x6548
+};
+
+static const uint32_t pinyin_xie_codepoints[] = {
+    0x6E89, 0x63A5, 0x6854, 0x89E3, 0x5951, 0x6954, 0x4E9B, 0x6B47,
+    0x874E, 0x978B, 0x534F, 0x631F, 0x643A, 0x90AA, 0x659C, 0x80C1,
+    0x8C10, 0x5199, 0x68B0, 0x5378, 0x87F9, 0x61C8, 0x6CC4, 0x6CFB,
+    0x8C22, 0x5C51, 0x8840, 0x8036, 0x53F6, 0x8C6B, 0x6C41
+};
+
+static const uint32_t pinyin_xin_codepoints[] = {
+    0x6B3E, 0x85AA, 0x82AF, 0x950C, 0x6B23, 0x8F9B, 0x65B0, 0x5FFB,
+    0x5FC3, 0x4FE1, 0x8845, 0x5BFB
+};
+
+static const uint32_t pinyin_xing_codepoints[] = {
+    0x7701, 0x80DC, 0x661F, 0x8165, 0x7329, 0x60FA, 0x5174, 0x5211,
+    0x578B, 0x5F62, 0x90A2, 0x884C, 0x9192, 0x5E78, 0x674F, 0x6027,
+    0x59D3, 0x7814
+};
+
+static const uint32_t pinyin_xiong_codepoints[] = {
+    0x80FD, 0x5BAA, 0x5144, 0x51F6, 0x80F8, 0x5308, 0x6C79, 0x96C4,
+    0x718A
+};
+
+static const uint32_t pinyin_xiu_codepoints[] = {
+    0x81ED, 0x5BBF, 0x4F11, 0x4FEE, 0x7F9E, 0x673D, 0x55C5, 0x9508,
+    0x79C0, 0x8896, 0x7EE3
+};
+
+static const uint32_t pinyin_xu_codepoints[] = {
+    0x547C, 0x59D0, 0x90AA, 0x4F11, 0x589F, 0x620C, 0x9700, 0x865A,
+    0x5618, 0x987B, 0x5F90, 0x8BB8, 0x84C4, 0x9157, 0x53D9, 0x65ED,
+    0x5E8F, 0x755C, 0x6064, 0x7D6E, 0x5A7F, 0x7EEA, 0x7EED, 0x4E8E,
+    0x4F59, 0x828B, 0x5401
+};
+
+static const uint32_t pinyin_xuan_codepoints[] = {
+    0x6696, 0x5238, 0x8F69, 0x55A7, 0x5BA3, 0x60AC, 0x65CB, 0x7384,
+    0x9009, 0x7663, 0x7729, 0x7EDA, 0x64B0, 0x6ECB
+};
+
+static const uint32_t pinyin_xue_codepoints[] = {
+    0x7094, 0x524A, 0x54EE, 0x9774, 0x859B, 0x5B66, 0x7A74, 0x96EA,
+    0x8840
+};
+
+static const uint32_t pinyin_xun_codepoints[] = {
+    0x9041, 0x8364, 0x6D5A, 0x6D12, 0x68AD, 0x6F6D, 0x52CB, 0x718F,
+    0x5FAA, 0x65EC, 0x8BE2, 0x5BFB, 0x9A6F, 0x5DE1, 0x6B89, 0x6C5B,
+    0x8BAD, 0x8BAF, 0x900A, 0x8FC5
+};
+
+static const uint32_t pinyin_ya_codepoints[] = {
+    0x543E, 0x6B47, 0x90AA, 0x538B, 0x62BC, 0x9E26, 0x9E2D, 0x5440,
+    0x4E2B, 0x82BD, 0x7259, 0x869C, 0x5D16, 0x8859, 0x6DAF, 0x96C5,
+    0x54D1, 0x4E9A, 0x8BB6, 0x5FA1, 0x672D, 0x8F67
+};
+
+static const uint32_t pinyin_yan_codepoints[] = {
+    0x764C, 0x4FFA, 0x5382, 0x4F46, 0x6DE1, 0x5E7F, 0x72E0, 0x852B,
+    0x94C5, 0x6D8E, 0x7FA1, 0x5DE1, 0x7109, 0x54BD, 0x9609, 0x70DF,
+    0x6DF9, 0x76D0, 0x4E25, 0x7814, 0x8712, 0x5CA9, 0x5EF6, 0x8A00,
+    0x989C, 0x960E, 0x708E, 0x6CBF, 0x5944, 0x63A9, 0x773C, 0x884D,
+    0x6F14, 0x8273, 0x5830, 0x71D5, 0x538C, 0x781A, 0x96C1, 0x5501,
+    0x5F66, 0x7130, 0x5BB4, 0x8C1A, 0x9A8C, 0x6BB7, 0x6DEB
+};
+
+static const uint32_t pinyin_yang_codepoints[] = {
+    0x6602, 0x6B83, 0x592E, 0x9E2F, 0x79E7, 0x6768, 0x626C, 0x4F6F,
+    0x75A1, 0x7F8A, 0x6D0B, 0x9633, 0x6C27, 0x4EF0, 0x75D2, 0x517B,
+    0x6837, 0x6F3E, 0x82F1, 0x6620
+};
+
+static const uint32_t pinyin_yao_codepoints[] = {
+    0x4FA5, 0x4E48, 0x759F, 0x9676, 0x9080, 0x8170, 0x5996, 0x7476,
+    0x6447, 0x5C27, 0x9065, 0x7A91, 0x8C23, 0x59DA, 0x54AC, 0x8200,
+    0x836F, 0x8981, 0x8000, 0x6DEB, 0x7531, 0x5E7C, 0x7EA6, 0x94A5
+};
+
+static const uint32_t pinyin_ye_codepoints[] = {
+    0x559D, 0x5C04, 0x5885, 0x6D82, 0x90AA, 0x659C, 0x54BD, 0x6930,
+    0x564E, 0x8036, 0x7237, 0x91CE, 0x51B6, 0x4E5F, 0x9875, 0x6396,
+    0x4E1A, 0x53F6, 0x66F3, 0x814B, 0x591C, 0x6DB2, 0x62FD
+};
+
+static const uint32_t pinyin_yi_codepoints[] = {
+    0x827E, 0x6020, 0x8FED, 0x86FE, 0x7599, 0x59EC, 0x96B6, 0x5947,
+    0x5D0E, 0x6C7D, 0x86C7, 0x5C04, 0x5931, 0x65BD, 0x98DF, 0x5DF3,
+    0x5B83, 0x53F0, 0x53F9, 0x542C, 0x5C3E, 0x7199, 0x5915, 0x7FA1,
+    0x6CC4, 0x7109, 0x564E, 0x4E5F, 0x4E00, 0x58F9, 0x533B, 0x63D6,
+    0x94F1, 0x4F9D, 0x4F0A, 0x8863, 0x9890, 0x5937, 0x9057, 0x79FB,
+    0x4EEA, 0x80F0, 0x7591, 0x6C82, 0x5B9C, 0x59E8, 0x5F5D, 0x6905,
+    0x8681, 0x501A, 0x5DF2, 0x4E59, 0x77E3, 0x4EE5, 0x827A, 0x6291,
+    0x6613, 0x9091, 0x5C79, 0x4EBF, 0x5F79, 0x81C6, 0x9038, 0x8084,
+    0x75AB, 0x4EA6, 0x88D4, 0x610F, 0x6BC5, 0x5FC6, 0x4E49, 0x76CA,
+    0x6EA2, 0x8BE3, 0x8BAE, 0x8C0A, 0x8BD1, 0x5F02, 0x7FFC, 0x7FCC,
+    0x7ECE, 0x5370
+};
+
+static const uint32_t pinyin_yin_codepoints[] = {
+    0x5E01, 0x57A6, 0x6F6D, 0x542C, 0x70DF, 0x8A00, 0x58F9, 0x6C82,
+    0x8335, 0x836B, 0x56E0, 0x6BB7, 0x97F3, 0x9634, 0x59FB, 0x541F,
+    0x94F6, 0x6DEB, 0x5BC5, 0x996E, 0x5C39, 0x5F15, 0x9690, 0x5370,
+    0x6E5B, 0x4F17
+};
+
+static const uint32_t pinyin_ying_codepoints[] = {
+    0x901E, 0x7538, 0x666F, 0x54E9, 0x592E, 0x82F1, 0x6A31, 0x5A74,
+    0x9E70, 0x5E94, 0x7F28, 0x83B9, 0x8424, 0x8425, 0x8367, 0x8747,
+    0x8FCE, 0x8D62, 0x76C8, 0x5F71, 0x9896, 0x786C, 0x6620
+};
+
+static const uint32_t pinyin_yo_codepoints[] = {
+    0x54DF, 0x80B2
+};
+
+static const uint32_t pinyin_yong_codepoints[] = {
+    0x5BB9, 0x62E5, 0x4F63, 0x81C3, 0x75C8, 0x5EB8, 0x96CD, 0x8E0A,
+    0x86F9, 0x548F, 0x6CF3, 0x6D8C, 0x6C38, 0x607F, 0x52C7, 0x7528,
+    0x9047
+};
+
+static const uint32_t pinyin_you_codepoints[] = {
+    0x5965, 0x6CC5, 0x6270, 0x53F9, 0x5E7D, 0x4F18, 0x60A0, 0x5FE7,
+    0x5C24, 0x7531, 0x90AE, 0x94C0, 0x72B9, 0x6CB9, 0x6E38, 0x9149,
+    0x6709, 0x53CB, 0x53F3, 0x4F51, 0x91C9, 0x8BF1, 0x53C8, 0x5E7C
+};
+
+static const uint32_t pinyin_yu_codepoints[] = {
+    0x5965, 0x61CA, 0x6FB3, 0x8C37, 0x6216, 0x4E8F, 0x8212, 0x5B9B,
+    0x738B, 0x851A, 0x5C09, 0x68A7, 0x543E, 0x8859, 0x8FC2, 0x6DE4,
+    0x4E8E, 0x76C2, 0x6986, 0x865E, 0x611A, 0x8206, 0x4F59, 0x4FDE,
+    0x903E, 0x9C7C, 0x6109, 0x6E1D, 0x6E14, 0x9685, 0x4E88, 0x5A31,
+    0x96E8, 0x4E0E, 0x5C7F, 0x79B9, 0x5B87, 0x8BED, 0x7FBD, 0x7389,
+    0x57DF, 0x828B, 0x90C1, 0x5401, 0x9047, 0x55BB, 0x5CEA, 0x5FA1,
+    0x6108, 0x6B32, 0x72F1, 0x80B2, 0x8A89, 0x6D74, 0x5BD3, 0x88D5,
+    0x9884, 0x8C6B, 0x9A6D, 0x82D1, 0x7CA5
+};
+
+static const uint32_t pinyin_yuan_codepoints[] = {
+    0x7A7F, 0x6350, 0x962E, 0x5B9B, 0x54BD, 0x9E33, 0x6E0A, 0x51A4,
+    0x5143, 0x57A3, 0x8881, 0x539F, 0x63F4, 0x8F95, 0x56ED, 0x5458,
+    0x5706, 0x733F, 0x6E90, 0x7F18, 0x8FDC, 0x82D1, 0x613F, 0x6028,
+    0x9662, 0x5141
+};
+
+static const uint32_t pinyin_yue_codepoints[] = {
+    0x5757, 0x4E50, 0x8BF4, 0x8715, 0x66F0, 0x7EA6, 0x8D8A, 0x8DC3,
+    0x94A5, 0x5CB3, 0x7CA4, 0x6708, 0x60A6, 0x9605
+};
+
+static const uint32_t pinyin_yun_codepoints[] = {
+    0x76FE, 0x5747, 0x5B9B, 0x5C09, 0x761F, 0x6E29, 0x5C39, 0x5458,
+    0x82D1, 0x6028, 0x8018, 0x4E91, 0x90E7, 0x5300, 0x9668, 0x5141,
+    0x8FD0, 0x8574, 0x915D, 0x6655, 0x97F5, 0x5B55
+};
+
+static const uint32_t pinyin_za_codepoints[] = {
+    0x531D, 0x7838, 0x6742, 0x54B1, 0x624E, 0x548B
+};
+
+static const uint32_t pinyin_zai_codepoints[] = {
+    0x624D, 0x683D, 0x54C9, 0x707E, 0x5BB0, 0x8F7D, 0x518D, 0x5728,
+    0x4ED4
+};
+
+static const uint32_t pinyin_zan_codepoints[] = {
+    0x54B1, 0x6512, 0x6682, 0x8D5E
+};
+
+static const uint32_t pinyin_zang_codepoints[] = {
+    0x85CF, 0x8D43, 0x810F, 0x846C
+};
+
+static const uint32_t pinyin_zao_codepoints[] = {
+    0x69FD, 0x8349, 0x7A96, 0x906D, 0x7CDF, 0x51FF, 0x85FB, 0x67A3,
+    0x65E9, 0x6FA1, 0x86A4, 0x8E81, 0x566A, 0x9020, 0x7682, 0x7076,
+    0x71E5
+};
+
+static const uint32_t pinyin_ze_codepoints[] = {
+    0x4FA7, 0x63AA, 0x8D23, 0x62E9, 0x5219, 0x6CFD, 0x548B, 0x67DE
+};
+
+static const uint32_t pinyin_zei_codepoints[] = {
+    0x8D3C
+};
+
+static const uint32_t pinyin_zen_codepoints[] = {
+    0x600E
+};
+
+static const uint32_t pinyin_zeng_codepoints[] = {
+    0x589E, 0x618E, 0x66FE, 0x8D60, 0x7EFC
+};
+
+static const uint32_t pinyin_zha_codepoints[] = {
+    0x518C, 0x63D2, 0x67E5, 0x54C6, 0x8721, 0x624E, 0x55B3, 0x6E23,
+    0x672D, 0x8F67, 0x94E1, 0x95F8, 0x7728, 0x6805, 0x69A8, 0x548B,
+    0x4E4D, 0x70B8, 0x8BC8, 0x67DE
+};
+
+static const uint32_t pinyin_zhai_codepoints[] = {
+    0x4FA7, 0x67F4, 0x75B5, 0x7FDF, 0x5EA6, 0x796D, 0x62E9, 0x6458,
+    0x658B, 0x5B85, 0x7A84, 0x503A, 0x5BE8
+};
+
+static const uint32_t pinyin_zhan_codepoints[] = {
+    0x98A4, 0x8892, 0x77BB, 0x6BE1, 0x8A79, 0x7C98, 0x6CBE, 0x76CF,
+    0x65A9, 0x8F97, 0x5D2D, 0x5C55, 0x8638, 0x6808, 0x5360, 0x6218,
+    0x7AD9, 0x6E5B, 0x7EFD
+};
+
+static const uint32_t pinyin_zhang_codepoints[] = {
+    0x957F, 0x6A1F, 0x7AE0, 0x5F70, 0x6F33, 0x5F20, 0x638C, 0x6DA8,
+    0x6756, 0x4E08, 0x5E10, 0x8D26, 0x4ED7, 0x80C0, 0x7634, 0x969C
+};
+
+static const uint32_t pinyin_zhao_codepoints[] = {
+    0x671D, 0x5632, 0x6DD6, 0x6843, 0x86A4, 0x62DB, 0x662D, 0x627E,
+    0x6CBC, 0x8D75, 0x7167, 0x7F69, 0x5146, 0x8087, 0x53EC, 0x8457,
+    0x722A, 0x7740
+};
+
+static const uint32_t pinyin_zhe_codepoints[] = {
+    0x65A5, 0x5835, 0x5EB6, 0x906E, 0x6298, 0x54F2, 0x86F0, 0x8F99,
+    0x8005, 0x9517, 0x8517, 0x8FD9, 0x6D59, 0x8457, 0x7740
+};
+
+static const uint32_t pinyin_zhei_codepoints[] = {
+    0x8FD9
+};
+
+static const uint32_t pinyin_zhen_codepoints[] = {
+    0x8D81, 0x5507, 0x6EC7, 0x9F0E, 0x614E, 0x586B, 0x73CD, 0x659F,
+    0x771F, 0x7504, 0x7827, 0x81FB, 0x8D1E, 0x9488, 0x4FA6, 0x6795,
+    0x75B9, 0x8BCA, 0x9707, 0x632F, 0x9547, 0x9635, 0x5E27
+};
+
+static const uint32_t pinyin_zheng_codepoints[] = {
+    0x655E, 0x627F, 0x5960, 0x4E01, 0x8D9F, 0x84B8, 0x6323, 0x7741,
+    0x5F81, 0x72F0, 0x4E89, 0x6014, 0x6574, 0x62EF, 0x6B63, 0x653F,
+    0x5E27, 0x75C7, 0x90D1, 0x8BC1
+};
+
+static const uint32_t pinyin_zhi_codepoints[] = {
+    0x57C3, 0x62B5, 0x79EF, 0x4F0E, 0x7941, 0x8BC6, 0x793A, 0x6C0F,
+    0x6043, 0x62D3, 0x829D, 0x679D, 0x652F, 0x5431, 0x8718, 0x77E5,
+    0x80A2, 0x8102, 0x6C41, 0x4E4B, 0x7EC7, 0x804C, 0x76F4, 0x690D,
+    0x6B96, 0x6267, 0x503C, 0x4F84, 0x5740, 0x6307, 0x6B62, 0x8DBE,
+    0x53EA, 0x65E8, 0x7EB8, 0x5FD7, 0x631A, 0x63B7, 0x81F3, 0x81F4,
+    0x7F6E, 0x5E1C, 0x5CD9, 0x5236, 0x667A, 0x79E9, 0x7A1A, 0x8D28,
+    0x7099, 0x75D4, 0x6EDE, 0x6CBB, 0x7A92
+};
+
+static const uint32_t pinyin_zhong_codepoints[] = {
+    0x8463, 0x7AE5, 0x4E2D, 0x76C5, 0x5FE0, 0x949F, 0x8877, 0x7EC8,
+    0x79CD, 0x80BF, 0x91CD, 0x4EF2, 0x4F17
+};
+
+static const uint32_t pinyin_zhou_codepoints[] = {
+    0x626D, 0x80B2, 0x821F, 0x5468, 0x5DDE, 0x6D32, 0x8BCC, 0x7CA5,
+    0x8F74, 0x8098, 0x5E1A, 0x5492, 0x76B1, 0x5B99, 0x663C, 0x9AA4,
+    0x9010, 0x6CE8, 0x795D, 0x5544
+};
+
+static const uint32_t pinyin_zhu_codepoints[] = {
+    0x671D, 0x9664, 0x6597, 0x9017, 0x67E0, 0x5B81, 0x6CDE, 0x5C5E,
+    0x672F, 0x5EB6, 0x4E88, 0x4E4B, 0x73E0, 0x682A, 0x86DB, 0x6731,
+    0x732A, 0x8BF8, 0x8BDB, 0x9010, 0x7AF9, 0x70DB, 0x716E, 0x62C4,
+    0x77A9, 0x5631, 0x4E3B, 0x8457, 0x67F1, 0x52A9, 0x86C0, 0x8D2E,
+    0x94F8, 0x7B51, 0x4F4F, 0x6CE8, 0x795D, 0x9A7B, 0x8301, 0x963B
+};
+
+static const uint32_t pinyin_zhua_codepoints[] = {
+    0x631D, 0x6293, 0x722A
+};
+
+static const uint32_t pinyin_zhuai_codepoints[] = {
+    0x62FD, 0x8F6C
+};
+
+static const uint32_t pinyin_zhuan_codepoints[] = {
+    0x4F20, 0x6E4D, 0x4E13, 0x7816, 0x8F6C, 0x64B0, 0x8D5A, 0x7BC6
+};
+
+static const uint32_t pinyin_zhuang_codepoints[] = {
+    0x5E62, 0x6869, 0x5E84, 0x88C5, 0x5986, 0x649E, 0x58EE, 0x72B6
+};
+
+static const uint32_t pinyin_zhui_codepoints[] = {
+    0x63E3, 0x5782, 0x96A7, 0x81F4, 0x690E, 0x9525, 0x8FFD, 0x8D58,
+    0x5760, 0x7F00
+};
+
+static const uint32_t pinyin_zhun_codepoints[] = {
+    0x6DF3, 0x6566, 0x5C6F, 0x8C06, 0x51C6
+};
+
+static const uint32_t pinyin_zhuo_codepoints[] = {
+    0x6387, 0x7F34, 0x6DD6, 0x52FA, 0x8457, 0x6349, 0x62D9, 0x5353,
+    0x684C, 0x7422, 0x8301, 0x914C, 0x5544, 0x7740, 0x707C, 0x6D4A
+};
+
+static const uint32_t pinyin_zi_codepoints[] = {
+    0x67F4, 0x75B5, 0x6B21, 0x4E8B, 0x5431, 0x5179, 0x54A8, 0x8D44,
+    0x59FF, 0x6ECB, 0x6DC4, 0x5B5C, 0x7D2B, 0x4ED4, 0x7C7D, 0x6ED3,
+    0x5B50, 0x81EA, 0x6E0D, 0x5B57
+};
+
+static const uint32_t pinyin_zong_codepoints[] = {
+    0x4ECE, 0x9B03, 0x68D5, 0x8E2A, 0x5B97, 0x7EFC, 0x603B, 0x7EB5
+};
+
+static const uint32_t pinyin_zou_codepoints[] = {
+    0x8DA3, 0x90B9, 0x8D70, 0x594F, 0x63CD, 0x65CF
+};
+
+static const uint32_t pinyin_zu_codepoints[] = {
+    0x6DEC, 0x59D0, 0x6CAE, 0x79DF, 0x8DB3, 0x5352, 0x65CF, 0x7956,
+    0x8BC5, 0x963B, 0x7EC4
+};
+
+static const uint32_t pinyin_zuan_codepoints[] = {
+    0x64AE, 0x8D5A, 0x94BB, 0x7E82
+};
+
+static const uint32_t pinyin_zui_codepoints[] = {
+    0x6467, 0x64AE, 0x5806, 0x5480, 0x5634, 0x9189, 0x6700, 0x7F6A
+};
+
+static const uint32_t pinyin_zun_codepoints[] = {
+    0x5960, 0x8E72, 0x5C0A, 0x9075
+};
+
+static const uint32_t pinyin_zuo_codepoints[] = {
+    0x918B, 0x64AE, 0x632B, 0x51FF, 0x4E4D, 0x7422, 0x6628, 0x5DE6,
+    0x4F50, 0x67DE, 0x505A, 0x4F5C, 0x5750, 0x5EA7
+};
+
+static const pinyin_entry_t pinyin_dict[] = {
+    {"a", pinyin_a_codepoints, 3},
+    {"ai", pinyin_ai_codepoints, 16},
+    {"an", pinyin_an_codepoints, 13},
+    {"ang", pinyin_ang_codepoints, 4},
+    {"ao", pinyin_ao_codepoints, 11},
+    {"ba", pinyin_ba_codepoints, 20},
+    {"bai", pinyin_bai_codepoints, 13},
+    {"ban", pinyin_ban_codepoints, 18},
+    {"bang", pinyin_bang_codepoints, 14},
+    {"bao", pinyin_bao_codepoints, 23},
+    {"bei", pinyin_bei_codepoints, 21},
+    {"ben", pinyin_ben_codepoints, 6},
+    {"beng", pinyin_beng_codepoints, 12},
+    {"bi", pinyin_bi_codepoints, 37},
+    {"bian", pinyin_bian_codepoints, 13},
+    {"biao", pinyin_biao_codepoints, 6},
+    {"bie", pinyin_bie_codepoints, 10},
+    {"bin", pinyin_bin_codepoints, 7},
+    {"bing", pinyin_bing_codepoints, 12},
+    {"bo", pinyin_bo_codepoints, 42},
+    {"bu", pinyin_bu_codepoints, 15},
+    {"ca", pinyin_ca_codepoints, 3},
+    {"cai", pinyin_cai_codepoints, 11},
+    {"can", pinyin_can_codepoints, 8},
+    {"cang", pinyin_cang_codepoints, 5},
+    {"cao", pinyin_cao_codepoints, 7},
+    {"ce", pinyin_ce_codepoints, 7},
+    {"cen", pinyin_cen_codepoints, 1},
+    {"ceng", pinyin_ceng_codepoints, 5},
+    {"cha", pinyin_cha_codepoints, 17},
+    {"chai", pinyin_chai_codepoints, 6},
+    {"chan", pinyin_chan_codepoints, 15},
+    {"chang", pinyin_chang_codepoints, 17},
+    {"chao", pinyin_chao_codepoints, 11},
+    {"che", pinyin_che_codepoints, 11},
+    {"chen", pinyin_chen_codepoints, 19},
+    {"cheng", pinyin_cheng_codepoints, 22},
+    {"chi", pinyin_chi_codepoints, 29},
+    {"chong", pinyin_chong_codepoints, 12},
+    {"chou", pinyin_chou_codepoints, 13},
+    {"chu", pinyin_chu_codepoints, 25},
+    {"chua", pinyin_chua_codepoints, 1},
+    {"chuai", pinyin_chuai_codepoints, 1},
+    {"chuan", pinyin_chuan_codepoints, 7},
+    {"chuang", pinyin_chuang_codepoints, 8},
+    {"chui", pinyin_chui_codepoints, 6},
+    {"chun", pinyin_chun_codepoints, 7},
+    {"chuo", pinyin_chuo_codepoints, 7},
+    {"ci", pinyin_ci_codepoints, 19},
+    {"cong", pinyin_cong_codepoints, 7},
+    {"cou", pinyin_cou_codepoints, 6},
+    {"cu", pinyin_cu_codepoints, 8},
+    {"cuan", pinyin_cuan_codepoints, 5},
+    {"cui", pinyin_cui_codepoints, 13},
+    {"cun", pinyin_cun_codepoints, 5},
+    {"cuo", pinyin_cuo_codepoints, 10},
+    {"da", pinyin_da_codepoints, 10},
+    {"dai", pinyin_dai_codepoints, 15},
+    {"dan", pinyin_dan_codepoints, 23},
+    {"dang", pinyin_dang_codepoints, 5},
+    {"dao", pinyin_dao_codepoints, 15},
+    {"de", pinyin_de_codepoints, 6},
+    {"dei", pinyin_dei_codepoints, 1},
+    {"deng", pinyin_deng_codepoints, 9},
+    {"di", pinyin_di_codepoints, 27},
+    {"dian", pinyin_dian_codepoints, 19},
+    {"diao", pinyin_diao_codepoints, 15},
+    {"die", pinyin_die_codepoints, 12},
+    {"ding", pinyin_ding_codepoints, 12},
+    {"diu", pinyin_diu_codepoints, 1},
+    {"dong", pinyin_dong_codepoints, 13},
+    {"dou", pinyin_dou_codepoints, 11},
+    {"du", pinyin_du_codepoints, 18},
+    {"duan", pinyin_duan_codepoints, 6},
+    {"dui", pinyin_dui_codepoints, 6},
+    {"dun", pinyin_dun_codepoints, 10},
+    {"duo", pinyin_duo_codepoints, 20},
+    {"e", pinyin_e_codepoints, 21},
+    {"en", pinyin_en_codepoints, 1},
+    {"er", pinyin_er_codepoints, 8},
+    {"fa", pinyin_fa_codepoints, 10},
+    {"fan", pinyin_fan_codepoints, 18},
+    {"fang", pinyin_fang_codepoints, 11},
+    {"fei", pinyin_fei_codepoints, 14},
+    {"fen", pinyin_fen_codepoints, 19},
+    {"feng", pinyin_feng_codepoints, 19},
+    {"fo", pinyin_fo_codepoints, 1},
+    {"fou", pinyin_fou_codepoints, 2},
+    {"fu", pinyin_fu_codepoints, 55},
+    {"ga", pinyin_ga_codepoints, 6},
+    {"gai", pinyin_gai_codepoints, 11},
+    {"gan", pinyin_gan_codepoints, 16},
+    {"gang", pinyin_gang_codepoints, 13},
+    {"gao", pinyin_gao_codepoints, 12},
+    {"ge", pinyin_ge_codepoints, 27},
+    {"gei", pinyin_gei_codepoints, 1},
+    {"gen", pinyin_gen_codepoints, 3},
+    {"geng", pinyin_geng_codepoints, 11},
+    {"gong", pinyin_gong_codepoints, 19},
+    {"gou", pinyin_gou_codepoints, 11},
+    {"gu", pinyin_gu_codepoints, 26},
+    {"gua", pinyin_gua_codepoints, 8},
+    {"guai", pinyin_guai_codepoints, 3},
+    {"guan", pinyin_guan_codepoints, 15},
+    {"guang", pinyin_guang_codepoints, 5},
+    {"gui", pinyin_gui_codepoints, 25},
+    {"gun", pinyin_gun_codepoints, 5},
+    {"guo", pinyin_guo_codepoints, 10},
+    {"ha", pinyin_ha_codepoints, 5},
+    {"hai", pinyin_hai_codepoints, 9},
+    {"han", pinyin_han_codepoints, 23},
+    {"hang", pinyin_hang_codepoints, 10},
+    {"hao", pinyin_hao_codepoints, 13},
+    {"he", pinyin_he_codepoints, 30},
+    {"hei", pinyin_hei_codepoints, 2},
+    {"hen", pinyin_hen_codepoints, 5},
+    {"heng", pinyin_heng_codepoints, 6},
+    {"hng", pinyin_hng_codepoints, 1},
+    {"hong", pinyin_hong_codepoints, 12},
+    {"hou", pinyin_hou_codepoints, 7},
+    {"hu", pinyin_hu_codepoints, 26},
+    {"hua", pinyin_hua_codepoints, 13},
+    {"huai", pinyin_huai_codepoints, 7},
+    {"huan", pinyin_huan_codepoints, 18},
+    {"huang", pinyin_huang_codepoints, 17},
+    {"hui", pinyin_hui_codepoints, 26},
+    {"hun", pinyin_hun_codepoints, 9},
+    {"huo", pinyin_huo_codepoints, 15},
+    {"ji", pinyin_ji_codepoints, 70},
+    {"jia", pinyin_jia_codepoints, 24},
+    {"jian", pinyin_jian_codepoints, 45},
+    {"jiang", pinyin_jiang_codepoints, 15},
+    {"jiao", pinyin_jiao_codepoints, 33},
+    {"jie", pinyin_jie_codepoints, 42},
+    {"jin", pinyin_jin_codepoints, 23},
+    {"jing", pinyin_jing_codepoints, 29},
+    {"jiong", pinyin_jiong_codepoints, 3},
+    {"jiu", pinyin_jiu_codepoints, 18},
+    {"ju", pinyin_ju_codepoints, 39},
+    {"juan", pinyin_juan_codepoints, 12},
+    {"jue", pinyin_jue_codepoints, 18},
+    {"jun", pinyin_jun_codepoints, 15},
+    {"ka", pinyin_ka_codepoints, 4},
+    {"kai", pinyin_kai_codepoints, 9},
+    {"kan", pinyin_kan_codepoints, 9},
+    {"kang", pinyin_kang_codepoints, 11},
+    {"kao", pinyin_kao_codepoints, 5},
+    {"ke", pinyin_ke_codepoints, 17},
+    {"kei", pinyin_kei_codepoints, 1},
+    {"ken", pinyin_ken_codepoints, 5},
+    {"keng", pinyin_keng_codepoints, 2},
+    {"kong", pinyin_kong_codepoints, 5},
+    {"kou", pinyin_kou_codepoints, 5},
+    {"ku", pinyin_ku_codepoints, 12},
+    {"kua", pinyin_kua_codepoints, 5},
+    {"kuai", pinyin_kuai_codepoints, 7},
+    {"kuan", pinyin_kuan_codepoints, 4},
+    {"kuang", pinyin_kuang_codepoints, 13},
+    {"kui", pinyin_kui_codepoints, 13},
+    {"kun", pinyin_kun_codepoints, 6},
+    {"kuo", pinyin_kuo_codepoints, 5},
+    {"la", pinyin_la_codepoints, 9},
+    {"lai", pinyin_lai_codepoints, 3},
+    {"lan", pinyin_lan_codepoints, 16},
+    {"lang", pinyin_lang_codepoints, 8},
+    {"lao", pinyin_lao_codepoints, 14},
+    {"le", pinyin_le_codepoints, 4},
+    {"lei", pinyin_lei_codepoints, 12},
+    {"leng", pinyin_leng_codepoints, 3},
+    {"li", pinyin_li_codepoints, 37},
+    {"lia", pinyin_lia_codepoints, 1},
+    {"lian", pinyin_lian_codepoints, 16},
+    {"liang", pinyin_liang_codepoints, 13},
+    {"liao", pinyin_liao_codepoints, 14},
+    {"lie", pinyin_lie_codepoints, 9},
+    {"lin", pinyin_lin_codepoints, 13},
+    {"ling", pinyin_ling_codepoints, 19},
+    {"liu", pinyin_liu_codepoints, 16},
+    {"lo", pinyin_lo_codepoints, 1},
+    {"long", pinyin_long_codepoints, 10},
+    {"lou", pinyin_lou_codepoints, 8},
+    {"lu", pinyin_lu_codepoints, 25},
+    {"luan", pinyin_luan_codepoints, 6},
+    {"lun", pinyin_lun_codepoints, 7},
+    {"luo", pinyin_luo_codepoints, 19},
+    {"lv", pinyin_lv_codepoints, 16},
+    {"lve", pinyin_lve_codepoints, 3},
+    {"ma", pinyin_ma_codepoints, 14},
+    {"mai", pinyin_mai_codepoints, 8},
+    {"man", pinyin_man_codepoints, 11},
+    {"mang", pinyin_mang_codepoints, 6},
+    {"mao", pinyin_mao_codepoints, 15},
+    {"me", pinyin_me_codepoints, 3},
+    {"mei", pinyin_mei_codepoints, 21},
+    {"men", pinyin_men_codepoints, 3},
+    {"meng", pinyin_meng_codepoints, 10},
+    {"mi", pinyin_mi_codepoints, 16},
+    {"mian", pinyin_mian_codepoints, 9},
+    {"miao", pinyin_miao_codepoints, 10},
+    {"mie", pinyin_mie_codepoints, 2},
+    {"min", pinyin_min_codepoints, 7},
+    {"ming", pinyin_ming_codepoints, 9},
+    {"miu", pinyin_miu_codepoints, 1},
+    {"mo", pinyin_mo_codepoints, 34},
+    {"mou", pinyin_mou_codepoints, 5},
+    {"mu", pinyin_mu_codepoints, 20},
+    {"na", pinyin_na_codepoints, 10},
+    {"nai", pinyin_nai_codepoints, 8},
+    {"nan", pinyin_nan_codepoints, 4},
+    {"nang", pinyin_nang_codepoints, 1},
+    {"nao", pinyin_nao_codepoints, 5},
+    {"ne", pinyin_ne_codepoints, 4},
+    {"nei", pinyin_nei_codepoints, 4},
+    {"nen", pinyin_nen_codepoints, 1},
+    {"neng", pinyin_neng_codepoints, 3},
+    {"ni", pinyin_ni_codepoints, 12},
+    {"nian", pinyin_nian_codepoints, 10},
+    {"niang", pinyin_niang_codepoints, 2},
+    {"niao", pinyin_niao_codepoints, 3},
+    {"nie", pinyin_nie_codepoints, 12},
+    {"nin", pinyin_nin_codepoints, 1},
+    {"ning", pinyin_ning_codepoints, 11},
+    {"niu", pinyin_niu_codepoints, 4},
+    {"nong", pinyin_nong_codepoints, 4},
+    {"nu", pinyin_nu_codepoints, 5},
+    {"nuan", pinyin_nuan_codepoints, 1},
+    {"nuo", pinyin_nuo_codepoints, 10},
+    {"nv", pinyin_nv_codepoints, 2},
+    {"nve", pinyin_nve_codepoints, 2},
+    {"o", pinyin_o_codepoints, 1},
+    {"ou", pinyin_ou_codepoints, 10},
+    {"pa", pinyin_pa_codepoints, 13},
+    {"pai", pinyin_pai_codepoints, 9},
+    {"pan", pinyin_pan_codepoints, 19},
+    {"pang", pinyin_pang_codepoints, 14},
+    {"pao", pinyin_pao_codepoints, 11},
+    {"pei", pinyin_pei_codepoints, 13},
+    {"pen", pinyin_pen_codepoints, 4},
+    {"peng", pinyin_peng_codepoints, 21},
+    {"pi", pinyin_pi_codepoints, 30},
+    {"pian", pinyin_pian_codepoints, 8},
+    {"piao", pinyin_piao_codepoints, 6},
+    {"pie", pinyin_pie_codepoints, 3},
+    {"pin", pinyin_pin_codepoints, 6},
+    {"ping", pinyin_ping_codepoints, 13},
+    {"po", pinyin_po_codepoints, 15},
+    {"pou", pinyin_pou_codepoints, 5},
+    {"pu", pinyin_pu_codepoints, 22},
+    {"qi", pinyin_qi_codepoints, 56},
+    {"qia", pinyin_qia_codepoints, 5},
+    {"qian", pinyin_qian_codepoints, 27},
+    {"qiang", pinyin_qiang_codepoints, 10},
+    {"qiao", pinyin_qiao_codepoints, 26},
+    {"qie", pinyin_qie_codepoints, 10},
+    {"qin", pinyin_qin_codepoints, 12},
+    {"qing", pinyin_qing_codepoints, 17},
+    {"qiong", pinyin_qiong_codepoints, 3},
+    {"qiu", pinyin_qiu_codepoints, 11},
+    {"qu", pinyin_qu_codepoints, 18},
+    {"quan", pinyin_quan_codepoints, 15},
+    {"que", pinyin_que_codepoints, 11},
+    {"qun", pinyin_qun_codepoints, 4},
+    {"ran", pinyin_ran_codepoints, 4},
+    {"rang", pinyin_rang_codepoints, 5},
+    {"rao", pinyin_rao_codepoints, 3},
+    {"re", pinyin_re_codepoints, 3},
+    {"ren", pinyin_ren_codepoints, 11},
+    {"reng", pinyin_reng_codepoints, 4},
+    {"ri", pinyin_ri_codepoints, 1},
+    {"rong", pinyin_rong_codepoints, 11},
+    {"rou", pinyin_rou_codepoints, 3},
+    {"ru", pinyin_ru_codepoints, 14},
+    {"ruan", pinyin_ruan_codepoints, 3},
+    {"rui", pinyin_rui_codepoints, 5},
+    {"run", pinyin_run_codepoints, 2},
+    {"ruo", pinyin_ruo_codepoints, 4},
+    {"sa", pinyin_sa_codepoints, 4},
+    {"sai", pinyin_sai_codepoints, 5},
+    {"san", pinyin_san_codepoints, 4},
+    {"sang", pinyin_sang_codepoints, 3},
+    {"sao", pinyin_sao_codepoints, 7},
+    {"se", pinyin_se_codepoints, 6},
+    {"sen", pinyin_sen_codepoints, 2},
+    {"seng", pinyin_seng_codepoints, 1},
+    {"sha", pinyin_sha_codepoints, 14},
+    {"shai", pinyin_shai_codepoints, 3},
+    {"shan", pinyin_shan_codepoints, 22},
+    {"shang", pinyin_shang_codepoints, 9},
+    {"shao", pinyin_shao_codepoints, 16},
+    {"she", pinyin_she_codepoints, 17},
+    {"shei", pinyin_shei_codepoints, 1},
+    {"shen", pinyin_shen_codepoints, 21},
+    {"sheng", pinyin_sheng_codepoints, 14},
+    {"shi", pinyin_shi_codepoints, 62},
+    {"shou", pinyin_shou_codepoints, 11},
+    {"shu", pinyin_shu_codepoints, 42},
+    {"shua", pinyin_shua_codepoints, 3},
+    {"shuai", pinyin_shuai_codepoints, 5},
+    {"shuan", pinyin_shuan_codepoints, 3},
+    {"shuang", pinyin_shuang_codepoints, 3},
+    {"shui", pinyin_shui_codepoints, 5},
+    {"shun", pinyin_shun_codepoints, 7},
+    {"shuo", pinyin_shuo_codepoints, 8},
+    {"si", pinyin_si_codepoints, 23},
+    {"song", pinyin_song_codepoints, 8},
+    {"sou", pinyin_sou_codepoints, 5},
+    {"su", pinyin_su_codepoints, 14},
+    {"suan", pinyin_suan_codepoints, 4},
+    {"sui", pinyin_sui_codepoints, 15},
+    {"sun", pinyin_sun_codepoints, 4},
+    {"suo", pinyin_suo_codepoints, 14},
+    {"ta", pinyin_ta_codepoints, 14},
+    {"tai", pinyin_tai_codepoints, 11},
+    {"tan", pinyin_tan_codepoints, 26},
+    {"tang", pinyin_tang_codepoints, 13},
+    {"tao", pinyin_tao_codepoints, 14},
+    {"te", pinyin_te_codepoints, 3},
+    {"teng", pinyin_teng_codepoints, 4},
+    {"ti", pinyin_ti_codepoints, 22},
+    {"tian", pinyin_tian_codepoints, 16},
+    {"tiao", pinyin_tiao_codepoints, 10},
+    {"tie", pinyin_tie_codepoints, 5},
+    {"ting", pinyin_ting_codepoints, 11},
+    {"tong", pinyin_tong_codepoints, 18},
+    {"tou", pinyin_tou_codepoints, 6},
+    {"tu", pinyin_tu_codepoints, 14},
+    {"tuan", pinyin_tuan_codepoints, 6},
+    {"tui", pinyin_tui_codepoints, 10},
+    {"tun", pinyin_tun_codepoints, 9},
+    {"tuo", pinyin_tuo_codepoints, 19},
+    {"wa", pinyin_wa_codepoints, 9},
+    {"wai", pinyin_wai_codepoints, 2},
+    {"wan", pinyin_wan_codepoints, 21},
+    {"wang", pinyin_wang_codepoints, 14},
+    {"wei", pinyin_wei_codepoints, 39},
+    {"wen", pinyin_wen_codepoints, 15},
+    {"weng", pinyin_weng_codepoints, 3},
+    {"wo", pinyin_wo_codepoints, 10},
+    {"wu", pinyin_wu_codepoints, 32},
+    {"xi", pinyin_xi_codepoints, 43},
+    {"xia", pinyin_xia_codepoints, 19},
+    {"xian", pinyin_xian_codepoints, 36},
+    {"xiang", pinyin_xiang_codepoints, 24},
+    {"xiao", pinyin_xiao_codepoints, 29},
+    {"xie", pinyin_xie_codepoints, 31},
+    {"xin", pinyin_xin_codepoints, 12},
+    {"xing", pinyin_xing_codepoints, 18},
+    {"xiong", pinyin_xiong_codepoints, 9},
+    {"xiu", pinyin_xiu_codepoints, 11},
+    {"xu", pinyin_xu_codepoints, 27},
+    {"xuan", pinyin_xuan_codepoints, 14},
+    {"xue", pinyin_xue_codepoints, 9},
+    {"xun", pinyin_xun_codepoints, 20},
+    {"ya", pinyin_ya_codepoints, 22},
+    {"yan", pinyin_yan_codepoints, 47},
+    {"yang", pinyin_yang_codepoints, 20},
+    {"yao", pinyin_yao_codepoints, 24},
+    {"ye", pinyin_ye_codepoints, 23},
+    {"yi", pinyin_yi_codepoints, 82},
+    {"yin", pinyin_yin_codepoints, 26},
+    {"ying", pinyin_ying_codepoints, 23},
+    {"yo", pinyin_yo_codepoints, 2},
+    {"yong", pinyin_yong_codepoints, 17},
+    {"you", pinyin_you_codepoints, 24},
+    {"yu", pinyin_yu_codepoints, 61},
+    {"yuan", pinyin_yuan_codepoints, 26},
+    {"yue", pinyin_yue_codepoints, 14},
+    {"yun", pinyin_yun_codepoints, 22},
+    {"za", pinyin_za_codepoints, 6},
+    {"zai", pinyin_zai_codepoints, 9},
+    {"zan", pinyin_zan_codepoints, 4},
+    {"zang", pinyin_zang_codepoints, 4},
+    {"zao", pinyin_zao_codepoints, 17},
+    {"ze", pinyin_ze_codepoints, 8},
+    {"zei", pinyin_zei_codepoints, 1},
+    {"zen", pinyin_zen_codepoints, 1},
+    {"zeng", pinyin_zeng_codepoints, 5},
+    {"zha", pinyin_zha_codepoints, 20},
+    {"zhai", pinyin_zhai_codepoints, 13},
+    {"zhan", pinyin_zhan_codepoints, 19},
+    {"zhang", pinyin_zhang_codepoints, 16},
+    {"zhao", pinyin_zhao_codepoints, 18},
+    {"zhe", pinyin_zhe_codepoints, 15},
+    {"zhei", pinyin_zhei_codepoints, 1},
+    {"zhen", pinyin_zhen_codepoints, 23},
+    {"zheng", pinyin_zheng_codepoints, 20},
+    {"zhi", pinyin_zhi_codepoints, 53},
+    {"zhong", pinyin_zhong_codepoints, 13},
+    {"zhou", pinyin_zhou_codepoints, 20},
+    {"zhu", pinyin_zhu_codepoints, 40},
+    {"zhua", pinyin_zhua_codepoints, 3},
+    {"zhuai", pinyin_zhuai_codepoints, 2},
+    {"zhuan", pinyin_zhuan_codepoints, 8},
+    {"zhuang", pinyin_zhuang_codepoints, 8},
+    {"zhui", pinyin_zhui_codepoints, 10},
+    {"zhun", pinyin_zhun_codepoints, 5},
+    {"zhuo", pinyin_zhuo_codepoints, 16},
+    {"zi", pinyin_zi_codepoints, 20},
+    {"zong", pinyin_zong_codepoints, 8},
+    {"zou", pinyin_zou_codepoints, 6},
+    {"zu", pinyin_zu_codepoints, 11},
+    {"zuan", pinyin_zuan_codepoints, 4},
+    {"zui", pinyin_zui_codepoints, 8},
+    {"zun", pinyin_zun_codepoints, 4},
+    {"zuo", pinyin_zuo_codepoints, 14}
+};
+
+#define PINYIN_DICT_SIZE (sizeof(pinyin_dict) / sizeof(pinyin_dict[0]))
+
+#endif /* PINYIN_DICT_H */

+ 432 - 0
components/pinyin/inc/valid_syllables.h

@@ -0,0 +1,432 @@
+/* Generated by syllable_list_generator.py */
+/* Valid Chinese pinyin syllables (without tone marks) */
+/* Sorted by frequency (character count) */
+#ifndef VALID_SYLLABLES_H
+#define VALID_SYLLABLES_H
+
+#include <stddef.h>
+
+/* 9-key input mapping */
+static const char* KEY_TO_LETTERS[9] = {
+    NULL,           // 0: unused
+    "abc",          // 1: ABC
+    "def",          // 2: DEF
+    "ghi",          // 3: GHI
+    "jkl",          // 4: JKL
+    "mno",          // 5: MNO
+    "pqrs",         // 6: PQRS
+    "tuv",          // 7: TUV
+    "wxyz"          // 8: WXYZ
+};
+
+static const char* valid_syllables[] = {
+    "yi",  // 82 chars
+    "ji",  // 70 chars
+    "shi",  // 62 chars
+    "yu",  // 61 chars
+    "qi",  // 56 chars
+    "fu",  // 55 chars
+    "zhi",  // 53 chars
+    "yan",  // 47 chars
+    "jian",  // 45 chars
+    "xi",  // 43 chars
+    "bo",  // 42 chars
+    "jie",  // 42 chars
+    "shu",  // 42 chars
+    "zhu",  // 40 chars
+    "ju",  // 39 chars
+    "wei",  // 39 chars
+    "bi",  // 37 chars
+    "li",  // 37 chars
+    "xian",  // 36 chars
+    "mo",  // 34 chars
+    "jiao",  // 33 chars
+    "wu",  // 32 chars
+    "xie",  // 31 chars
+    "he",  // 30 chars
+    "pi",  // 30 chars
+    "chi",  // 29 chars
+    "jing",  // 29 chars
+    "xiao",  // 29 chars
+    "di",  // 27 chars
+    "ge",  // 27 chars
+    "qian",  // 27 chars
+    "xu",  // 27 chars
+    "gu",  // 26 chars
+    "hu",  // 26 chars
+    "hui",  // 26 chars
+    "qiao",  // 26 chars
+    "tan",  // 26 chars
+    "yin",  // 26 chars
+    "yuan",  // 26 chars
+    "chu",  // 25 chars
+    "gui",  // 25 chars
+    "lu",  // 25 chars
+    "jia",  // 24 chars
+    "xiang",  // 24 chars
+    "yao",  // 24 chars
+    "you",  // 24 chars
+    "bao",  // 23 chars
+    "dan",  // 23 chars
+    "han",  // 23 chars
+    "jin",  // 23 chars
+    "si",  // 23 chars
+    "ye",  // 23 chars
+    "ying",  // 23 chars
+    "zhen",  // 23 chars
+    "cheng",  // 22 chars
+    "pu",  // 22 chars
+    "shan",  // 22 chars
+    "ti",  // 22 chars
+    "ya",  // 22 chars
+    "yun",  // 22 chars
+    "bei",  // 21 chars
+    "e",  // 21 chars
+    "mei",  // 21 chars
+    "peng",  // 21 chars
+    "shen",  // 21 chars
+    "wan",  // 21 chars
+    "ba",  // 20 chars
+    "duo",  // 20 chars
+    "mu",  // 20 chars
+    "xun",  // 20 chars
+    "yang",  // 20 chars
+    "zha",  // 20 chars
+    "zheng",  // 20 chars
+    "zhou",  // 20 chars
+    "zi",  // 20 chars
+    "chen",  // 19 chars
+    "ci",  // 19 chars
+    "dian",  // 19 chars
+    "fen",  // 19 chars
+    "feng",  // 19 chars
+    "gong",  // 19 chars
+    "ling",  // 19 chars
+    "luo",  // 19 chars
+    "pan",  // 19 chars
+    "tuo",  // 19 chars
+    "xia",  // 19 chars
+    "zhan",  // 19 chars
+    "ban",  // 18 chars
+    "du",  // 18 chars
+    "fan",  // 18 chars
+    "huan",  // 18 chars
+    "jiu",  // 18 chars
+    "jue",  // 18 chars
+    "qu",  // 18 chars
+    "tong",  // 18 chars
+    "xing",  // 18 chars
+    "zhao",  // 18 chars
+    "cha",  // 17 chars
+    "chang",  // 17 chars
+    "huang",  // 17 chars
+    "ke",  // 17 chars
+    "qing",  // 17 chars
+    "she",  // 17 chars
+    "yong",  // 17 chars
+    "zao",  // 17 chars
+    "ai",  // 16 chars
+    "gan",  // 16 chars
+    "lan",  // 16 chars
+    "lian",  // 16 chars
+    "liu",  // 16 chars
+    "lv",  // 16 chars
+    "mi",  // 16 chars
+    "shao",  // 16 chars
+    "tian",  // 16 chars
+    "zhang",  // 16 chars
+    "zhuo",  // 16 chars
+    "bu",  // 15 chars
+    "chan",  // 15 chars
+    "dai",  // 15 chars
+    "dao",  // 15 chars
+    "diao",  // 15 chars
+    "guan",  // 15 chars
+    "huo",  // 15 chars
+    "jiang",  // 15 chars
+    "jun",  // 15 chars
+    "mao",  // 15 chars
+    "po",  // 15 chars
+    "quan",  // 15 chars
+    "sui",  // 15 chars
+    "wen",  // 15 chars
+    "zhe",  // 15 chars
+    "bang",  // 14 chars
+    "fei",  // 14 chars
+    "lao",  // 14 chars
+    "liao",  // 14 chars
+    "ma",  // 14 chars
+    "pang",  // 14 chars
+    "ru",  // 14 chars
+    "sha",  // 14 chars
+    "sheng",  // 14 chars
+    "su",  // 14 chars
+    "suo",  // 14 chars
+    "ta",  // 14 chars
+    "tao",  // 14 chars
+    "tu",  // 14 chars
+    "wang",  // 14 chars
+    "xuan",  // 14 chars
+    "yue",  // 14 chars
+    "zuo",  // 14 chars
+    "an",  // 13 chars
+    "bai",  // 13 chars
+    "bian",  // 13 chars
+    "chou",  // 13 chars
+    "cui",  // 13 chars
+    "dong",  // 13 chars
+    "gang",  // 13 chars
+    "hao",  // 13 chars
+    "hua",  // 13 chars
+    "kuang",  // 13 chars
+    "kui",  // 13 chars
+    "liang",  // 13 chars
+    "lin",  // 13 chars
+    "pa",  // 13 chars
+    "pei",  // 13 chars
+    "ping",  // 13 chars
+    "tang",  // 13 chars
+    "zhai",  // 13 chars
+    "zhong",  // 13 chars
+    "beng",  // 12 chars
+    "bing",  // 12 chars
+    "chong",  // 12 chars
+    "die",  // 12 chars
+    "ding",  // 12 chars
+    "gao",  // 12 chars
+    "hong",  // 12 chars
+    "juan",  // 12 chars
+    "ku",  // 12 chars
+    "lei",  // 12 chars
+    "ni",  // 12 chars
+    "nie",  // 12 chars
+    "qin",  // 12 chars
+    "xin",  // 12 chars
+    "ao",  // 11 chars
+    "cai",  // 11 chars
+    "chao",  // 11 chars
+    "che",  // 11 chars
+    "dou",  // 11 chars
+    "fang",  // 11 chars
+    "gai",  // 11 chars
+    "geng",  // 11 chars
+    "gou",  // 11 chars
+    "kang",  // 11 chars
+    "man",  // 11 chars
+    "ning",  // 11 chars
+    "pao",  // 11 chars
+    "qiu",  // 11 chars
+    "que",  // 11 chars
+    "ren",  // 11 chars
+    "rong",  // 11 chars
+    "shou",  // 11 chars
+    "tai",  // 11 chars
+    "ting",  // 11 chars
+    "xiu",  // 11 chars
+    "zu",  // 11 chars
+    "bie",  // 10 chars
+    "cuo",  // 10 chars
+    "da",  // 10 chars
+    "dun",  // 10 chars
+    "fa",  // 10 chars
+    "guo",  // 10 chars
+    "hang",  // 10 chars
+    "long",  // 10 chars
+    "meng",  // 10 chars
+    "miao",  // 10 chars
+    "na",  // 10 chars
+    "nian",  // 10 chars
+    "nuo",  // 10 chars
+    "ou",  // 10 chars
+    "qiang",  // 10 chars
+    "qie",  // 10 chars
+    "tiao",  // 10 chars
+    "tui",  // 10 chars
+    "wo",  // 10 chars
+    "zhui",  // 10 chars
+    "deng",  // 9 chars
+    "hai",  // 9 chars
+    "hun",  // 9 chars
+    "kai",  // 9 chars
+    "kan",  // 9 chars
+    "la",  // 9 chars
+    "lie",  // 9 chars
+    "mian",  // 9 chars
+    "ming",  // 9 chars
+    "pai",  // 9 chars
+    "shang",  // 9 chars
+    "tun",  // 9 chars
+    "wa",  // 9 chars
+    "xiong",  // 9 chars
+    "xue",  // 9 chars
+    "zai",  // 9 chars
+    "can",  // 8 chars
+    "chuang",  // 8 chars
+    "cu",  // 8 chars
+    "er",  // 8 chars
+    "gua",  // 8 chars
+    "lang",  // 8 chars
+    "lou",  // 8 chars
+    "mai",  // 8 chars
+    "nai",  // 8 chars
+    "pian",  // 8 chars
+    "shuo",  // 8 chars
+    "song",  // 8 chars
+    "ze",  // 8 chars
+    "zhuan",  // 8 chars
+    "zhuang",  // 8 chars
+    "zong",  // 8 chars
+    "zui",  // 8 chars
+    "bin",  // 7 chars
+    "cao",  // 7 chars
+    "ce",  // 7 chars
+    "chuan",  // 7 chars
+    "chun",  // 7 chars
+    "chuo",  // 7 chars
+    "cong",  // 7 chars
+    "hou",  // 7 chars
+    "huai",  // 7 chars
+    "kuai",  // 7 chars
+    "lun",  // 7 chars
+    "min",  // 7 chars
+    "sao",  // 7 chars
+    "shun",  // 7 chars
+    "ben",  // 6 chars
+    "biao",  // 6 chars
+    "chai",  // 6 chars
+    "chui",  // 6 chars
+    "cou",  // 6 chars
+    "de",  // 6 chars
+    "duan",  // 6 chars
+    "dui",  // 6 chars
+    "ga",  // 6 chars
+    "heng",  // 6 chars
+    "kun",  // 6 chars
+    "luan",  // 6 chars
+    "mang",  // 6 chars
+    "piao",  // 6 chars
+    "pin",  // 6 chars
+    "se",  // 6 chars
+    "tou",  // 6 chars
+    "tuan",  // 6 chars
+    "za",  // 6 chars
+    "zou",  // 6 chars
+    "cang",  // 5 chars
+    "ceng",  // 5 chars
+    "cuan",  // 5 chars
+    "cun",  // 5 chars
+    "dang",  // 5 chars
+    "guang",  // 5 chars
+    "gun",  // 5 chars
+    "ha",  // 5 chars
+    "hen",  // 5 chars
+    "kao",  // 5 chars
+    "ken",  // 5 chars
+    "kong",  // 5 chars
+    "kou",  // 5 chars
+    "kua",  // 5 chars
+    "kuo",  // 5 chars
+    "mou",  // 5 chars
+    "nao",  // 5 chars
+    "nu",  // 5 chars
+    "pou",  // 5 chars
+    "qia",  // 5 chars
+    "rang",  // 5 chars
+    "rui",  // 5 chars
+    "sai",  // 5 chars
+    "shuai",  // 5 chars
+    "shui",  // 5 chars
+    "sou",  // 5 chars
+    "tie",  // 5 chars
+    "zeng",  // 5 chars
+    "zhun",  // 5 chars
+    "ang",  // 4 chars
+    "ka",  // 4 chars
+    "kuan",  // 4 chars
+    "le",  // 4 chars
+    "nan",  // 4 chars
+    "ne",  // 4 chars
+    "nei",  // 4 chars
+    "niu",  // 4 chars
+    "nong",  // 4 chars
+    "pen",  // 4 chars
+    "qun",  // 4 chars
+    "ran",  // 4 chars
+    "reng",  // 4 chars
+    "ruo",  // 4 chars
+    "sa",  // 4 chars
+    "san",  // 4 chars
+    "suan",  // 4 chars
+    "sun",  // 4 chars
+    "teng",  // 4 chars
+    "zan",  // 4 chars
+    "zang",  // 4 chars
+    "zuan",  // 4 chars
+    "zun",  // 4 chars
+    "a",  // 3 chars
+    "ca",  // 3 chars
+    "gen",  // 3 chars
+    "guai",  // 3 chars
+    "jiong",  // 3 chars
+    "lai",  // 3 chars
+    "leng",  // 3 chars
+    "lve",  // 3 chars
+    "me",  // 3 chars
+    "men",  // 3 chars
+    "neng",  // 3 chars
+    "niao",  // 3 chars
+    "pie",  // 3 chars
+    "qiong",  // 3 chars
+    "rao",  // 3 chars
+    "re",  // 3 chars
+    "rou",  // 3 chars
+    "ruan",  // 3 chars
+    "sang",  // 3 chars
+    "shai",  // 3 chars
+    "shua",  // 3 chars
+    "shuan",  // 3 chars
+    "shuang",  // 3 chars
+    "te",  // 3 chars
+    "weng",  // 3 chars
+    "zhua",  // 3 chars
+    "fou",  // 2 chars
+    "hei",  // 2 chars
+    "keng",  // 2 chars
+    "mie",  // 2 chars
+    "niang",  // 2 chars
+    "nv",  // 2 chars
+    "nve",  // 2 chars
+    "run",  // 2 chars
+    "sen",  // 2 chars
+    "wai",  // 2 chars
+    "yo",  // 2 chars
+    "zhuai",  // 2 chars
+    "cen",  // 1 chars
+    "chua",  // 1 chars
+    "chuai",  // 1 chars
+    "dei",  // 1 chars
+    "diu",  // 1 chars
+    "en",  // 1 chars
+    "fo",  // 1 chars
+    "gei",  // 1 chars
+    "hng",  // 1 chars
+    "kei",  // 1 chars
+    "lia",  // 1 chars
+    "lo",  // 1 chars
+    "miu",  // 1 chars
+    "nang",  // 1 chars
+    "nen",  // 1 chars
+    "nin",  // 1 chars
+    "nuan",  // 1 chars
+    "o",  // 1 chars
+    "ri",  // 1 chars
+    "seng",  // 1 chars
+    "shei",  // 1 chars
+    "zei",  // 1 chars
+    "zen",  // 1 chars
+    "zhei"  // 1 chars
+};
+
+#define VALID_SYLLABLES_SIZE (sizeof(valid_syllables) / sizeof(valid_syllables[0]))
+
+#endif /* VALID_SYLLABLES_H */

+ 354 - 0
components/pinyin/src/luat_pinyin.c

@@ -0,0 +1,354 @@
+/*
+ * pinyin库核心实现
+ */
+
+#include "luat_base.h"
+#include "luat_pinyin.h"
+#include "pinyin_dict.h"
+#include "valid_syllables.h"
+#include <string.h>
+
+#define LUAT_LOG_TAG "pinyin"
+#include "luat_log.h"
+
+/**
+ * @brief 二分查找拼音条目(数组已按拼音排序)
+ * @param pinyin 拼音字符串
+ * @return 找到返回条目指针,未找到返回NULL
+ */
+static const pinyin_entry_t *find_pinyin_entry(const char *pinyin)
+{
+    if (!pinyin || !*pinyin) {
+        return NULL;
+    }
+    
+    int left = 0;
+    int right = PINYIN_DICT_SIZE - 1;
+    
+    while (left <= right) {
+        int mid = (left + right) / 2;
+        int cmp = strcmp(pinyin_dict[mid].pinyin, pinyin);
+        
+        if (cmp == 0) {
+            return &pinyin_dict[mid];
+        } else if (cmp < 0) {
+            left = mid + 1;
+        } else {
+            right = mid - 1;
+        }
+    }
+    
+    return NULL;  // 未找到
+}
+
+/**
+ * @brief 初始化pinyin库(预留接口)
+ */
+int luat_pinyin_init(void)
+{
+    // 当前无需初始化,数据是静态的
+    return 0;
+}
+
+/**
+ * @brief 将Unicode码点转换为UTF-8字符串
+ * @param codepoint Unicode码点
+ * @param utf8_buf 输出缓冲区(至少5字节)
+ * @return UTF-8字节数,失败返回0
+ */
+int luat_pinyin_codepoint_to_utf8(uint32_t codepoint, char *utf8_buf)
+{
+    if (!utf8_buf) {
+        return 0;
+    }
+    
+    if (codepoint <= 0x7F) {
+        // 1字节:0xxxxxxx
+        utf8_buf[0] = (char)codepoint;
+        utf8_buf[1] = '\0';
+        return 1;
+    } else if (codepoint <= 0x7FF) {
+        // 2字节:110xxxxx 10xxxxxx
+        utf8_buf[0] = (char)(0xC0 | (codepoint >> 6));
+        utf8_buf[1] = (char)(0x80 | (codepoint & 0x3F));
+        utf8_buf[2] = '\0';
+        return 2;
+    } else if (codepoint <= 0xFFFF) {
+        // 3字节:1110xxxx 10xxxxxx 10xxxxxx
+        utf8_buf[0] = (char)(0xE0 | (codepoint >> 12));
+        utf8_buf[1] = (char)(0x80 | ((codepoint >> 6) & 0x3F));
+        utf8_buf[2] = (char)(0x80 | (codepoint & 0x3F));
+        utf8_buf[3] = '\0';
+        return 3;
+    } else if (codepoint <= 0x10FFFF) {
+        // 4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+        utf8_buf[0] = (char)(0xF0 | (codepoint >> 18));
+        utf8_buf[1] = (char)(0x80 | ((codepoint >> 12) & 0x3F));
+        utf8_buf[2] = (char)(0x80 | ((codepoint >> 6) & 0x3F));
+        utf8_buf[3] = (char)(0x80 | (codepoint & 0x3F));
+        utf8_buf[4] = '\0';
+        return 4;
+    }
+    
+    return 0;  // 无效的码点
+}
+
+/**
+ * @brief 查询拼音对应的候选字Unicode码点数组
+ */
+int luat_pinyin_query(const char *pinyin, const uint32_t **codepoints, uint16_t *count)
+{
+    if (!pinyin || !codepoints || !count) {
+        return -1;
+    }
+    
+    const pinyin_entry_t *entry = find_pinyin_entry(pinyin);
+    if (!entry) {
+        *codepoints = NULL;
+        *count = 0;
+        return -1;
+    }
+    
+    *codepoints = entry->codepoints;
+    *count = entry->count;
+    return 0;
+}
+
+/**
+ * @brief 查询拼音对应的候选字UTF-8字符串数组
+ * @param pinyin 拼音字符串(小写,无声调)
+ * @param utf8_strings 输出参数:UTF-8字符串数组(需要调用者分配内存)
+ * @param max_count 最大字符串数量(数组大小)
+ * @param count 输出参数:实际返回的字符串数量
+ * @return 0表示成功,-1表示失败
+ * 
+ * 注意:调用者需要分配足够的内存来存储UTF-8字符串。
+ * 每个字符串最多4字节UTF-8编码 + 1字节'\0' = 5字节
+ * 建议分配: char utf8_strings[max_count][5]
+ */
+int luat_pinyin_query_utf8(const char *pinyin, char (*utf8_strings)[5], uint16_t max_count, uint16_t *count)
+{
+    if (!pinyin || !utf8_strings || !count || max_count == 0) {
+        return -1;
+    }
+    
+    const uint32_t *codepoints = NULL;
+    uint16_t codepoint_count = 0;
+    
+    int ret = luat_pinyin_query(pinyin, &codepoints, &codepoint_count);
+    if (ret != 0 || !codepoints || codepoint_count == 0) {
+        *count = 0;
+        return -1;
+    }
+    
+    // 转换码点为UTF-8字符串
+    uint16_t actual_count = (codepoint_count < max_count) ? codepoint_count : max_count;
+    for (uint16_t i = 0; i < actual_count; i++) {
+        luat_pinyin_codepoint_to_utf8(codepoints[i], utf8_strings[i]);
+    }
+    
+    *count = actual_count;
+    return 0;
+}
+
+/**
+ * @brief 检查字符串是否在valid_syllables数组中(线性查找)
+ * @param syllable 要查找的音节字符串
+ * @return 如果找到返回1,否则返回0
+ * 
+ * 注意:valid_syllables数组是按常用度排序的,不是按字母顺序,
+ * 因此不能使用二分查找,必须使用线性查找
+ */
+static int is_valid_syllable(const char *syllable)
+{
+    if (!syllable || !*syllable) {
+        return 0;
+    }
+    
+    // 线性查找(因为valid_syllables按常用度排序,不是按字母顺序)
+    for (int i = 0; i < VALID_SYLLABLES_SIZE; i++) {
+        if (strcmp(valid_syllables[i], syllable) == 0) {
+            return 1;  // 找到
+        }
+    }
+    
+    return 0;  // 未找到
+}
+
+/**
+ * @brief 递归枚举所有可能的字母组合
+ * @param key_sequence 按键序列
+ * @param key_count 按键序列长度
+ * @param depth 当前深度(递归参数)
+ * @param buffer 当前组合缓冲区
+ * @param buffer_pos 缓冲区当前位置
+ * @param syllables 输出音节数组
+ * @param syllable_count 当前音节数量(输入输出参数)
+ * @param max_syllable_count 最大音节数量
+ */
+static void enumerate_combinations(
+    const uint8_t *key_sequence,
+    uint8_t key_count,
+    uint8_t depth,
+    char *buffer,
+    uint8_t buffer_pos,
+    char (*syllables)[8],
+    uint16_t *syllable_count,
+    uint16_t max_syllable_count
+)
+{
+    // 如果已经达到最大音节数量,停止枚举
+    if (*syllable_count >= max_syllable_count) {
+        return;
+    }
+    
+    // 如果已经处理完所有按键
+    if (depth >= key_count) {
+        if (buffer_pos > 0) {
+            // 检查当前组合是否是合法音节
+            buffer[buffer_pos] = '\0';
+            if (is_valid_syllable(buffer)) {
+                // 检查是否已存在(避免重复)
+                int found = 0;
+                for (uint16_t i = 0; i < *syllable_count; i++) {
+                    if (strcmp(syllables[i], buffer) == 0) {
+                        found = 1;
+                        break;
+                    }
+                }
+                if (!found) {
+                    strncpy(syllables[*syllable_count], buffer, 7);
+                    syllables[*syllable_count][7] = '\0';
+                    (*syllable_count)++;
+                }
+            }
+        }
+        return;
+    }
+    
+    // 获取当前按键对应的字母串
+    uint8_t key_id = key_sequence[depth];
+    if (key_id < 1 || key_id > 8) {
+        return;  // 无效按键ID
+    }
+    
+    const char *letters = KEY_TO_LETTERS[key_id];
+    if (!letters) {
+        return;
+    }
+    
+    // 枚举当前按键对应的所有字母
+    for (const char *p = letters; *p != '\0'; p++) {
+        // 缓冲区空间检查(最多7个字母)
+        if (buffer_pos >= 7) {
+            continue;
+        }
+        
+        buffer[buffer_pos] = *p;
+        
+        // 递归处理下一个按键
+        enumerate_combinations(
+            key_sequence,
+            key_count,
+            depth + 1,
+            buffer,
+            buffer_pos + 1,
+            syllables,
+            syllable_count,
+            max_syllable_count
+        );
+    }
+}
+
+/**
+ * @brief 根据按键序列查询可能的音节列表(9键输入法)
+ */
+int luat_pinyin_query_syllables_by_keys(
+    const uint8_t *key_sequence, 
+    uint8_t key_count,
+    char (*syllables)[8],
+    uint16_t max_syllable_count,
+    uint16_t *actual_count
+)
+{
+    if (!key_sequence || !syllables || !actual_count || max_syllable_count == 0) {
+        return -1;
+    }
+    
+    // 限制按键序列最大长度为5
+    if (key_count == 0 || key_count > 5) {
+        *actual_count = 0;
+        return -1;
+    }
+    
+    // 验证按键ID有效性
+    for (uint8_t i = 0; i < key_count; i++) {
+        if (key_sequence[i] < 1 || key_sequence[i] > 8) {
+            *actual_count = 0;
+            return -1;
+        }
+    }
+    
+    // 初始化输出
+    *actual_count = 0;
+    
+    // 枚举所有可能的字母组合
+    char buffer[8] = {0};  // 临时缓冲区(最多7个字母+'\0')
+    enumerate_combinations(
+        key_sequence,
+        key_count,
+        0,
+        buffer,
+        0,
+        syllables,
+        actual_count,
+        max_syllable_count
+    );
+    
+    // 按valid_syllables数组中的顺序排序结果(常用度排序)
+    // 先构建索引映射,然后使用简单排序
+    if (*actual_count > 1) {
+        // 为每个匹配的音节查找索引
+        int16_t indices[100];  // 假设最多100个音节
+        if (*actual_count <= 100) {
+            for (uint16_t i = 0; i < *actual_count; i++) {
+                indices[i] = -1;
+                // 二分查找索引
+                int left = 0;
+                int right = VALID_SYLLABLES_SIZE - 1;
+                while (left <= right) {
+                    int mid = (left + right) / 2;
+                    int cmp = strcmp(valid_syllables[mid], syllables[i]);
+                    if (cmp == 0) {
+                        indices[i] = mid;
+                        break;
+                    } else if (cmp < 0) {
+                        left = mid + 1;
+                    } else {
+                        right = mid - 1;
+                    }
+                }
+            }
+            
+            // 使用简单冒泡排序按索引排序
+            for (uint16_t i = 0; i < *actual_count - 1; i++) {
+                for (uint16_t j = 0; j < *actual_count - 1 - i; j++) {
+                    if (indices[j] > indices[j + 1] && indices[j] >= 0 && indices[j + 1] >= 0) {
+                        // 交换索引
+                        int16_t temp_idx = indices[j];
+                        indices[j] = indices[j + 1];
+                        indices[j + 1] = temp_idx;
+                        // 交换音节
+                        char temp[8];
+                        strncpy(temp, syllables[j], 8);
+                        strncpy(syllables[j], syllables[j + 1], 8);
+                        strncpy(syllables[j + 1], temp, 8);
+                    }
+                }
+            }
+        }
+    }
+    
+    return 0;
+}
+

+ 1 - 0
luat/include/luat_libs.h

@@ -85,6 +85,7 @@ LUAMOD_API int luaopen_ir( lua_State *L );
 LUAMOD_API int luaopen_lcd( lua_State *L );
 LUAMOD_API int luaopen_tp( lua_State *L );
 LUAMOD_API int luaopen_lwip( lua_State *L );
+LUAMOD_API int luaopen_pinyin( lua_State *L );
 
 LUAMOD_API int luaopen_wdt( lua_State *L );
 LUAMOD_API int luaopen_mcu( lua_State *L );