/** * Generate zh-TW / ja / ko locale files from zh-CN.json and en.json * Run: node scripts/gen-locales.js */ const fs = require('fs') const path = require('path') const zhCN = JSON.parse(fs.readFileSync(path.join(__dirname, '../src/locales/zh-CN.json'), 'utf8')) const en = JSON.parse(fs.readFileSync(path.join(__dirname, '../src/locales/en.json'), 'utf8')) // ========== Simplified → Traditional Chinese mapping ========== // Covers common UI characters; context-dependent chars handled via phrase table first const PHRASE_MAP = { '里面': '裡面', '里程': '裡程', '这里': '這裡', '哪里': '哪裡', '复制': '複製', '恢复': '恢復', '重复': '重複', '回复': '回覆', '头发': '頭髮', '发送': '發送', '发现': '發現', '发布': '發佈', '发起': '發起', '发生': '發生', '发出': '發出', '触发': '觸發', '信息': '資訊', '系统': '系統', '干预': '干預', '面板': '面板', '仪表盘': '儀表盤', '仪表板': '儀表板', '只读': '唯讀', '默认': '預設', '并发': '並行', '并且': '並且', '采集': '採集', '采用': '採用', '准确': '準確', '准备': '準備', '标准': '標準', '获取': '取得', '获得': '取得', '运行': '執行', '运营': '營運', '运输': '運輸', '模拟': '模擬', '类型': '類型', '历史': '歷史', '日历': '日曆', '存储': '儲存', '内存': '記憶體', '鼠标': '滑鼠', '光标': '游標', '网络': '網路', '联网': '聯網', '视频': '影片', '音频': '音訊', '软件': '軟體', '硬件': '硬體', '程序': '程式', '应用程序': '應用程式', '文件': '檔案', '文件夹': '資料夾', '数据': '資料', '数据库': '資料庫', '用户': '使用者', '客户端': '用戶端', '服务器': '伺服器', '服务端': '伺服端', '日志': '日誌', '博客': '部落格', '功能': '功能', '智能': '智慧', '支持': '支援', '支持的': '支援的', '响应': '回應', '优先': '優先', '优化': '最佳化', '后台': '後台', '后端': '後端', '后续': '後續', '之后': '之後', '然后': '然後', '最后': '最後', '前台': '前台', '前端': '前端', '拖拽': '拖曳', '链接': '連結', '字节': '位元組', '适配': '適配', '兼容': '相容', '注册': '註冊', '登录': '登入', '退出登录': '登出', '下载': '下載', '上传': '上傳', '启动': '啟動', '激活': '啟用', '调试': '除錯', '调用': '呼叫', '确认': '確認', '确定': '確定', '扩展': '擴充', '插件': '外掛', '渠道': '頻道', '频道': '頻道', '任务': '任務', '计划': '計畫', '定时': '定時', '签名': '簽章', '令牌': '權杖', '权限': '權限', '授权': '授權', '工具': '工具', '终端': '終端', '实例': '執行個體', '进程': '處理程序', '消息': '訊息', '通知': '通知', '正在': '正在', '成功': '成功', '失败': '失敗', '警告': '警告', '错误': '錯誤', '异常': '異常', '加载': '載入', '刷新': '重新整理', '编辑': '編輯', '删除': '刪除', '创建': '建立', '修改': '修改', '更新': '更新', '添加': '新增', '搜索': '搜尋', '查找': '尋找', '过滤': '篩選', '筛选': '篩選', '排序': '排序', '升序': '升冪', '降序': '降冪', '备份': '備份', '还原': '還原', '配置': '設定', '设置': '設定', '选项': '選項', '参数': '參數', '属性': '屬性', '代理': '代理', '网关': '閘道器', '密码': '密碼', '密钥': '金鑰', '地址': '位址', '端口': '連接埠', '状态': '狀態', '在线': '線上', '离线': '離線', '连接': '連線', '断开': '斷開', '超时': '逾時', '请求': '請求', '接口': '介面', '缓存': '快取', '队列': '佇列', '全局': '全域', '局部': '區域', '模型': '模型', '会话': '對話', '对话': '對話', '提示词': '提示詞', '提示': '提示', '回答': '回答', '问题': '問題', '输入': '輸入', '输出': '輸出', '复选': '核取', '单选': '單選', '勾选': '勾選', '折叠': '摺疊', '展开': '展開', '上限': '上限', '下限': '下限', '升级': '升級', '降级': '降級', '安装': '安裝', '卸载': '解除安裝', '绑定': '綁定', '解绑': '解除綁定', '拦截': '攔截', '转发': '轉發', '遥测': '遙測', '监控': '監控', '格式': '格式', '模板': '範本', '变量': '變數', '常量': '常數', '关闭': '關閉', '打开': '開啟', '隐藏': '隱藏', '显示': '顯示', '禁用': '停用', '启用': '啟用', '允许': '允許', '拒绝': '拒絕', '取消': '取消', '保存': '儲存', '重试': '重試', '跳过': '略過', '已知': '已知', '未知': '未知', '手动': '手動', '自动': '自動', '已完成': '已完成', '进行中': '進行中', '待处理': '待處理', '暂无': '暫無', '暂停': '暫停', '粘贴': '貼上', '剪切': '剪下', '选择': '選擇', '当前': '目前', '已选': '已選', '全选': '全選', '最近': '最近', '最新': '最新', '详情': '詳情', '详细': '詳細', '简介': '簡介', '描述': '描述', '名称': '名稱', '标题': '標題', '标签': '標籤', '注意': '注意', '说明': '說明', '总量': '總量', '总计': '總計', '费用': '費用', '价格': '價格', '文档': '文件', '记忆': '記憶', '记录': '紀錄', '独立': '獨立', '共享': '共用', '工作区': '工作區', '无限制': '無限制', '已停止': '已停止', '运行中': '執行中', '挂载': '掛載', '卸载': '卸載', } // Single character fallback mapping (only applied after phrase mapping) const CHAR_MAP = { '与': '與', '万': '萬', '专': '專', '业': '業', '丢': '丟', '两': '兩', '严': '嚴', '个': '個', '丰': '豐', '临': '臨', '为': '為', '举': '舉', '义': '義', '乐': '樂', '习': '習', '书': '書', '买': '買', '乱': '亂', '争': '爭', '于': '於', '亏': '虧', '云': '雲', '亚': '亞', '产': '產', '亲': '親', '仅': '僅', '从': '從', '仓': '倉', '们': '們', '价': '價', '众': '眾', '优': '優', '会': '會', '伟': '偉', '传': '傳', '伤': '傷', '体': '體', '佣': '傭', '余': '餘', '侠': '俠', '侧': '側', '侦': '偵', '债': '債', '值': '值', '偿': '償', '像': '像', '允': '允', '兆': '兆', '党': '黨', '兰': '蘭', '关': '關', '兴': '興', '养': '養', '内': '內', '冲': '沖', '决': '決', '况': '況', '净': '淨', '准': '準', '凑': '湊', '减': '減', '几': '幾', '凭': '憑', '出': '出', '击': '擊', '划': '劃', '创': '創', '别': '別', '刘': '劉', '则': '則', '刚': '剛', '剂': '劑', '剧': '劇', '剩': '剩', '劝': '勸', '办': '辦', '动': '動', '务': '務', '劳': '勞', '势': '勢', '勋': '勳', '匀': '勻', '区': '區', '医': '醫', '华': '華', '单': '單', '卖': '賣', '占': '佔', '卫': '衛', '厂': '廠', '厅': '廳', '历': '歷', '压': '壓', '厉': '厲', '县': '縣', '参': '參', '双': '雙', '发': '發', '变': '變', '叙': '敘', '叶': '葉', '号': '號', '叹': '嘆', '吓': '嚇', '吕': '呂', '听': '聽', '启': '啟', '呐': '吶', '员': '員', '响': '響', '哑': '啞', '唤': '喚', '啬': '嗇', '团': '團', '园': '園', '围': '圍', '国': '國', '图': '圖', '圣': '聖', '场': '場', '块': '塊', '坏': '壞', '坚': '堅', '坛': '壇', '垒': '壘', '垄': '壟', '型': '型', '域': '域', '堕': '墮', '塑': '塑', '墙': '牆', '壮': '壯', '声': '聲', '处': '處', '备': '備', '够': '夠', '头': '頭', '夹': '夾', '夺': '奪', '奋': '奮', '奖': '獎', '奥': '奧', '妇': '婦', '妈': '媽', '娱': '娛', '孙': '孫', '学': '學', '宝': '寶', '实': '實', '宠': '寵', '审': '審', '宪': '憲', '宽': '寬', '将': '將', '尔': '爾', '尘': '塵', '层': '層', '岁': '歲', '岂': '豈', '岛': '島', '岭': '嶺', '岸': '岸', '币': '幣', '帅': '帥', '师': '師', '帐': '帳', '帜': '幟', '带': '帶', '帮': '幫', '干': '乾', '并': '並', '广': '廣', '庄': '莊', '庆': '慶', '库': '庫', '应': '應', '废': '廢', '开': '開', '异': '異', '弃': '棄', '张': '張', '弹': '彈', '归': '歸', '当': '當', '录': '錄', '彻': '徹', '径': '徑', '态': '態', '怀': '懷', '总': '總', '恶': '惡', '恼': '惱', '悬': '懸', '惊': '驚', '惧': '懼', '惩': '懲', '惯': '慣', '愤': '憤', '慎': '慎', '懒': '懶', '戏': '戲', '战': '戰', '户': '戶', '执': '執', '扩': '擴', '扫': '掃', '扬': '揚', '扰': '擾', '抚': '撫', '抛': '拋', '担': '擔', '拟': '擬', '拥': '擁', '择': '擇', '挂': '掛', '挡': '擋', '挤': '擠', '挥': '揮', '损': '損', '换': '換', '据': '據', '掷': '擲', '描': '描', '摄': '攝', '摆': '擺', '摇': '搖', '操': '操', '撑': '撐', '撤': '撤', '播': '播', '擅': '擅', '数': '數', '整': '整', '斗': '鬥', '斩': '斬', '断': '斷', '无': '無', '旧': '舊', '时': '時', '昼': '晝', '显': '顯', '晋': '晉', '晒': '曬', '术': '術', '机': '機', '权': '權', '杀': '殺', '杂': '雜', '条': '條', '来': '來', '极': '極', '构': '構', '柜': '櫃', '标': '標', '栈': '棧', '样': '樣', '检': '檢', '楼': '樓', '榄': '欖', '横': '橫', '档': '檔', '桥': '橋', '梦': '夢', '毁': '毀', '殇': '殤', '残': '殘', '毕': '畢', '汇': '匯', '汉': '漢', '污': '汙', '汤': '湯', '沟': '溝', '没': '沒', '泪': '淚', '浅': '淺', '测': '測', '济': '濟', '浏': '瀏', '涌': '湧', '涛': '濤', '润': '潤', '涨': '漲', '淀': '澱', '渐': '漸', '渠': '渠', '温': '溫', '湾': '灣', '滞': '滯', '满': '滿', '滤': '濾', '潜': '潛', '灭': '滅', '灵': '靈', '灿': '燦', '烂': '爛', '烛': '燭', '烦': '煩', '烧': '燒', '热': '熱', '犹': '猶', '独': '獨', '狭': '狹', '猎': '獵', '猪': '豬', '献': '獻', '玩': '玩', '环': '環', '现': '現', '珍': '珍', '瓶': '瓶', '电': '電', '画': '畫', '畅': '暢', '疗': '療', '症': '症', '盘': '盤', '盖': '蓋', '监': '監', '盐': '鹽', '目': '目', '码': '碼', '础': '礎', '确': '確', '碍': '礙', '禅': '禪', '离': '離', '种': '種', '积': '積', '称': '稱', '稳': '穩', '穷': '窮', '窃': '竊', '窜': '竄', '窝': '窩', '竞': '競', '笔': '筆', '签': '簽', '简': '簡', '算': '算', '类': '類', '粮': '糧', '紧': '緊', '纠': '糾', '纤': '纖', '红': '紅', '纯': '純', '纲': '綱', '纳': '納', '纵': '縱', '纷': '紛', '纸': '紙', '线': '線', '组': '組', '细': '細', '织': '織', '终': '終', '绍': '紹', '经': '經', '结': '結', '绑': '綁', '绕': '繞', '统': '統', '继': '繼', '绩': '績', '绪': '緒', '续': '續', '综': '綜', '缓': '緩', '编': '編', '缘': '緣', '缝': '縫', '缩': '縮', '缴': '繳', '网': '網', '罗': '羅', '罚': '罰', '翻': '翻', '耻': '恥', '联': '聯', '肃': '肅', '肤': '膚', '胀': '脹', '胁': '脅', '脉': '脈', '脑': '腦', '脸': '臉', '腊': '臘', '舆': '輿', '舰': '艦', '艰': '艱', '节': '節', '芦': '蘆', '苹': '蘋', '范': '範', '荐': '薦', '药': '藥', '获': '獲', '虑': '慮', '虚': '虛', '虽': '雖', '蚕': '蠶', '蛮': '蠻', '蝇': '蠅', '补': '補', '衬': '襯', '袜': '襪', '装': '裝', '规': '規', '觉': '覺', '览': '覽', '观': '觀', '角': '角', '解': '解', '触': '觸', '言': '言', '计': '計', '订': '訂', '认': '認', '讨': '討', '让': '讓', '议': '議', '讯': '訊', '记': '記', '讲': '講', '许': '許', '论': '論', '设': '設', '访': '訪', '证': '證', '评': '評', '识': '識', '词': '詞', '试': '試', '话': '話', '该': '該', '详': '詳', '语': '語', '误': '誤', '说': '說', '请': '請', '诸': '諸', '读': '讀', '课': '課', '调': '調', '谁': '誰', '谈': '談', '谢': '謝', '谱': '譜', '贝': '貝', '负': '負', '贡': '貢', '财': '財', '责': '責', '质': '質', '贴': '貼', '费': '費', '资': '資', '赋': '賦', '赏': '賞', '赛': '賽', '赞': '贊', '趋': '趨', '跃': '躍', '践': '踐', '转': '轉', '轨': '軌', '载': '載', '较': '較', '辅': '輔', '辑': '輯', '输': '輸', '辩': '辯', '边': '邊', '达': '達', '过': '過', '迁': '遷', '运': '運', '进': '進', '远': '遠', '违': '違', '连': '連', '迟': '遲', '适': '適', '选': '選', '逻': '邏', '遗': '遺', '邮': '郵', '郑': '鄭', '释': '釋', '钉': '釘', '钟': '鐘', '钥': '鑰', '钮': '鈕', '链': '鏈', '锁': '鎖', '锐': '銳', '错': '錯', '键': '鍵', '锻': '鍛', '镇': '鎮', '镜': '鏡', '长': '長', '门': '門', '闭': '閉', '问': '問', '闲': '閒', '间': '間', '阅': '閱', '阶': '階', '际': '際', '陆': '陸', '险': '險', '随': '隨', '隐': '隱', '障': '障', '难': '難', '集': '集', '雾': '霧', '需': '需', '静': '靜', '页': '頁', '顶': '頂', '项': '項', '须': '須', '预': '預', '频': '頻', '题': '題', '颜': '顏', '风': '風', '飞': '飛', '驱': '驅', '验': '驗', '骤': '驟', '鸡': '雞', '鸣': '鳴', '鹏': '鵬', '龄': '齡', '龙': '龍', } function s2t(text) { if (typeof text !== 'string') return text // Apply phrase mapping first (longer matches first) const phrases = Object.keys(PHRASE_MAP).sort((a, b) => b.length - a.length) let result = text for (const phrase of phrases) { result = result.split(phrase).join(PHRASE_MAP[phrase]) } // Then apply single character mapping let out = '' for (const ch of result) { out += CHAR_MAP[ch] || ch } return out } function transformValues(obj, fn) { const result = {} for (const [k, v] of Object.entries(obj)) { if (typeof v === 'string') { result[k] = fn(v) } else if (typeof v === 'object' && v !== null) { result[k] = transformValues(v, fn) } else { result[k] = v } } return result } // Generate zh-TW const zhTW = transformValues(zhCN, s2t) fs.writeFileSync( path.join(__dirname, '../src/locales/zh-TW.json'), JSON.stringify(zhTW, null, 2) + '\n', 'utf8' ) console.log('✓ zh-TW.json generated') // Verify const parsed = JSON.parse(fs.readFileSync(path.join(__dirname, '../src/locales/zh-TW.json'), 'utf8')) function countKeys(o) { let n = 0; for (const v of Object.values(o)) { if (typeof v === 'string') n++; else if (typeof v === 'object') n += countKeys(v) } return n } console.log(` ${countKeys(parsed)} keys`)