# OMNX Chain 区块浏览器 · 多语言（i18n）说明

> 版本：v1｜日期：2026-09-16｜适用：`node/explorer.html`、`node/demo.html`、`OMNX公链浏览器-离线版（双击打开）.html`
> 边界：**只做追加**。原页面布局、蓝色主题、按钮位置、表格结构、原有 `<style>` 与脚本一行未改。

## 1. 支持语言（8 种）

| 顺序 | 代码 | 语言 | 说明 |
|---|---|---|---|
| 1 | `en` | English | **主语言 / 默认**。无法识别浏览器语言、或识别到清单外语言时，一律回落到英语 |
| 2 | `zh-TW` | 繁體中文 | 中国台湾地区用语 |
| 3 | `vi` | Tiếng Việt | 越南语 |
| 4 | `fr` | Français | 法语 |
| 5 | `hi` | हिन्दी | 印地语（印度） |
| 6 | `ko` | 한국어 | 韩语 |
| 7 | `ja` | 日本語 | 日语 |
| 8 | `th` | ไทย | 泰语 |

繁体中文（`zh-TW`）**按台湾地区用词**翻译（例：区块→區塊、合约→合約、地址→地址、代币→代幣）。
简体中文不在本次清单内：页面源语言本身是简体中文，若后续要把「简体中文」也放进下拉框，改 1 行即可（见 §6）。

## 2. 语言如何被选中（优先级从高到低）

1. **URL 参数**：`index.html?lang=vi`（临时指定，不写记忆）
2. **本机记忆**：`localStorage["omnx_lang"]`（用户上次在下拉框手动选过的语言）
3. **浏览器语言**：`navigator.languages[0]` / `navigator.language`
   - `zh-TW / zh-HK / zh-Hant / zh-MO` → `zh-TW`
   - `vi* / fr* / hi* / ko* / ja* / th*` → 对应语言
   - 其它（含 `zh-CN`、`de-DE` 等）→ **`en`**
4. 兜底：**`en`**

## 3. 用户怎么切换

页面右上角（原顶部栏 `<header>` 末端）新增一个语言下拉框，样式沿用原页面的 `var(--card)` / `var(--line)` / `var(--muted)`
变量与 20px 圆角，**不新增配色、不改原按钮**。切换后：

- 立即重绘全文，无需刷新；
- 写入 `localStorage`，下次打开保持；
- 同步更新 `<html lang="...">`，便于浏览器翻译/朗读。

## 4. 动态内容如何跟进

概览页的「最新区块」表格每 3 秒刷新一次，属于运行时新建节点。注入的 i18n 引擎用
`MutationObserver` 监听 `childList / characterData / attributes`，对新增节点做**增量翻译**，
并让 `requestAnimationFrame` 合并同一拍的多次变更，避免每 3 秒全页重扫。

引擎内部用 `WeakMap` 保存**节点的中文原文**，因此：

- 反复切换语言，中文源串不会丢失（英→繁→越→法→印→韩→日→泰→英，英文渲染逐字节一致）；
- 引擎自己写回的译文不会被误判为「外部改动」而二次翻译。

## 5. 词条与翻译引擎

| 文件 | 作用 |
|---|---|
| `deploy/i18n/cn-keys.json` | 从 3 个页面抽取的中文词条元数据（键、出现次数、所在区块） |
| `deploy/i18n/dict.json` | **主词典**：557 条词条 × 8 语言。值数组顺序固定为 `[en, zh-TW, vi, fr, hi, ko, ja, th]` |
| `deploy/i18n/inject.py` | 注入器：把引擎 + 词典追加到页面 `</body>` 前（幂等，可重复运行） |
| `deploy/i18n/backup/*.orig` | 3 个页面的**改动前原版备份**，用于随时剥离还原 |

翻译算法为**单遍最长匹配**：从左到右扫描文本，在当前位置取能匹配到的**最长**词条，
命中即输出译文并跳过该段，否则原样输出 1 个字符。这样译文不会再被当作输入二次替换——
早期版本用「全局最长优先替换」，日文会出现「合成资产取引」被吃成「合成資産引」这类掉字，
现已修正；改为单遍后，除日文外的 7 种语言输出与修正前逐字节一致。

## 6. 如何增删语言 / 修改译文

- **改译文**：直接改 `deploy/i18n/dict.json` 里该词条对应位置的值，然后执行
  `python3 deploy/i18n/inject.py`，重新打开页面即可。**不要**改数组长度。
- **加语言**：在 `inject.py` 的 `LANGS` 列表加一项，并给 `dict.json` 每条词条补一个值
  （8 → 9），同时把 `tr()` 的索引对齐。加「简体中文」选项时，把默认值设为原中文串即可。
- **还原成改动前的单语言页面**：用 `deploy/i18n/backup/*.orig` 覆盖同名文件；
  或用正则剥离页面里 `<!-- ==== OMNX Chain i18n ==== -->` 到 `<!-- /OMNX Chain i18n -->` 之间的整块。

## 7. 验收结果（2026-09-16）

| 项目 | 结果 |
|---|---|
| 纯追加 | 3 个页面剥离注入块后与改动前原文**逐字节相同** ✅ |
| 幂等 | 连续注入 3 次，文件 md5 不变 ✅ |
| JS 语法 | JavaScriptCore（Safari/WebKit 内核）解析通过 ✅ |
| 运行时 | 在真实 JS 引擎 + DOM 环境执行注入脚本：无异常，下拉框 8 项 ✅ |
| 文本残留汉字 | en / vi / fr / hi / ko / th 均 **0 处**；zh-TW、ja 的残留为合法繁体/日文汉字 ✅ |
| 语言往返 | 8 语言绕一圈回到英文，渲染结果与原英文**逐字节一致**（源串不丢）✅ |
| 动态节点 | 模拟 3 秒刷新的表格新增节点，经 MutationObserver 正确翻译 ✅ |
| 属性翻译 | `placeholder` / `title` / `alt` / `value` 同步翻译 ✅ |
| 后端回归 | 342/342 全绿（test_testnet 68 / test_omnimx_dex 88 / test_platform 36 / test_ws_subscribe 48 / test_suite 102）✅ |

## 8. 已知事项

- 词典为**机器初稿 + 人工校对**，术语准确性尚未经母语者复核。金融/合规术语（如
  `RWA 确权`、`合规模块`、`分账`）建议由各地区运营同事过一遍 `dict.json` 再对外发布。
- `en` 下 `zh-CN` 浏览器会看到英文（这是「主语言英语」的既定行为）。若要改成简体中文兜底，
  见 §6 的「加语言」。
- 本次仅覆盖区块浏览器两个页面；DEX 页（`node/dex.html`）为独立工程，未纳入本次改动。
