diff --git a/.prettierignore b/.prettierignore
index efdc50f..732d7d7 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -5,3 +5,7 @@ app/assets/strokes/
# Generated by scripts/build-fonts.ts alongside the woff2 files
app/assets/fonts/fonts-*.css
app/generated/
+
+# Pinned upstream licence notices copied verbatim by the font build.
+public/notices/plangothic-ofl.txt
+public/notices/wenjin-mincho-ofl.md
diff --git a/README.ja-JP.md b/README.ja-JP.md
index 83cb007..8834ce7 100644
--- a/README.ja-JP.md
+++ b/README.ja-JP.md
@@ -16,7 +16,7 @@
## 収録範囲
-中国大陸の『通用規範漢字表』(2013年)、台湾の『常用國字標準字體表』(1982年)、香港の『常用字字形表』、日本の『常用漢字表』(2010年)、韓国の『漢文教育用基礎漢字』(2000年)の和集合を収録しています。韓国の字表には常用漢字1,800字が含まれます。簡体字と繁体字、日本の新字体と旧字体、韓国式異体字など、コードポイントをまたぐ対応を1行に統合した結果、全体で **8,449行** です。このうち1,695行は5地域の字形が完全に一致し、129行は5地域すべてで異なります。
+中国大陸の『通用規範漢字表』(2013年)、台湾の『常用國字標準字體表』(1982年)、香港の『常用字字形表』、日本の『常用漢字表』(2010年)、韓国の『漢文教育用基礎漢字』(2000年)の和集合を収録しています。韓国の字表には常用漢字1,800字が含まれます。簡体字と繁体字、日本の新字体と旧字体、韓国式異体字など、コードポイントをまたぐ対応を1行に統合した結果、全体で **8,449行** です。このうち1,692行は5地域の字形が完全に一致し、129行は5地域すべてで異なります。
台湾の『次常用國字表』は、既存行の二級収録状態と候補を示すためだけに使い、新しい行の生成には使いません。6,343件の主要項目のうち、他にない3,599件は明示的に本プロダクトの対象外としています。
@@ -40,6 +40,8 @@
ページ上ではこの判定に基づいてセルを再グループ化します。同形と判定されたセルは、グループ内の一地域のNotoフォントを共通して使い、画面上でも実際に同じ輪郭を表示します。そのため、上記ルールで除外された地域版間の細かな差異は表示されません。`scripts/tests/fonts.test.ts` はfontkitで生成フォントの実際のアウトラインを取り出し、判定と画面表示が一致することを1字ずつ検証します。
+明確なコードポイント間の対応は、Noto/Source Hanが対応先の文字を収録していなくても元のコードポイントへ戻しません。たとえば `𬒗 → 𥗽` は二つのコードポイントとして表示します。ビルドは、現在のデータで表示が必要ながらNotoにないコードポイントを自動収集し、同梱用の補充WOFF2サブセットを生成します。ゴシック体はPlangothic P1、明朝体はWenJin Mincho P2を使い、選択したフォントに一つでも未収録コードポイントがあればビルドを明示的に失敗させます。ページには常に実際のUnicodeテキストを残すため、端末フォントには依存しません。これらの補充字形は表示専用で、地域差の判定には使いません。
+
## 制限事項
- 本アプリが比較するのは、一般的なゴシック体と明朝体における印刷字形だけです。手書きの慣習は対象外で、教科書体の例示字形も基準にしません。日本語の教科書体は主に日本語教育向けに設計され、中国大陸・香港・台湾・韓国と同じグリフプールを共有する正式な地域版がありません。見た目の近い別々のフォントを組み合わせると、地域差とフォント固有のデザイン差を分離できません。条件を揃えるため、5地域版を同時に提供する同系統のフォントファミリーだけを使います。
@@ -63,7 +65,7 @@
```bash
pnpm install
-pnpm build:data # 字表とフォントサブセットを生成。初回は約261 MiBをダウンロードし、以後はキャッシュを使用
+pnpm build:data # 字表とフォントサブセットを生成。初回は約302 MiBをダウンロードし、以後はキャッシュを使用
pnpm update:sources # サードパーティデータの更新を確認して固定。変更があればダウンロードして再生成
pnpm dev
pnpm test
@@ -94,7 +96,7 @@ Cloudflareの **Settings → Domains & Routes** でproductionドメインを接
各字群の詳細ページはそれぞれ独立したHTMLとして生成されます。ページデータはローカルbundleに含まれるため、ルートごとの追加 `_payload.json` を生成するpayload extractionは無効にしています。地域異体字の別名については、リダイレクト専用ページを生成しません。Static Assetsがまず `404.html` とHTTP 404を返し、その後Nuxtのクライアントミドルウェアが対応する行へ移動します。これにより、検索エンジンが別名を成功ページとして重複登録することを避けます。実際に存在しないURLはHTTP 404のままです。`@nuxtjs/sitemap` は静的生成時にすべてのcanonicalページを `/sitemap.xml` へ書き出し、`@nuxtjs/robots` は `/robots.txt` を生成してsitemapの場所を通知します。両方の絶対URLには `NUXT_SITE_URL` を使用します。GitHub Actionsは同名のリポジトリ変数を優先し、未設定の場合はリポジトリのhomepageを使用します。他の環境では `pnpm generate` の実行時に設定する必要があります。PRプレビューのビルドでは `NUXT_SITE_ENV=preview` によりインデックス登録を禁止します。`public/_headers` では、内容ハッシュ付きの `_nuxt/*` に長期immutableキャッシュを設定し、安定した `/notices/*`、sitemap、robotsのURLには `no-cache`、`/data/chars.json` には1時間の `max-age` と1日の `stale-while-revalidate` を指定します。
-サードパーティ資産の具体的なcommit、公式添付ファイル識別子、SHA-256は `data/sources.lock.json` に記録しています。更新時には `pnpm update:sources` を実行します。バージョンのある上流データについてはバージョン番号を解決し、バージョンのない公式直リンクについては改めて検証します。内容が変わっていればlockfileを更新してデータを再生成し、まったく変わっていなければ生成をスキップします。ビルド時の `pnpm build:data` はlockfileに従い、約 **261 MiB** の元データをダウンロードして検証します。このうち195 MiBは10個のNoto CJKフォントです。明示的な更新を行っていない直リンクの内容が変わった場合は、チェックサム不一致として失敗し、黙ってデータに取り込むことはありません。Actionsでは元データのダウンロードと生成フォントを別々にキャッシュします。前者はlockfileだけで決まり、後者はlockfile、実際の生成スクリプト、関連依存関係、locale、字表から決まります。フォント入力が完全に同じ場合は、データ生成を省略します。
+サードパーティ資産の具体的なcommit、GitHub release tag、公式添付ファイル識別子、SHA-256は `data/sources.lock.json` に記録しています。更新時には `pnpm update:sources` を実行します。GitHubブランチ、最新release、Unicodeバージョンを解決し、バージョンのない公式直リンクについては改めて検証します。内容が変わっていればlockfileを更新してデータを再生成し、まったく変わっていなければ生成をスキップします。ビルド時の `pnpm build:data` はlockfileに従い、約 **302 MiB** の元データをダウンロードして検証します。このうち195 MiBは10個のNoto CJKフォントで、約40 MiBは2個の補充フォントです。明示的な更新を行っていない直リンクの内容が変わった場合は、チェックサム不一致として失敗し、黙ってデータに取り込むことはありません。Actionsでは元データのダウンロードと生成フォントを別々にキャッシュします。前者はlockfileだけで決まり、後者はlockfile、実際の生成スクリプト、関連依存関係、locale、字表から決まります。フォント入力が完全に同じ場合は、データ生成を省略します。
筆順シャードは `pnpm build:dataset` が `app/assets/strokes/` に生成し、リポジトリにはコミットしません。デプロイ処理はテストと静的生成の前に毎回再生成し、Viteが内容ハッシュ付きのファイル名で出力します。付属ライセンスは `public/notices/` の安定URLに置き、再検証を必須にします。同じ字グループ内で筆画順に並べた輪郭が完全に一致する場合は、最初のバリアントとその中心線だけを保存し、画面上でも対応する地域を1つの選択肢にまとめます。ページ読み込み時に所属シャードを一度だけ取得し、その後の地域切替ではメモリ上の字グループデータを再利用します。サイト全体で、ここから解析した輪郭数を第一候補の画数として使います。
@@ -115,6 +117,8 @@ pnpm deploy
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 5地域の字形差異の判定 | [Adobe Source Han Sans / Serif(CMapリソース)](https://github.com/adobe-fonts/source-han-sans) | [SIL OFL 1.1](https://openfontlicense.org/) |
| ページ表示用フォント | [Noto Sans / Noto Serif(CJKを含む)](https://github.com/notofonts/noto-cjk) | [SIL OFL 1.1](https://openfontlicense.org/) |
+| Noto未収録字のゴシック体補完 | [Plangothic P1](https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project) | [SIL OFL 1.1](https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project/blob/main/LICENSE-OFL.txt) |
+| Noto未収録字の明朝体補完 | [WenJin Mincho P2](https://github.com/takushun-wu/WenJinMincho) | [SIL OFL 1.1](https://github.com/takushun-wu/WenJinMincho/blob/main/LICENSE.md) |
| 簡体・繁体、香港・台湾異体字、日本新旧字体の対応 | [OpenCC(中国語文字変換)](https://github.com/BYVoid/OpenCC) | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| 中国・台湾・日本・韓国の筆順と画数 | [AnimCJK](https://github.com/parsimonhi/animCJK) | [Arphic Public License](https://github.com/parsimonhi/animCJK/blob/master/licenses/APL/english/ARPHICPL.TXT) |
| 5地域の標準字表 | [zispace/hanzi-chars](https://github.com/zispace/hanzi-chars) | [リポジトリに記載なし](https://github.com/zispace/hanzi-chars) |
@@ -129,9 +133,9 @@ pnpm deploy
原典となる標準は、中国大陸の『通用規範漢字表』(2013年)、台湾の『常用國字標準字體表』(1982年)、香港の『常用字字形表』、日本の『常用漢字表』(2010年)と『学年別漢字配当表』(2017年)、韓国の『漢文教育用基礎漢字』(2000年)です。
-1字ずつ比較できるツール [tofu.tools](https://tofu.tools/) は本プロジェクトの先行例で、同じくNotoファミリーを使って地域字形を区別しています。
+1字ずつ比較できるツール [tofu.tools](https://tofu.tools/) は本プロジェクトの先行例で、同じくNotoファミリーを使って地域字形を区別しています。希少字の補充字形を提供してくださったPlangothicとWenJin Minchoのメンテナーにも感謝します。
-フォントはNoto Sans CJKとNoto Serif CJK(SIL OFL 1.1)を本アプリで使う文字にサブセット化したものです。ライセンス文は [`/notices/noto-ofl.txt`](public/notices/noto-ofl.txt) に同梱しています。生成データファイルは上記の出典から派生しているため、それぞれのライセンスに従ってください。項目ごとの変換方法と帰属表示は、公開されている [`/notices/data-sources.md`](public/notices/data-sources.md) にも記載しています。
+フォントはNoto Sans CJK、Noto Serif CJK、Plangothic P1、WenJin Mincho P2(すべてSIL OFL 1.1)を本アプリで使う文字にサブセット化したものです。ライセンス文は [`/notices/noto-ofl.txt`](public/notices/noto-ofl.txt)、[`/notices/plangothic-ofl.txt`](public/notices/plangothic-ofl.txt)、[`/notices/wenjin-mincho-ofl.md`](public/notices/wenjin-mincho-ofl.md) に同梱しています。生成データファイルは上記の出典から派生しているため、それぞれのライセンスに従ってください。項目ごとの変換方法と帰属表示は、公開されている [`/notices/data-sources.md`](public/notices/data-sources.md) にも記載しています。
## License
diff --git a/README.md b/README.md
index dc0fd57..1047d55 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
## 收录范围
-收录《通用规范汉字表》(2013)、臺灣《常用國字標準字體表》(1982)、香港《常用字字形表》、日本《常用漢字表》(2010)、韩国《漢文教育用基礎漢字》(2000)五份字表的并集。韩国字表含 1,800 个常用汉字。把简繁、日本新旧字体和韩式异体这类跨码点的对应合并成一行后,共 **8,449 行**——其中 1,695 行五地字形完全一致,129 行五地各不相同。
+收录《通用规范汉字表》(2013)、臺灣《常用國字標準字體表》(1982)、香港《常用字字形表》、日本《常用漢字表》(2010)、韩国《漢文教育用基礎漢字》(2000)五份字表的并集。韩国字表含 1,800 个常用汉字。把简繁、日本新旧字体和韩式异体这类跨码点的对应合并成一行后,共 **8,449 行**——其中 1,692 行五地字形完全一致,129 行五地各不相同。
台湾《次常用國字表》只为已有行提供二级收录状态和候选,不参与生成新行;其 6,343 个主条目中有 3,599 个独有条目明确在产品范围之外。
@@ -40,6 +40,8 @@
页面会按这份判定重新分组:被判为同形的格子统一借用组内一个地区的 Noto 字体,使屏幕上也真正呈现同一轮廓。相应地,被上述规则过滤的地区版本细小差异不会显示。`scripts/tests/fonts.test.ts` 会用 fontkit 取出生成字体的真实轮廓,逐字验证判定与画面显示一致。
+明确的跨码点映射不会因为 Noto/Source Han 未收录目标字而退回原码点。例如 `𬒗 → 𥗽` 仍会显示为两个码点。构建会从当前数据自动收集 Noto 缺少但页面需要显示的码点,并生成项目内置的补充 WOFF2 子集:黑体取 Plangothic P1,宋体取 WenJin Mincho P2;所选字体缺少任一码点时,构建会明确失败。页面始终保留真正的 Unicode 文本,不依赖用户设备的本机字体。这两套补充字形只负责显示,不参与地区差异判定。
+
## 局限
- 本应用只比较通用黑体与宋体中的印刷字形,不涵盖手写习惯,也不以教科书体的示范字形为准。日语教科书体主要为日语教学设计,并没有与中、港、台、韩共享同一字形池的正式地区版本;若拼接风格相近但来源不同的字体,地区差异与字体自身的设计差异就无法分开。为了控制变量,本应用只能选用同时提供五地版本的同源字体系列。
@@ -63,7 +65,7 @@
```bash
pnpm install
-pnpm build:data # 生成字表与字体子集,首次会下载约 261 MiB 原始数据,之后走缓存
+pnpm build:data # 生成字表与字体子集,首次会下载约 302 MiB 原始数据,之后走缓存
pnpm update:sources # 检查并锁定新版第三方数据;有变化时下载并重新生成
pnpm dev
pnpm test
@@ -94,7 +96,7 @@ Cloudflare Worker 名称须为 `hanji`,与 `wrangler.json` 中的 `name` 一
每个字组详情页都会生成独立 HTML;页面数据在本地 bundle 中,因此关闭了每路由额外生成 `_payload.json` 的 payload extraction。地区异体别名不另外生成跳转页:它先由 Static Assets 返回 `404.html` 和 HTTP 404,再由 Nuxt 客户端中间件跳到所属行;搜索引擎不会把 alias 当作成功页面重复收录。真正未知的地址保持 HTTP 404。`@nuxtjs/sitemap` 会在静态生成时把全部 canonical 页面写入 `/sitemap.xml`,`@nuxtjs/robots` 生成 `/robots.txt` 并公布 sitemap 地址。两者的绝对 URL 来自 `NUXT_SITE_URL`;GitHub Actions 优先读取同名仓库变量,未设置时使用仓库 homepage,其他环境需在运行 `pnpm generate` 时设置。PR 预览构建通过 `NUXT_SITE_ENV=preview` 禁止索引。`public/_headers` 给带内容哈希的 `_nuxt/*` 设长期 immutable 缓存,让稳定的 `/notices/*`、sitemap 和 robots URL 使用 `no-cache`,并为 `/data/chars.json` 设置 1 小时的 `max-age` 与 1 天的 `stale-while-revalidate`。
-第三方资产的具体 commit、官方附件标识与 SHA-256 记录在 `data/sources.lock.json`;需要升级时运行 `pnpm update:sources`。它会解析有版本上游的版本号,并重新校验没有版本号的官方直链;内容有变化时更新 lockfile 并直接重新生成数据,完全未变则跳过生成。构建时 `pnpm build:data` 会按 lockfile 下载并校验约 **261 MiB** 原始数据(其中 195 MiB 是十份 Noto CJK 字体);任何未显式更新的直链内容变化都会因校验和不符而失败,不会静默进入数据。Actions 分开缓存原始下载与生成字体:前者只由 lockfile 决定,后者由 lockfile、实际生成脚本、相关依赖、locale 与字表决定;字体输入完全不变时跳过数据生成。
+第三方资产的具体 commit、GitHub release tag、官方附件标识与 SHA-256 记录在 `data/sources.lock.json`;需要升级时运行 `pnpm update:sources`。它会解析 GitHub 分支、最新 release 与 Unicode 版本,并重新校验没有版本号的官方直链;内容有变化时更新 lockfile 并直接重新生成数据,完全未变则跳过生成。构建时 `pnpm build:data` 会按 lockfile 下载并校验约 **302 MiB** 原始数据(其中 195 MiB 是十份 Noto CJK 字体,另有约 40 MiB 的两份补充字体);任何未显式更新的直链内容变化都会因校验和不符而失败,不会静默进入数据。Actions 分开缓存原始下载与生成字体:前者只由 lockfile 决定,后者由 lockfile、实际生成脚本、相关依赖、locale 与字表决定;字体输入完全不变时跳过数据生成。
笔顺分片由 `pnpm build:dataset` 生成到 `app/assets/strokes/`,不提交到仓库;部署流程会在测试和静态生成前重建,再由 Vite 输出带内容哈希的文件名。随附授权保留在 `public/notices/` 的稳定 URL 下并要求重新验证。同一字组内,按笔画顺序排列的轮廓完全一致时只保存第一份变体及其中线,界面也把对应地区合并为一个选择项;页面加载时只获取一次所属分片,之后切换地区直接复用内存中的字组数据。整站使用这里解析出的轮廓数量作为首选笔画数。
@@ -115,6 +117,8 @@ pnpm deploy
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| 判定五地字形差异 | [Adobe Source Han Sans / Serif(CMap 资源)](https://github.com/adobe-fonts/source-han-sans) | [SIL OFL 1.1](https://openfontlicense.org/) |
| 页面展示用字体 | [Noto Sans / Noto Serif(含 CJK)](https://github.com/notofonts/noto-cjk) | [SIL OFL 1.1](https://openfontlicense.org/) |
+| 补充Noto未收录的黑体字形 | [Plangothic P1](https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project) | [SIL OFL 1.1](https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project/blob/main/LICENSE-OFL.txt) |
+| 补充Noto未收录的宋体字形 | [WenJin Mincho P2](https://github.com/takushun-wu/WenJinMincho) | [SIL OFL 1.1](https://github.com/takushun-wu/WenJinMincho/blob/main/LICENSE.md) |
| 简繁、港台异体、日本新旧字体对应 | [OpenCC 开放中文转换](https://github.com/BYVoid/OpenCC) | [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| 中、台、日、韩笔顺动画与笔画数 | [AnimCJK](https://github.com/parsimonhi/animCJK) | [Arphic Public License](https://github.com/parsimonhi/animCJK/blob/master/licenses/APL/english/ARPHICPL.TXT) |
| 五地标准字表 | [zispace/hanzi-chars](https://github.com/zispace/hanzi-chars) | [仓库未声明](https://github.com/zispace/hanzi-chars) |
@@ -129,9 +133,9 @@ pnpm deploy
原始规范出处:《通用规范汉字表》(2013)、臺灣《常用國字標準字體表》(1982)、香港《常用字字形表》、日本《常用漢字表》(2010)与《学年別漢字配当表》(2017)、韩国《漢文教育用基礎漢字》(2000)。
-逐字对照工具 [tofu.tools](https://tofu.tools/) 是本项目的先行者,同样用 Noto 系列区分地区字形。
+逐字对照工具 [tofu.tools](https://tofu.tools/) 是本项目的先行者,同样用 Noto 系列区分地区字形。感谢 Plangothic 与 WenJin Mincho 的维护者提供生僻字补充字形。
-字体为 Noto Sans CJK 与 Noto Serif CJK(SIL OFL 1.1)按本应用用字子集化后的产物,声明随附于 [`/notices/noto-ofl.txt`](public/notices/noto-ofl.txt)。生成的数据文件派生自上述来源,请遵守各自许可;逐项转换方式与署名也写入公开的 [`/notices/data-sources.md`](public/notices/data-sources.md)。
+字体为 Noto Sans CJK、Noto Serif CJK、Plangothic P1 与 WenJin Mincho P2(均为 SIL OFL 1.1)按本应用用字子集化后的产物。声明分别随附于 [`/notices/noto-ofl.txt`](public/notices/noto-ofl.txt)、[`/notices/plangothic-ofl.txt`](public/notices/plangothic-ofl.txt) 与 [`/notices/wenjin-mincho-ofl.md`](public/notices/wenjin-mincho-ofl.md)。生成的数据文件派生自上述来源,请遵守各自许可;逐项转换方式与署名也写入公开的 [`/notices/data-sources.md`](public/notices/data-sources.md)。
## License
diff --git a/app/components/CharCells.vue b/app/components/CharCells.vue
index 0ad3d5a..fe7ca6f 100644
--- a/app/components/CharCells.vue
+++ b/app/components/CharCells.vue
@@ -65,7 +65,7 @@ const cells = computed(() =>
>
{{ cell.codePoint }}
/**
* BCP-47 tag per column. This is accessibility semantics, unrelated to the
- * interface language; it also drives the system's own CJK fallback when a
- * subset has not loaded. The kyujitai is Japan's own, so it is tagged as
+ * interface language. The kyujitai is Japan's own, so it is tagged as
* Japanese too.
*/
export const COLUMN_LANG: Record = {
diff --git a/data/sources.lock.json b/data/sources.lock.json
index 5633a25..aba1d53 100644
--- a/data/sources.lock.json
+++ b/data/sources.lock.json
@@ -2,14 +2,17 @@
"version": 1,
"revisions": {
"github:zispace/hanzi-chars@main": "105544909cab18db1fedfd41a42c87408fbaac59",
- "github:BYVoid/OpenCC@master": "4f90418b9ed73a91023897095c762e5fdaadc016",
+ "github:BYVoid/OpenCC@master": "f5de4dd6eb96186e5ab9973043e19873ed678288",
"github:parsimonhi/animCJK@master": "ec5e17cca76c87587790bcbce5ea0b4d4fb753d6",
"github:adobe-fonts/source-han-sans@master": "0b993716f6910f0c8e00f957c767ab3cf5cb7602",
"github:adobe-fonts/source-han-serif@master": "4356704ff7c68e9a84bf2bd489c9ebe186a9e2ef",
"github:ruddfawcett/hanziDB.csv@master": "3e9f908d25f70674862343b201f6b641a36cd226",
"github:scriptin/kanji-frequency@master": "62df93626e51a61c3dec58b51bfa20bef79491d7",
"github:notofonts/noto-cjk@main": "f8d157532fbfaeda587e826d4cd5b21a49186f7c",
+ "github:Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project@main": "cfcb7cc869562443d6c6f85c935d0dd8dbdd69b6",
+ "github:takushun-wu/WenJinMincho@main": "a9b9653cf12857e10bdf1c22455afaa4e21dd9a3",
"github:notofonts/notofonts.github.io@main": "3c16704cb6f6e7c02268f7bc0cf86aaee598d16f",
+ "github-release:Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project": "V2.9.5795",
"unicode:ucd": "17.0.0"
},
"assets": {
@@ -59,27 +62,27 @@
"size": 7466
},
"opencc/STCharacters.txt": {
- "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/4f90418b9ed73a91023897095c762e5fdaadc016/data/dictionary/STCharacters.txt",
+ "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/f5de4dd6eb96186e5ab9973043e19873ed678288/data/dictionary/STCharacters.txt",
"sha256": "a0ca1601c70648cf48b33c3c6210ccbecc5c7eead4b4c3daf76587ba2c03582b",
"size": 36026
},
"opencc/TSCharacters.txt": {
- "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/4f90418b9ed73a91023897095c762e5fdaadc016/data/dictionary/TSCharacters.txt",
+ "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/f5de4dd6eb96186e5ab9973043e19873ed678288/data/dictionary/TSCharacters.txt",
"sha256": "737c21c66f55a419dd6956cb3089476cdefc5a36877452631617696df1e5d925",
"size": 104516
},
"opencc/TWVariants.txt": {
- "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/4f90418b9ed73a91023897095c762e5fdaadc016/data/dictionary/TWVariants.txt",
+ "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/f5de4dd6eb96186e5ab9973043e19873ed678288/data/dictionary/TWVariants.txt",
"sha256": "e187278e119c427ca561180ac5da5b20e9f8681190458f35c327ce499e95a6a5",
"size": 986
},
"opencc/HKVariants.txt": {
- "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/4f90418b9ed73a91023897095c762e5fdaadc016/data/dictionary/HKVariants.txt",
+ "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/f5de4dd6eb96186e5ab9973043e19873ed678288/data/dictionary/HKVariants.txt",
"sha256": "e5cd4345303224587102f2c9e4d2b67d2b7e349c6ce9152e4a118f4656cf7302",
"size": 1001
},
"opencc/JPShinjitaiCharacters.txt": {
- "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/4f90418b9ed73a91023897095c762e5fdaadc016/data/dictionary/JPShinjitaiCharacters.txt",
+ "url": "https://raw.githubusercontent.com/BYVoid/OpenCC/f5de4dd6eb96186e5ab9973043e19873ed678288/data/dictionary/JPShinjitaiCharacters.txt",
"sha256": "12cec7250b873ef52b36d8f92218d4f92c0aaf5d8cd7c58fe42d9785bdcdc43a",
"size": 12442
},
@@ -238,6 +241,26 @@
"sha256": "77b4b741f864d27f15e90f275b17106dde90b2ad28f82bab72dc95805db5fb42",
"size": 24539640
},
+ "font/PlangothicP1-Regular.ttf": {
+ "url": "https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project/releases/download/V2.9.5795/PlangothicP1-Regular.ttf",
+ "sha256": "550b5d0775b15405946b18f4843df439a51e69508d7e6778d94c1f7a53dc5ad6",
+ "size": 20410664
+ },
+ "font/Plangothic-OFL.txt": {
+ "url": "https://raw.githubusercontent.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project/cfcb7cc869562443d6c6f85c935d0dd8dbdd69b6/LICENSE-OFL.txt",
+ "sha256": "e564f06d018e7b95bc3594c96a17f1d41865af4038c375e7aa974dd69df38602",
+ "size": 4302
+ },
+ "font/WenJinMinchoP2-Regular.otf": {
+ "url": "https://raw.githubusercontent.com/takushun-wu/WenJinMincho/a9b9653cf12857e10bdf1c22455afaa4e21dd9a3/otf/WenJinMinchoP2-Regular.otf",
+ "sha256": "8ed6e637aafd659e517b2af230b66ae587f23412223c054a29c1e2e64dbf1642",
+ "size": 22041624
+ },
+ "font/WenJinMincho-OFL.md": {
+ "url": "https://raw.githubusercontent.com/takushun-wu/WenJinMincho/a9b9653cf12857e10bdf1c22455afaa4e21dd9a3/LICENSE.md",
+ "sha256": "3f47d592920dbb67d90e2b248b26295703b3892cfeec465f1814fd71b2e902ef",
+ "size": 5356
+ },
"font/NotoSans-VF.ttf": {
"url": "https://raw.githubusercontent.com/notofonts/notofonts.github.io/3c16704cb6f6e7c02268f7bc0cf86aaee598d16f/fonts/NotoSans/unhinted/variable-ttf/NotoSans%5Bwdth,wght%5D.ttf",
"sha256": "511cc04b442ffcc3b24d65c2cc780bdffaf482b20ba0aebdc8f27b37017ff0f5",
diff --git a/docs/known-issues.md b/docs/known-issues.md
index b69aa4c..f9ad1cd 100644
--- a/docs/known-issues.md
+++ b/docs/known-issues.md
@@ -27,14 +27,15 @@
## 公共数据语义
-| 字段 | 含义 |
-| -------------- | ----------------------------------------------------------------------------------- |
-| `chars` | 五地展示形;未收录时仍保留可绘制的参考字形 |
-| `listing` | 每格在该地区字表中的身份:`primary`、`glossed` 或 `unlisted` |
-| `alternatives` | 该地区已收录、未展示且明确属于当前字组的形式;可搜索、作网址别名并显示字典引用 |
-| `aka` | 同一字组的其他名称,不表示地区候选 |
-| `uncertain` | 双向未确认关系,记录相关行、触发字形和地区;只用于详情页“另见” |
-| `old` | 仅由 `JPShinjitaiCharacters` 的明确关系产生的日本旧字体,不由行名与日本列的差异反推 |
+| 字段 | 含义 |
+| ------------------ | ----------------------------------------------------------------------------------- |
+| `chars` | 五地展示形;未收录时仍保留参考字形,明确映射不会因项目字体缺字而改回原码点 |
+| `listing` | 每格在该地区字表中的身份:`primary`、`glossed` 或 `unlisted` |
+| `alternatives` | 该地区已收录、未展示且明确属于当前字组的形式;可搜索、作网址别名并显示字典引用 |
+| `aka` | 同一字组的其他名称,不表示地区候选 |
+| `uncertain` | 双向未确认关系,记录相关行、触发字形和地区;只用于详情页“另见” |
+| `old` | 仅由 `JPShinjitaiCharacters` 的明确关系产生的日本旧字体,不由行名与日本列的差异反推 |
+| `supplementalFont` | 黑体、宋体各自需要跳过Noto、改用项目内置补充字体的列 |
`listing` 的三个状态直接来自原始字表:
@@ -46,7 +47,7 @@
## 字形与笔画
-字形比较使用 Source Han Sans 与 Source Han Serif 的地区 CMap。同一套字体内 CID 相同即视为同形;黑体或宋体任一方认为两地同形,最终就按同形处理。这样会过滤只由一套字体作出的设计区分,但也意味着本应用衡量的是 Source Han 的地区设计,而不是规范文件本身。
+字形比较使用 Source Han Sans 与 Source Han Serif 的地区 CMap。同一套字体内 CID 相同即视为同形;黑体或宋体任一方认为两地同形,最终就按同形处理。这样会过滤只由一套字体作出的设计区分,但也意味着本应用衡量的是 Source Han 的地区设计,而不是规范文件本身。若明确的跨码点目标不在两套 CMap 中,同一码点的未测量列按一组保留,并通过 `supplementalFont` 改用项目内置的 Plangothic P1 或 WenJin Mincho P2 子集;不同码点仍保持不同。补充字形只用于渲染,不作为地区差异证据。
字表筛选、排序与详情页共用同一套地区笔画数,优先级为笔顺数据的轮廓数 → `kAlternateTotalStrokes` → 日本列的 `kRSAdobe_Japan1_6` → `kTotalStrokes`。香港复用笔顺的同形回退,按台湾、大陆、日本、韩国的顺序取首个可用数据。例如 `以` 五列为 `4 / 5 / 5 / 5 / 5`。
@@ -58,7 +59,7 @@
- 每格 `listing` 与原始主条目、括注和未收录状态一致;
- `alternatives` 不属于其他最终字组;
- 五份建行主表的每个主条目都被展示或记录为候选,否则构建失败;
-- 所有展示形和日本旧字体都能由生成的字体子集绘制。
+- 每个展示形和日本旧字体都能由最终生成的Noto或补充字体子集绘制;标记为 `supplementalFont` 的码点还必须由对应的补充字体源覆盖。
## 已知限制
diff --git a/public/notices/data-sources.md b/public/notices/data-sources.md
index 574a741..6b4e9fd 100644
--- a/public/notices/data-sources.md
+++ b/public/notices/data-sources.md
@@ -7,14 +7,28 @@ Hanji 的程序代码采用 MIT 许可;来源数据及其派生字段仍须遵
- 用途:判定五地字形差异
- 来源:https://github.com/adobe-fonts/source-han-sans
- 许可:SIL OFL 1.1 (https://openfontlicense.org/)
-- 备注:每套字体的五份地区 CMap 给出「码点 → CID」映射,同一字形池内 CID 相同即同一字形。判定取黑体与宋体的并集。
+- 备注:每套字体的五份地区CMap给出「码点 → CID」映射,同一字形池内CID相同即同一字形。判定取黑体与宋体的并集。
## Noto Sans / Noto Serif(含 CJK)
- 用途:页面展示用字体
- 来源:https://github.com/notofonts/noto-cjk
- 许可:SIL OFL 1.1 (https://openfontlicense.org/)
-- 备注:汉字取自 CJK 版本,拉丁字母与数字取自拉丁版本,都按应用内用字子集化后自托管,OFL 声明随附于 /notices/noto-ofl.txt。
+- 备注:汉字取自CJK版本,拉丁字母与数字取自拉丁版本,都按应用内用字子集化后自托管,OFL声明随附于 /notices/noto-ofl.txt。
+
+## Plangothic P1
+
+- 用途:补充Noto未收录的黑体字形
+- 来源:https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project
+- 许可:SIL OFL 1.1 (https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project/blob/main/LICENSE-OFL.txt)
+- 备注:按当前数据中Noto未收录但需要显示的码点,动态生成重命名后的网页字体子集;这些字形不参与地区差异判定。OFL声明随附于/notices/plangothic-ofl.txt。
+
+## WenJin Mincho P2
+
+- 用途:补充Noto未收录的宋体字形
+- 来源:https://github.com/takushun-wu/WenJinMincho
+- 许可:SIL OFL 1.1 (https://github.com/takushun-wu/WenJinMincho/blob/main/LICENSE.md)
+- 备注:按当前数据中Noto未收录但需要显示的码点,动态生成重命名后的网页字体子集;这些字形不参与地区差异判定。OFL声明随附于/notices/wenjin-mincho-ofl.md。
## OpenCC 开放中文转换
diff --git a/public/notices/plangothic-ofl.txt b/public/notices/plangothic-ofl.txt
new file mode 100644
index 0000000..77b1731
--- /dev/null
+++ b/public/notices/plangothic-ofl.txt
@@ -0,0 +1,91 @@
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/public/notices/wenjin-mincho-ofl.md b/public/notices/wenjin-mincho-ofl.md
new file mode 100644
index 0000000..75c26d3
--- /dev/null
+++ b/public/notices/wenjin-mincho-ofl.md
@@ -0,0 +1,126 @@
+Copyright (c) 2024-2026, Takushun Wu (https://github.com/takushun-wu/),
+with Reserved Font Name 'WenJin Mincho', '文津宋体', '文津宋體', '文津明朝', '문진(文津) 명조'.
+
+Copyright 2010-2025 Adobe (http://www.adobe.com/), with Reserved Font
+Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States
+and/or other countries.
+
+Copyright 2021-2025 Tamcy (https://github.com/chiron-fonts/chiron-sung-hk).
+
+Copyright 2022-2025 Shanggu Fonts (https://github.com/GuiWonder/Shanggu).
+
+© 2007–2024 Adobe, But Ko, CMEX, Creative Commons Corporation, GlyphWiki & Night Koo.
+
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/). Noto is a trademark of Google Inc.
+
+Copyright © 2015 Google Inc.
+
+Saudi Riyal Font © Emran Alhaddad - Used under SIL Open Font License 1.1
+
+
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https\://openfontlicense.org
+
+
+\----------------------------------------------------------------------
+
+#### SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+
+\----------------------------------------------------------------------
+
+
+
+PREAMBLE
+-----------
+
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+-----------
+
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+-----------
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+-----------
+
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+-----------
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/scripts/build-data.ts b/scripts/build-data.ts
index 1292757..6e38da4 100644
--- a/scripts/build-data.ts
+++ b/scripts/build-data.ts
@@ -13,7 +13,19 @@
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import { format, resolveConfig } from 'prettier'
+import { fontIndexOf } from '../shared/row.ts'
import { SOURCES } from '../shared/sources.ts'
+import {
+ STYLES,
+ type CharRow,
+ type Column,
+ type ListedAlternative,
+ type Region,
+ type RegionalTuple,
+ type Stats,
+ type Style,
+ type UncertainRelation,
+} from '../shared/types.ts'
import { buildStrokeData } from './build-strokes.ts'
import { parseCMap, partitionSignature } from './cmap.ts'
import {
@@ -31,15 +43,6 @@ import {
reverseDict,
ROOT,
} from './sources.ts'
-import type {
- CharRow,
- ListedAlternative,
- Region,
- RegionalTuple,
- Stats,
- UncertainRelation,
-} from '../shared/types.ts'
-
const dict = async (name: string) =>
parseDict(await rawText(`opencc/${name}.txt`))
@@ -360,7 +363,10 @@ function pick(
* glyph. Source Han Sans hands Japan its own glyph for a fifth of common
* characters; for a couple of hundred of those the serif faces do not, which
* marks the difference as that typeface's design decision rather than a
- * regional one. Agreement in either face is therefore taken as agreement.
+ * regional one. Agreement in either face is therefore taken as agreement. If
+ * neither face covers a codepoint, its same-codepoint columns remain one
+ * unmeasured group; different codepoints still remain distinct and are drawn
+ * by the project's supplemental fonts.
*
* The union of two equivalence relations need not be transitive, so the groups
* are the connected components rather than the pairs themselves.
@@ -368,6 +374,7 @@ function pick(
function unifiedSignature(
sans: (number | undefined)[],
serif: (number | undefined)[],
+ codePoints?: (number | undefined)[],
): string {
const parent = sans.map((_, i) => i)
const find = (x: number): number =>
@@ -378,7 +385,15 @@ function unifiedSignature(
for (let i = 0; i < parent.length; i++)
for (let j = i + 1; j < parent.length; j++) {
- if (!agree(sans, i, j) && !agree(serif, i, j)) continue
+ const sameUnmeasuredCodePoint =
+ codePoints?.[i] !== undefined &&
+ codePoints[i] === codePoints[j] &&
+ sans[i] === undefined &&
+ sans[j] === undefined &&
+ serif[i] === undefined &&
+ serif[j] === undefined
+ if (!agree(sans, i, j) && !agree(serif, i, j) && !sameUnmeasuredCodePoint)
+ continue
const [ri, rj] = [find(i), find(j)]
if (ri !== rj) parent[rj] = ri
}
@@ -437,12 +452,9 @@ function buildRow(
char,
]) as RegionalTuple,
alternatives?: CharRow['alternatives'],
-): CharRow | undefined {
+): CharRow {
const codePoints = chars.map((c) => c.codePointAt(0)) as RegionalTuple
const sansCids = codePoints.map((cp, i) => sansCMaps[i]!.get(cp))
- // A character Noto does not cover can be neither drawn nor judged
- if (sansCids.includes(undefined)) return undefined
-
const serifCids = codePoints.map((cp, i) => serifCMaps[i]!.get(cp))
/**
@@ -456,13 +468,14 @@ function buildRow(
const oldPoint = oldChar?.codePointAt(0)
const oldSans =
oldPoint === undefined ? undefined : sansCMaps[JP_INDEX]!.get(oldPoint)
- const hasOld = oldChar !== undefined && oldSans !== undefined
+ const hasOld = oldChar !== undefined
const oldSerif =
oldPoint === undefined ? undefined : serifCMaps[JP_INDEX]!.get(oldPoint)
const signature = unifiedSignature(
hasOld ? [...sansCids, oldSans] : sansCids,
hasOld ? [...serifCids, oldSerif] : serifCids,
+ hasOld ? [...codePoints, oldPoint] : codePoints,
)
const glyph = signature.slice(0, REGION_IDS.length)
const cp = partitionSignature(codePoints)
@@ -512,6 +525,26 @@ function buildRow(
common: tier.filter(Boolean).length,
...(Object.keys(readings).length > 0 ? { readings } : {}),
}
+
+ const mapsByStyle: Record