dsh-diff-approval 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +4 -0
  2. package/README.zh.md +4 -0
  3. package/assets/fonts/FONTLOG.md +55 -0
  4. package/assets/fonts/OFL.txt +95 -0
  5. package/assets/fonts/README.md +123 -0
  6. package/assets/fonts/manifest.json +1784 -0
  7. package/assets/fonts/regular-cjk-punctuation.woff2 +0 -0
  8. package/assets/fonts/regular-hanzi-000.woff2 +0 -0
  9. package/assets/fonts/regular-hanzi-001.woff2 +0 -0
  10. package/assets/fonts/regular-hanzi-002.woff2 +0 -0
  11. package/assets/fonts/regular-hanzi-003.woff2 +0 -0
  12. package/assets/fonts/regular-hanzi-004.woff2 +0 -0
  13. package/assets/fonts/regular-hanzi-005.woff2 +0 -0
  14. package/assets/fonts/regular-hanzi-006.woff2 +0 -0
  15. package/assets/fonts/regular-hanzi-007.woff2 +0 -0
  16. package/assets/fonts/regular-hanzi-008.woff2 +0 -0
  17. package/assets/fonts/regular-hanzi-009.woff2 +0 -0
  18. package/assets/fonts/regular-hanzi-010.woff2 +0 -0
  19. package/assets/fonts/regular-hanzi-011.woff2 +0 -0
  20. package/assets/fonts/regular-hanzi-012.woff2 +0 -0
  21. package/assets/fonts/regular-hanzi-013.woff2 +0 -0
  22. package/assets/fonts/regular-hanzi-014.woff2 +0 -0
  23. package/assets/fonts/regular-hanzi-015.woff2 +0 -0
  24. package/assets/fonts/regular-hanzi-016.woff2 +0 -0
  25. package/assets/fonts/regular-hanzi-017.woff2 +0 -0
  26. package/assets/fonts/regular-hanzi-018.woff2 +0 -0
  27. package/assets/fonts/regular-hanzi-019.woff2 +0 -0
  28. package/assets/fonts/regular-hanzi-020.woff2 +0 -0
  29. package/assets/fonts/regular-hanzi-021.woff2 +0 -0
  30. package/assets/fonts/regular-hanzi-022.woff2 +0 -0
  31. package/assets/fonts/regular-hanzi-023.woff2 +0 -0
  32. package/assets/fonts/regular-hanzi-024.woff2 +0 -0
  33. package/assets/fonts/regular-hanzi-025.woff2 +0 -0
  34. package/assets/fonts/regular-hanzi-026.woff2 +0 -0
  35. package/assets/fonts/regular-hanzi-027.woff2 +0 -0
  36. package/assets/fonts/regular-hanzi-028.woff2 +0 -0
  37. package/assets/fonts/regular-hanzi-029.woff2 +0 -0
  38. package/assets/fonts/regular-hanzi-030.woff2 +0 -0
  39. package/assets/fonts/regular-hanzi-031.woff2 +0 -0
  40. package/assets/fonts/regular-hanzi-032.woff2 +0 -0
  41. package/assets/fonts/regular-hanzi-033.woff2 +0 -0
  42. package/assets/fonts/regular-hanzi-034.woff2 +0 -0
  43. package/assets/fonts/regular-hanzi-035.woff2 +0 -0
  44. package/assets/fonts/regular-hanzi-036.woff2 +0 -0
  45. package/assets/fonts/regular-hanzi-037.woff2 +0 -0
  46. package/assets/fonts/regular-hanzi-038.woff2 +0 -0
  47. package/assets/fonts/regular-hanzi-039.woff2 +0 -0
  48. package/assets/fonts/regular-hanzi-040.woff2 +0 -0
  49. package/assets/fonts/regular-hanzi-041.woff2 +0 -0
  50. package/assets/fonts/regular-hanzi-042.woff2 +0 -0
  51. package/assets/fonts/regular-hanzi-043.woff2 +0 -0
  52. package/assets/fonts/regular-hanzi-044.woff2 +0 -0
  53. package/assets/fonts/regular-hanzi-045.woff2 +0 -0
  54. package/assets/fonts/regular-hanzi-046.woff2 +0 -0
  55. package/assets/fonts/regular-hanzi-047.woff2 +0 -0
  56. package/assets/fonts/regular-hanzi-048.woff2 +0 -0
  57. package/assets/fonts/regular-hanzi-049.woff2 +0 -0
  58. package/assets/fonts/regular-hanzi-050.woff2 +0 -0
  59. package/assets/fonts/regular-hanzi-051.woff2 +0 -0
  60. package/assets/fonts/regular-hanzi-052.woff2 +0 -0
  61. package/assets/fonts/regular-hanzi-053.woff2 +0 -0
  62. package/assets/fonts/regular-hanzi-054.woff2 +0 -0
  63. package/assets/fonts/regular-hanzi-055.woff2 +0 -0
  64. package/assets/fonts/regular-hanzi-056.woff2 +0 -0
  65. package/assets/fonts/regular-hanzi-057.woff2 +0 -0
  66. package/assets/fonts/regular-hanzi-058.woff2 +0 -0
  67. package/assets/fonts/regular-hanzi-059.woff2 +0 -0
  68. package/assets/fonts/regular-hanzi-060.woff2 +0 -0
  69. package/assets/fonts/regular-hanzi-061.woff2 +0 -0
  70. package/assets/fonts/regular-hanzi-062.woff2 +0 -0
  71. package/assets/fonts/regular-hanzi-063.woff2 +0 -0
  72. package/assets/fonts/regular-hanzi-064.woff2 +0 -0
  73. package/assets/fonts/regular-latin.woff2 +0 -0
  74. package/assets/fonts/regular-punctuation.woff2 +0 -0
  75. package/assets/fonts/regular-symbols.woff2 +0 -0
  76. package/assets/fonts/semibold-cjk-punctuation.woff2 +0 -0
  77. package/assets/fonts/semibold-hanzi-000.woff2 +0 -0
  78. package/assets/fonts/semibold-hanzi-001.woff2 +0 -0
  79. package/assets/fonts/semibold-hanzi-002.woff2 +0 -0
  80. package/assets/fonts/semibold-hanzi-003.woff2 +0 -0
  81. package/assets/fonts/semibold-hanzi-004.woff2 +0 -0
  82. package/assets/fonts/semibold-hanzi-005.woff2 +0 -0
  83. package/assets/fonts/semibold-hanzi-006.woff2 +0 -0
  84. package/assets/fonts/semibold-hanzi-007.woff2 +0 -0
  85. package/assets/fonts/semibold-hanzi-008.woff2 +0 -0
  86. package/assets/fonts/semibold-hanzi-009.woff2 +0 -0
  87. package/assets/fonts/semibold-hanzi-010.woff2 +0 -0
  88. package/assets/fonts/semibold-hanzi-011.woff2 +0 -0
  89. package/assets/fonts/semibold-hanzi-012.woff2 +0 -0
  90. package/assets/fonts/semibold-hanzi-013.woff2 +0 -0
  91. package/assets/fonts/semibold-hanzi-014.woff2 +0 -0
  92. package/assets/fonts/semibold-hanzi-015.woff2 +0 -0
  93. package/assets/fonts/semibold-hanzi-016.woff2 +0 -0
  94. package/assets/fonts/semibold-hanzi-017.woff2 +0 -0
  95. package/assets/fonts/semibold-hanzi-018.woff2 +0 -0
  96. package/assets/fonts/semibold-hanzi-019.woff2 +0 -0
  97. package/assets/fonts/semibold-hanzi-020.woff2 +0 -0
  98. package/assets/fonts/semibold-hanzi-021.woff2 +0 -0
  99. package/assets/fonts/semibold-hanzi-022.woff2 +0 -0
  100. package/assets/fonts/semibold-hanzi-023.woff2 +0 -0
  101. package/assets/fonts/semibold-hanzi-024.woff2 +0 -0
  102. package/assets/fonts/semibold-hanzi-025.woff2 +0 -0
  103. package/assets/fonts/semibold-hanzi-026.woff2 +0 -0
  104. package/assets/fonts/semibold-hanzi-027.woff2 +0 -0
  105. package/assets/fonts/semibold-hanzi-028.woff2 +0 -0
  106. package/assets/fonts/semibold-hanzi-029.woff2 +0 -0
  107. package/assets/fonts/semibold-hanzi-030.woff2 +0 -0
  108. package/assets/fonts/semibold-hanzi-031.woff2 +0 -0
  109. package/assets/fonts/semibold-hanzi-032.woff2 +0 -0
  110. package/assets/fonts/semibold-hanzi-033.woff2 +0 -0
  111. package/assets/fonts/semibold-hanzi-034.woff2 +0 -0
  112. package/assets/fonts/semibold-hanzi-035.woff2 +0 -0
  113. package/assets/fonts/semibold-hanzi-036.woff2 +0 -0
  114. package/assets/fonts/semibold-hanzi-037.woff2 +0 -0
  115. package/assets/fonts/semibold-hanzi-038.woff2 +0 -0
  116. package/assets/fonts/semibold-hanzi-039.woff2 +0 -0
  117. package/assets/fonts/semibold-hanzi-040.woff2 +0 -0
  118. package/assets/fonts/semibold-hanzi-041.woff2 +0 -0
  119. package/assets/fonts/semibold-hanzi-042.woff2 +0 -0
  120. package/assets/fonts/semibold-hanzi-043.woff2 +0 -0
  121. package/assets/fonts/semibold-hanzi-044.woff2 +0 -0
  122. package/assets/fonts/semibold-hanzi-045.woff2 +0 -0
  123. package/assets/fonts/semibold-hanzi-046.woff2 +0 -0
  124. package/assets/fonts/semibold-hanzi-047.woff2 +0 -0
  125. package/assets/fonts/semibold-hanzi-048.woff2 +0 -0
  126. package/assets/fonts/semibold-hanzi-049.woff2 +0 -0
  127. package/assets/fonts/semibold-hanzi-050.woff2 +0 -0
  128. package/assets/fonts/semibold-hanzi-051.woff2 +0 -0
  129. package/assets/fonts/semibold-hanzi-052.woff2 +0 -0
  130. package/assets/fonts/semibold-hanzi-053.woff2 +0 -0
  131. package/assets/fonts/semibold-hanzi-054.woff2 +0 -0
  132. package/assets/fonts/semibold-hanzi-055.woff2 +0 -0
  133. package/assets/fonts/semibold-hanzi-056.woff2 +0 -0
  134. package/assets/fonts/semibold-hanzi-057.woff2 +0 -0
  135. package/assets/fonts/semibold-hanzi-058.woff2 +0 -0
  136. package/assets/fonts/semibold-hanzi-059.woff2 +0 -0
  137. package/assets/fonts/semibold-hanzi-060.woff2 +0 -0
  138. package/assets/fonts/semibold-hanzi-061.woff2 +0 -0
  139. package/assets/fonts/semibold-hanzi-062.woff2 +0 -0
  140. package/assets/fonts/semibold-hanzi-063.woff2 +0 -0
  141. package/assets/fonts/semibold-hanzi-064.woff2 +0 -0
  142. package/assets/fonts/semibold-latin.woff2 +0 -0
  143. package/assets/fonts/semibold-punctuation.woff2 +0 -0
  144. package/assets/fonts/semibold-symbols.woff2 +0 -0
  145. package/lib/client.js +1026 -437
  146. package/lib/index.js +132 -3
  147. package/lib/types/client/PendingPanel.d.ts +10 -0
  148. package/lib/types/client/code-font.d.ts +64 -0
  149. package/lib/types/client/locales.d.ts +14 -2
  150. package/lib/types/client/panel-memory.d.ts +12 -0
  151. package/lib/types/client/settings.d.ts +15 -0
  152. package/lib/types/client/slots.d.ts +6 -0
  153. package/lib/types/comment-skill.d.ts +1 -1
  154. package/lib/types/font-slices.d.ts +58 -0
  155. package/lib/types/index.d.ts +20 -0
  156. package/lib/types/types.d.ts +6 -0
  157. package/package.json +8 -1
package/README.md CHANGED
@@ -92,4 +92,8 @@ corepack pnpm install
92
92
  pnpm run typecheck # tsc over both faces
93
93
  pnpm run build # emits lib/index.js and lib/client.js
94
94
  pnpm test
95
+ pnpm run fonts:check # the bundled code font: 138 slices, every range covered exactly once
96
+ pnpm run fonts:plan # what a page actually downloads, by how many hanzi it shows
95
97
  ```
98
+
99
+ The bundled font is [JetBrains Maple Mono](https://github.com/SpaceTimee/Fusion-JetBrainsMapleMono) (SIL OFL 1.1), subset and sliced by `scripts/fonts` — see [`assets/fonts/README.md`](assets/fonts/README.md) for the pipeline, the licence and what the slices cost.
package/README.zh.md CHANGED
@@ -92,4 +92,8 @@ corepack pnpm install
92
92
  pnpm run typecheck # 两个编译面的 tsc
93
93
  pnpm run build # 产出 lib/index.js 与 lib/client.js
94
94
  pnpm test
95
+ pnpm run fonts:check # 内置代码字体:138 个切片,每个码位恰好被覆盖一次
96
+ pnpm run fonts:plan # 页面上出现多少汉字时实际会下载多少
95
97
  ```
98
+
99
+ 内置字体是 [JetBrains Maple Mono](https://github.com/SpaceTimee/Fusion-JetBrainsMapleMono)(SIL OFL 1.1),由 `scripts/fonts` 子集化并切片——流水线、许可证与各切片的体积见 [`assets/fonts/README.md`](assets/fonts/README.md)。
@@ -0,0 +1,55 @@
1
+ # FONTLOG
2
+
3
+ What the bundled font is, where it came from, and what was done to it. The
4
+ licence text is in `OFL.txt` next to this file; the machine-readable record of
5
+ the exact upstream build and every slice is in `manifest.json`.
6
+
7
+ ## Upstream
8
+
9
+ - **JetBrains Maple Mono 1.2304.79** — <https://github.com/SpaceTimee/Fusion-JetBrainsMapleMono>
10
+ - archive `JetBrainsMapleMono-XX-XX-XX-XX.zip`, sha256
11
+ `1998cf7047be954c781510d5a651e9d57fadb2ee00bebd80a0719d49eaa50513`
12
+ - the plain build: no Nerd Font icons (`XX`), no narrowed CJK (`XX` — that
13
+ variant is documented as breaking the 2:1 ratio), no hinting (`XX`)
14
+ - itself a fusion of **JetBrains Mono 2.304** (all non-CJK outlines) and
15
+ **Maple Mono 7.9** (the CJK outlines), assembled by FontForge
16
+ - CJK designs ultimately from Resource Han Rounded and Source Han Sans
17
+ - Licence of everything above: **SIL Open Font License 1.1**, with no Reserved
18
+ Font Name declared by any of the three copyright holders. `OFL.txt` carries
19
+ JetBrains Mono (2020), Maple Mono (2022) and Space Time (2025) notices.
20
+
21
+ ## What this repository does to it
22
+
23
+ A **modification** in OFL terms, and therefore recorded here:
24
+
25
+ 1. **Renamed** to `JetBrains Maple Mono for DSH` (the family the CSS declares).
26
+ The name says which face it is; the `for DSH` marker keeps it from colliding
27
+ with a copy of the upstream font the reader may have installed — a locally
28
+ installed font wins over a webfont of the same name, which would leave these
29
+ slices unused and render someone else's build. It also keeps the upstream
30
+ names out of a user-visible primary name, which is what the OFL asks of a
31
+ modified version (Maple Mono declares `Maple Mono` as a Reserved Font Name).
32
+ 2. **Subset** to the characters a code diff can render: Latin and Latin-1,
33
+ Latin Extended-A, general punctuation, arrows, box drawing, geometric shapes
34
+ and dingbats, CJK punctuation and fullwidth forms, and the 20,992 hanzi of
35
+ U+4E00-9FFF. Uncovered on purpose: Korean, CJK Ext-A/B, compatibility
36
+ ideographs — those fall back to the system stack.
37
+ 3. **Sliced** into woff2 files by frequency, so a page fetches the few hundred
38
+ kilobytes it needs instead of the whole block. The order is frozen in
39
+ `ranked-hanzi.txt`; the rule is in `scripts/fonts/build.py`.
40
+ 4. **Converted** to woff2 and stripped of hinting (`--no-hinting`), keeping every
41
+ OpenType feature (`--layout-features='*'`).
42
+
43
+ Both weights are cut from the same slices: Regular for code, SemiBold for
44
+ emphasis, matching `font-weight: 400` and `600`.
45
+
46
+ ## Reproducing
47
+
48
+ ```bash
49
+ python -m scripts.fonts.build --download --extract
50
+ python -m scripts.fonts.build
51
+ python -m scripts.fonts.build --check
52
+ ```
53
+
54
+ `--download` verifies the sha256 above before unpacking, so the slices cannot
55
+ silently come from a different build of the font.
@@ -0,0 +1,95 @@
1
+ Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
2
+ Copyright 2022 The Maple Mono Project Authors (https://github.com/subframe7536/maple-font)
3
+ Copyright 2025 Space Time (https://github.com/SpaceTimee/Fusion-JetBrainsMapleMono)
4
+
5
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
6
+ This license is copied below, and is also available with a FAQ at:
7
+ https://openfontlicense.org
8
+
9
+
10
+ -----------------------------------------------------------
11
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
12
+ -----------------------------------------------------------
13
+
14
+ PREAMBLE
15
+ The goals of the Open Font License (OFL) are to stimulate worldwide
16
+ development of collaborative font projects, to support the font creation
17
+ efforts of academic and linguistic communities, and to provide a free and
18
+ open framework in which fonts may be shared and improved in partnership
19
+ with others.
20
+
21
+ The OFL allows the licensed fonts to be used, studied, modified and
22
+ redistributed freely as long as they are not sold by themselves. The
23
+ fonts, including any derivative works, can be bundled, embedded,
24
+ redistributed and/or sold with any software provided that any reserved
25
+ names are not used by derivative works. The fonts and derivatives,
26
+ however, cannot be released under any other type of license. The
27
+ requirement for fonts to remain under this license does not apply
28
+ to any document created using the fonts or their derivatives.
29
+
30
+ DEFINITIONS
31
+ "Font Software" refers to the set of files released by the Copyright
32
+ Holder(s) under this license and clearly marked as such. This may
33
+ include source files, build scripts and documentation.
34
+
35
+ "Reserved Font Name" refers to any names specified as such after the
36
+ copyright statement(s).
37
+
38
+ "Original Version" refers to the collection of Font Software components as
39
+ distributed by the Copyright Holder(s).
40
+
41
+ "Modified Version" refers to any derivative made by adding to, deleting,
42
+ or substituting -- in part or in whole -- any of the components of the
43
+ Original Version, by changing formats or by porting the Font Software to a
44
+ new environment.
45
+
46
+ "Author" refers to any designer, engineer, programmer, technical
47
+ writer or other person who contributed to the Font Software.
48
+
49
+ PERMISSION & CONDITIONS
50
+ Permission is hereby granted, free of charge, to any person obtaining
51
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
52
+ redistribute, and sell modified and unmodified copies of the Font
53
+ Software, subject to the following conditions:
54
+
55
+ 1) Neither the Font Software nor any of its individual components,
56
+ in Original or Modified Versions, may be sold by itself.
57
+
58
+ 2) Original or Modified Versions of the Font Software may be bundled,
59
+ redistributed and/or sold with any software, provided that each copy
60
+ contains the above copyright notice and this license. These can be
61
+ included either as stand-alone text files, human-readable headers or
62
+ in the appropriate machine-readable metadata fields within text or
63
+ binary files as long as those fields can be easily viewed by the user.
64
+
65
+ 3) No Modified Version of the Font Software may use the Reserved Font
66
+ Name(s) unless explicit written permission is granted by the corresponding
67
+ Copyright Holder. This restriction only applies to the primary font name as
68
+ presented to the users.
69
+
70
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
71
+ Software shall not be used to promote, endorse or advertise any
72
+ Modified Version, except to acknowledge the contribution(s) of the
73
+ Copyright Holder(s) and the Author(s) or with their explicit written
74
+ permission.
75
+
76
+ 5) The Font Software, modified or unmodified, in part or in whole,
77
+ must be distributed entirely under this license, and must not be
78
+ distributed under any other license. The requirement for fonts to
79
+ remain under this license does not apply to any document created
80
+ using the Font Software.
81
+
82
+ TERMINATION
83
+ This license becomes null and void if any of the above conditions are
84
+ not met.
85
+
86
+ DISCLAIMER
87
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
88
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
89
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
90
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
91
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
92
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
93
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
94
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
95
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,123 @@
1
+ # The bundled code font
2
+
3
+ The panel renders code and Chinese comments on one character grid, which needs a
4
+ font where one CJK glyph is exactly twice one Latin glyph. No system stack does
5
+ that on Windows or Android: the shell's own code font is
6
+ `"SF Mono", "JetBrains Mono", …, "PingFang SC", "Microsoft YaHei"`, so Latin
7
+ comes from a monospace face and hanzi from a proportional one, and every
8
+ Chinese comment drifts out of column.
9
+
10
+ So the font ships with the plugin. It is
11
+ [JetBrains Maple Mono](https://github.com/SpaceTimee/Fusion-JetBrainsMapleMono)
12
+ (JetBrains Mono for Latin, Maple Mono for CJK, fused upstream so the 2:1 ratio
13
+ holds by construction), subset into sliced woff2 files and served by the host.
14
+
15
+ ## What is committed
16
+
17
+ | path | what it is |
18
+ | --- | --- |
19
+ | `ranked-hanzi.txt` | the 20,992 hanzi of U+4E00-9FFF in frequency order — the input the slice plan is built on |
20
+ | `regular-*.woff2`, `semibold-*.woff2` | the slices themselves (`regular-latin.woff2`, `regular-hanzi-000.woff2`, …) |
21
+ | `manifest.json` | every slice's `unicode-range`, byte size, weight, and the pinned upstream archive |
22
+ | `OFL.txt` | the font's licence, which must travel with it |
23
+
24
+ The full TTFs and the upstream archive are **not** committed: they are 17 MB and
25
+ 141 MB, they are reproducible from the pinned URL and checksum in
26
+ `manifest.json`, and `scripts/fonts/build.py` fetches them into `vendor/`
27
+ (git-ignored) on demand. Keeping the whole font locally is still the point of
28
+ that cache — re-slicing must never require a network round trip, and after one
29
+ `--download` it does not.
30
+
31
+ ## Rebuilding
32
+
33
+ ```bash
34
+ python -m pip install fonttools brotli wordfreq jieba
35
+ python -m scripts.fonts.build --download --extract # once: fills assets/fonts/vendor
36
+ python -m scripts.fonts.build # writes the slices + manifest
37
+ python -m scripts.fonts.build --check # ranges cover U+4E00-9FFF exactly once
38
+ python -m scripts.fonts.build --plan # what a page actually pulls
39
+ ```
40
+
41
+ `--download` verifies the archive's sha256 before unpacking, so a re-slice
42
+ cannot silently pick up a different font. `--check` is what CI-able confidence
43
+ looks like here: it re-reads the committed manifest, re-derives the covered
44
+ codepoints from every `unicode-range`, and fails on a gap, an overlap, or a byte
45
+ size that no longer matches the file on disk.
46
+
47
+ The frequency order is a separate, frozen input:
48
+
49
+ ```bash
50
+ python -m scripts.fonts.rank --out assets/fonts/ranked-hanzi.txt # regenerate (deliberate)
51
+ python -m scripts.fonts.rank --check assets/fonts/ranked-hanzi.txt # verify coverage
52
+ ```
53
+
54
+ ## Why the slices look like this
55
+
56
+ A browser downloads a whole `@font-face` slice as soon as **one** character in
57
+ its `unicode-range` appears on the page. Measured on this font:
58
+
59
+ - the whole hanzi block as one slice: **5,431,736 B** — one Chinese comment would
60
+ cost 5.4 MB;
61
+ - four equal quarters by codepoint: **~5.8 MB total, and no better per page** —
62
+ the 60 commonest hanzi are scattered across all four, because codepoint order
63
+ has nothing to do with how often a character is used;
64
+ - frequency order plus a byte cap: a page using the commonest 200 hanzi pulls
65
+ **one small slice** (the seed), a page using 3,000 pulls a few, and one rare
66
+ character costs at most one capped slice (120 KB).
67
+
68
+ So the plan is a small seed slice (the 300 commonest hanzi) followed by slices
69
+ capped at 120,000 B each. Both numbers live in `scripts/fonts/build.py`; raising
70
+ the cap means fewer files, lowering it means a cheaper worst case. Changing
71
+ either re-slices the same frozen order, which is the point of committing it.
72
+
73
+ ## What the CSS does with it
74
+
75
+ One rule in `src/client/code-font.ts`: `.lines{font-family:<the bundled family>, <the
76
+ shell's stack>}`. `.lines` is the diff's code table, so the grid lands on the code
77
+ and nothing else — comment bubbles, the file list and the panel's chrome keep the
78
+ shell's font stack.
79
+
80
+ **Off until asked for.** The switch is in the plugin's DSH Settings section
81
+ (`等宽 CJK 字体` / "Monospaced CJK font"), stored as `diff-approval:code-font`, and
82
+ it defaults to off because the slices are traffic the reader pays for: tens of
83
+ kilobytes for ordinary Chinese, at most ~120 KB per slice for a rare character,
84
+ 33 KB for pure ASCII. Off means nothing is fetched at all — no manifest request,
85
+ no `@font-face` — so the default panel is exactly what it was before this
86
+ existed. A browser fetches a `@font-face` only when a rule uses it, which is what
87
+ keeps an enabled pure-ASCII file down to the one Latin slice.
88
+
89
+ `font-display: swap` rather than `block`: the code is readable in the system font
90
+ immediately, and swapping when the slices land changes the column width, never
91
+ the row height that the virtual window and the jump math are built on.
92
+
93
+ ## Two things the font forces on the build
94
+
95
+ - **The full feature set is kept when slicing.** `pyftsubset`'s default prunes a
96
+ code font down to `calt` and `locl` and drops GPOS entirely, which would take
97
+ the slashed zero (`zero`), the character variants (`cv*`, `ss*`) and accent
98
+ composition with it. `--layout-features='*'` costs ~20% on the Latin slice and
99
+ is why `scripts/fonts/build.py` does not use the defaults.
100
+ - **The family name is our own** (`DSH Code Mono`), declared by
101
+ `src/font-slices.ts`. Two reasons: the upstream name embeds the JetBrains
102
+ trademark, which OFL does not grant rights to; and a separately installed copy
103
+ of the upstream font would otherwise win over the webfont, silently replacing
104
+ the slices the panel counts on. The copyright lines and the OFL text still
105
+ travel with the files.
106
+
107
+ The face keeps its own `calt`, so `->` and `=>` draw as arrows — the same thing
108
+ JetBrains Mono already does everywhere else in the UI. The upstream project also
109
+ ships a no-ligature build (`…-NL-…`) if that ever changes; using it means
110
+ re-slicing, not a CSS override, because `calt` is what carries the arrows.
111
+
112
+ Unhinted on purpose: Windows browser rendering goes through DirectWrite, where
113
+ Google Fonts ships unhinted too, and dropping `cvt `/`fpgm`/`prep` makes every
114
+ slice smaller.
115
+
116
+ ## Licence
117
+
118
+ SIL Open Font License 1.1, no Reserved Font Name declared by any of the three
119
+ copyright holders (JetBrains Mono, Maple Mono, and the fusion project), so
120
+ subsetting and redistribution are permitted provided `OFL.txt` and the
121
+ copyright notices travel with the files — which is why `OFL.txt` sits here.
122
+ `fontTools.subset` strips the license name records out of a woff2, so the file
123
+ is not optional: the slices do not carry the notice themselves.