reamkit 0.1.0-alpha.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 (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/esm/bidi/algorithm.d.ts +9 -0
  4. package/dist/esm/bidi/algorithm.js +458 -0
  5. package/dist/esm/bidi/char-types.d.ts +2 -0
  6. package/dist/esm/bidi/char-types.js +439 -0
  7. package/dist/esm/bidi/index.d.ts +14 -0
  8. package/dist/esm/bidi/index.js +25 -0
  9. package/dist/esm/converter/docx-to-pdf.d.ts +15 -0
  10. package/dist/esm/converter/docx-to-pdf.js +227 -0
  11. package/dist/esm/converter/index.d.ts +4 -0
  12. package/dist/esm/converter/index.js +2 -0
  13. package/dist/esm/converter/xlsx-to-pdf.d.ts +13 -0
  14. package/dist/esm/converter/xlsx-to-pdf.js +515 -0
  15. package/dist/esm/crypto/asn1.d.ts +23 -0
  16. package/dist/esm/crypto/asn1.js +123 -0
  17. package/dist/esm/crypto/cms.d.ts +9 -0
  18. package/dist/esm/crypto/cms.js +34 -0
  19. package/dist/esm/crypto/index.d.ts +2 -0
  20. package/dist/esm/crypto/index.js +1 -0
  21. package/dist/esm/document-model/index.d.ts +1 -0
  22. package/dist/esm/document-model/index.js +0 -0
  23. package/dist/esm/document-model/types.d.ts +403 -0
  24. package/dist/esm/font/arabic-joining.d.ts +4 -0
  25. package/dist/esm/font/arabic-joining.js +97 -0
  26. package/dist/esm/font/binary-reader.d.ts +13 -0
  27. package/dist/esm/font/binary-reader.js +44 -0
  28. package/dist/esm/font/font-registry.d.ts +19 -0
  29. package/dist/esm/font/font-registry.js +39 -0
  30. package/dist/esm/font/index.d.ts +7 -0
  31. package/dist/esm/font/opentype-layout.d.ts +21 -0
  32. package/dist/esm/font/opentype-layout.js +329 -0
  33. package/dist/esm/font/ttf-parser.d.ts +29 -0
  34. package/dist/esm/font/ttf-parser.js +290 -0
  35. package/dist/esm/font/ttf-subset.d.ts +3 -0
  36. package/dist/esm/font/ttf-subset.js +201 -0
  37. package/dist/esm/fonts/index.d.ts +2 -0
  38. package/dist/esm/fonts/remote-fonts.d.ts +13 -0
  39. package/dist/esm/fonts/remote-fonts.js +94 -0
  40. package/dist/esm/hyphenation/index.d.ts +10 -0
  41. package/dist/esm/hyphenation/index.js +38 -0
  42. package/dist/esm/hyphenation/liang.d.ts +10 -0
  43. package/dist/esm/hyphenation/liang.js +79 -0
  44. package/dist/esm/hyphenation/patterns-en-us.d.ts +2 -0
  45. package/dist/esm/hyphenation/patterns-en-us.js +5 -0
  46. package/dist/esm/hyphenation/patterns-ru.d.ts +2 -0
  47. package/dist/esm/hyphenation/patterns-ru.js +5 -0
  48. package/dist/esm/index.d.ts +12 -0
  49. package/dist/esm/index.js +13 -0
  50. package/dist/esm/line-breaker/index.d.ts +2 -0
  51. package/dist/esm/line-breaker/knuth-plass.d.ts +30 -0
  52. package/dist/esm/line-breaker/knuth-plass.js +172 -0
  53. package/dist/esm/numbering/index.d.ts +1 -0
  54. package/dist/esm/numbering/state.d.ts +6 -0
  55. package/dist/esm/numbering/state.js +83 -0
  56. package/dist/esm/ooxml/drawingml/chart-parser.d.ts +3 -0
  57. package/dist/esm/ooxml/drawingml/chart-parser.js +218 -0
  58. package/dist/esm/ooxml/drawingml/colors.d.ts +17 -0
  59. package/dist/esm/ooxml/drawingml/colors.js +125 -0
  60. package/dist/esm/ooxml/drawingml/theme-parser.d.ts +1 -0
  61. package/dist/esm/ooxml/drawingml/theme-parser.js +55 -0
  62. package/dist/esm/ooxml/index.d.ts +1 -0
  63. package/dist/esm/ooxml/math/omml-parser.d.ts +4 -0
  64. package/dist/esm/ooxml/math/omml-parser.js +217 -0
  65. package/dist/esm/ooxml/spreadsheet/cell-reference.d.ts +6 -0
  66. package/dist/esm/ooxml/spreadsheet/cell-reference.js +26 -0
  67. package/dist/esm/ooxml/spreadsheet/defined-name-ref.d.ts +11 -0
  68. package/dist/esm/ooxml/spreadsheet/defined-name-ref.js +64 -0
  69. package/dist/esm/ooxml/spreadsheet/index.d.ts +12 -0
  70. package/dist/esm/ooxml/spreadsheet/index.js +7 -0
  71. package/dist/esm/ooxml/spreadsheet/number-format.d.ts +1 -0
  72. package/dist/esm/ooxml/spreadsheet/number-format.js +438 -0
  73. package/dist/esm/ooxml/spreadsheet/shared-strings-parser.d.ts +1 -0
  74. package/dist/esm/ooxml/spreadsheet/shared-strings-parser.js +47 -0
  75. package/dist/esm/ooxml/spreadsheet/styles-parser.d.ts +52 -0
  76. package/dist/esm/ooxml/spreadsheet/styles-parser.js +225 -0
  77. package/dist/esm/ooxml/spreadsheet/workbook-parser.d.ts +16 -0
  78. package/dist/esm/ooxml/spreadsheet/workbook-parser.js +90 -0
  79. package/dist/esm/ooxml/spreadsheet/worksheet-parser.d.ts +60 -0
  80. package/dist/esm/ooxml/spreadsheet/worksheet-parser.js +311 -0
  81. package/dist/esm/ooxml/wordproc/document-parser.d.ts +9 -0
  82. package/dist/esm/ooxml/wordproc/document-parser.js +274 -0
  83. package/dist/esm/ooxml/wordproc/drawing-parser.d.ts +33 -0
  84. package/dist/esm/ooxml/wordproc/drawing-parser.js +374 -0
  85. package/dist/esm/ooxml/wordproc/font-table.d.ts +15 -0
  86. package/dist/esm/ooxml/wordproc/font-table.js +82 -0
  87. package/dist/esm/ooxml/wordproc/index.d.ts +10 -0
  88. package/dist/esm/ooxml/wordproc/index.js +9 -0
  89. package/dist/esm/ooxml/wordproc/numbering-parser.d.ts +3 -0
  90. package/dist/esm/ooxml/wordproc/numbering-parser.js +89 -0
  91. package/dist/esm/ooxml/wordproc/paragraph-properties.d.ts +2 -0
  92. package/dist/esm/ooxml/wordproc/paragraph-properties.js +85 -0
  93. package/dist/esm/ooxml/wordproc/po-helpers.d.ts +14 -0
  94. package/dist/esm/ooxml/wordproc/po-helpers.js +76 -0
  95. package/dist/esm/ooxml/wordproc/po-to-flat.d.ts +2 -0
  96. package/dist/esm/ooxml/wordproc/po-to-flat.js +28 -0
  97. package/dist/esm/ooxml/wordproc/run-properties.d.ts +2 -0
  98. package/dist/esm/ooxml/wordproc/run-properties.js +82 -0
  99. package/dist/esm/ooxml/wordproc/settings-parser.d.ts +5 -0
  100. package/dist/esm/ooxml/wordproc/settings-parser.js +26 -0
  101. package/dist/esm/ooxml/wordproc/styles-parser.d.ts +3 -0
  102. package/dist/esm/ooxml/wordproc/styles-parser.js +67 -0
  103. package/dist/esm/ooxml/wordproc/table-parser.d.ts +3 -0
  104. package/dist/esm/ooxml/wordproc/table-parser.js +162 -0
  105. package/dist/esm/ooxml/wordproc/text-extractor.d.ts +1 -0
  106. package/dist/esm/ooxml/wordproc/text-extractor.js +1 -0
  107. package/dist/esm/ooxml/wordproc/xml-helpers.d.ts +9 -0
  108. package/dist/esm/ooxml/wordproc/xml-helpers.js +36 -0
  109. package/dist/esm/opc/core-properties.d.ts +11 -0
  110. package/dist/esm/opc/core-properties.js +51 -0
  111. package/dist/esm/opc/index.d.ts +5 -0
  112. package/dist/esm/opc/index.js +3 -0
  113. package/dist/esm/opc/package.d.ts +26 -0
  114. package/dist/esm/opc/package.js +113 -0
  115. package/dist/esm/opc/relationship-types.d.ts +3 -0
  116. package/dist/esm/opc/relationship-types.js +4 -0
  117. package/dist/esm/opc/relationships.d.ts +7 -0
  118. package/dist/esm/opc/relationships.js +28 -0
  119. package/dist/esm/pdf/arc-to-bezier.d.ts +5 -0
  120. package/dist/esm/pdf/arc-to-bezier.js +58 -0
  121. package/dist/esm/pdf/builtin-fonts.d.ts +2 -0
  122. package/dist/esm/pdf/chart-geometry.d.ts +64 -0
  123. package/dist/esm/pdf/chart-geometry.js +674 -0
  124. package/dist/esm/pdf/cid-font.d.ts +15 -0
  125. package/dist/esm/pdf/cid-font.js +174 -0
  126. package/dist/esm/pdf/embedded-file.d.ts +11 -0
  127. package/dist/esm/pdf/embedded-file.js +23 -0
  128. package/dist/esm/pdf/icc-profile.d.ts +1 -0
  129. package/dist/esm/pdf/icc-profile.js +166 -0
  130. package/dist/esm/pdf/image-xobject.d.ts +13 -0
  131. package/dist/esm/pdf/image-xobject.js +335 -0
  132. package/dist/esm/pdf/index.d.ts +11 -0
  133. package/dist/esm/pdf/index.js +5 -0
  134. package/dist/esm/pdf/math-layout.d.ts +45 -0
  135. package/dist/esm/pdf/math-layout.js +1138 -0
  136. package/dist/esm/pdf/objects.d.ts +32 -0
  137. package/dist/esm/pdf/objects.js +54 -0
  138. package/dist/esm/pdf/preset-geometry.d.ts +6 -0
  139. package/dist/esm/pdf/preset-geometry.js +199 -0
  140. package/dist/esm/pdf/serialize.d.ts +3 -0
  141. package/dist/esm/pdf/serialize.js +54 -0
  142. package/dist/esm/pdf/signature.d.ts +25 -0
  143. package/dist/esm/pdf/signature.js +126 -0
  144. package/dist/esm/pdf/struct-tree.d.ts +31 -0
  145. package/dist/esm/pdf/struct-tree.js +109 -0
  146. package/dist/esm/pdf/styled-page-renderer.d.ts +43 -0
  147. package/dist/esm/pdf/styled-page-renderer.js +2317 -0
  148. package/dist/esm/pdf/text-encoding.d.ts +2 -0
  149. package/dist/esm/pdf/text-page-renderer.d.ts +16 -0
  150. package/dist/esm/pdf/text-page-renderer.js +4 -0
  151. package/dist/esm/pdf/vector-graphics.d.ts +46 -0
  152. package/dist/esm/pdf/vector-graphics.js +103 -0
  153. package/dist/esm/pdf/writer.d.ts +10 -0
  154. package/dist/esm/pdf/writer.js +81 -0
  155. package/dist/esm/pdf/xmp.d.ts +13 -0
  156. package/dist/esm/pdf/xmp.js +38 -0
  157. package/dist/esm/style-cascade/index.d.ts +3 -0
  158. package/dist/esm/style-cascade/resolver.d.ts +4 -0
  159. package/dist/esm/style-cascade/resolver.js +96 -0
  160. package/dist/esm/style-cascade/types.d.ts +29 -0
  161. package/dist/esm/style-cascade/types.js +26 -0
  162. package/package.json +90 -0
@@ -0,0 +1,1138 @@
1
+ //#region src/pdf/math-layout.ts
2
+ var ASCENT = .72;
3
+ var DESCENT = .2;
4
+ var AXIS = .26;
5
+ var BAR_THICK = .045;
6
+ var FRAC_GAP = .15;
7
+ var FRAC_PAD = .12;
8
+ var SCRIPT_SIZE = .7;
9
+ function variantStyle(v) {
10
+ return {
11
+ bold: v === "bold" || v === "boldItalic",
12
+ italic: v === "italic" || v === "boldItalic"
13
+ };
14
+ }
15
+ var variantOf = (italic, bold) => bold ? italic ? "boldItalic" : "bold" : italic ? "italic" : "regular";
16
+ function isAutoItalic(ch) {
17
+ return /[A-Za-z]/.test(ch) || ch >= "α" && ch <= "ω" || ch >= "Α" && ch <= "Ω";
18
+ }
19
+ function runCharVariant(ch, run) {
20
+ const bold = run.bold ?? false;
21
+ return variantOf(run.nor ? false : run.italic ?? isAutoItalic(ch), bold);
22
+ }
23
+ function layoutMath(node, ctx, measure) {
24
+ switch (node.type) {
25
+ case "run": return layoutRun(node, ctx, measure);
26
+ case "row": return layoutRow(node, ctx, measure);
27
+ case "fraction": return layoutFraction(node, ctx, measure);
28
+ case "script": return layoutScript(node, ctx, measure);
29
+ case "radical": return layoutRadical(node, ctx, measure);
30
+ case "nary": return layoutNary(node, ctx, measure);
31
+ case "func": return layoutFunc(node, ctx, measure);
32
+ case "limit": return layoutLimit(node, ctx, measure);
33
+ case "delimiter": return layoutDelimiter(node, ctx, measure);
34
+ case "matrix": return layoutMatrix(node, ctx, measure);
35
+ case "eqArr": return layoutEqArray(node, ctx, measure);
36
+ case "accent": return layoutAccent(node, ctx, measure);
37
+ case "bar": return layoutBar(node, ctx, measure);
38
+ case "groupChr": return layoutGroupChr(node, ctx, measure);
39
+ default: return emptyBox();
40
+ }
41
+ }
42
+ var emptyBox = () => ({
43
+ width: 0,
44
+ ascent: 0,
45
+ descent: 0,
46
+ items: []
47
+ });
48
+ var MATH_BINARY = new Set([
49
+ "+",
50
+ "−",
51
+ "-",
52
+ "±",
53
+ "∓",
54
+ "×",
55
+ "÷",
56
+ "⋅",
57
+ "∗",
58
+ "⊕",
59
+ "⊗",
60
+ "∘"
61
+ ]);
62
+ var MATH_RELATION = new Set([
63
+ "=",
64
+ "≠",
65
+ "<",
66
+ ">",
67
+ "≤",
68
+ "≥",
69
+ "≈",
70
+ "≡",
71
+ "≅",
72
+ "∝",
73
+ "→",
74
+ "←",
75
+ "↔",
76
+ "∈",
77
+ "∉",
78
+ "⊂",
79
+ "⊃",
80
+ "⊆",
81
+ "⊇",
82
+ "≪",
83
+ "≫"
84
+ ]);
85
+ function isSpacedOp(ch, i, n) {
86
+ return (MATH_BINARY.has(ch) || MATH_RELATION.has(ch)) && i > 0 && i < n - 1;
87
+ }
88
+ function layoutRun(run, ctx, measure) {
89
+ const size = ctx.sizePt;
90
+ const chars = [...run.text];
91
+ if (chars.length === 0) return emptyBox();
92
+ const med = .2 * size;
93
+ const items = [];
94
+ let x = 0;
95
+ let i = 0;
96
+ while (i < chars.length) {
97
+ const v = runCharVariant(chars[i], run);
98
+ if (isSpacedOp(chars[i], i, chars.length)) {
99
+ x += med;
100
+ items.push({
101
+ kind: "glyph",
102
+ x,
103
+ y: 0,
104
+ text: chars[i],
105
+ variant: v,
106
+ sizePt: size
107
+ });
108
+ x += measure(chars[i], size, v) + med;
109
+ i++;
110
+ continue;
111
+ }
112
+ let seg = "";
113
+ let j = i;
114
+ while (j < chars.length && runCharVariant(chars[j], run) === v && !isSpacedOp(chars[j], j, chars.length)) {
115
+ seg += chars[j];
116
+ j++;
117
+ }
118
+ items.push({
119
+ kind: "glyph",
120
+ x,
121
+ y: 0,
122
+ text: seg,
123
+ variant: v,
124
+ sizePt: size
125
+ });
126
+ x += measure(seg, size, v);
127
+ i = j;
128
+ }
129
+ return {
130
+ width: x,
131
+ ascent: size * ASCENT,
132
+ descent: size * DESCENT,
133
+ items
134
+ };
135
+ }
136
+ function layoutRow(node, ctx, measure) {
137
+ let x = 0;
138
+ let ascent = 0;
139
+ let descent = 0;
140
+ const items = [];
141
+ for (const child of node.children) {
142
+ const box = layoutMath(child, ctx, measure);
143
+ for (const it of shiftItems(box.items, x, 0)) items.push(it);
144
+ x += box.width;
145
+ ascent = Math.max(ascent, box.ascent);
146
+ descent = Math.max(descent, box.descent);
147
+ }
148
+ return {
149
+ width: x,
150
+ ascent,
151
+ descent,
152
+ items
153
+ };
154
+ }
155
+ function layoutFraction(node, ctx, measure) {
156
+ const size = ctx.sizePt;
157
+ const numBox = layoutMath(node.num, ctx, measure);
158
+ const denBox = layoutMath(node.den, ctx, measure);
159
+ const pad = FRAC_PAD * size;
160
+ const width = Math.max(numBox.width, denBox.width) + 2 * pad;
161
+ const barThick = Math.max(BAR_THICK * size, .5);
162
+ const axis = AXIS * size;
163
+ const gap = FRAC_GAP * size;
164
+ const items = [];
165
+ const numBaseY = axis + barThick / 2 + gap + numBox.descent;
166
+ const numX = (width - numBox.width) / 2;
167
+ for (const it of shiftItems(numBox.items, numX, numBaseY)) items.push(it);
168
+ const denBaseY = axis - barThick / 2 - gap - denBox.ascent;
169
+ const denX = (width - denBox.width) / 2;
170
+ for (const it of shiftItems(denBox.items, denX, denBaseY)) items.push(it);
171
+ if (!node.barless) items.push({
172
+ kind: "rule",
173
+ x: pad * .5,
174
+ y: axis - barThick / 2,
175
+ w: width - pad,
176
+ h: barThick
177
+ });
178
+ return {
179
+ width,
180
+ ascent: numBaseY + numBox.ascent,
181
+ descent: -(denBaseY - denBox.descent),
182
+ items
183
+ };
184
+ }
185
+ function layoutScript(node, ctx, measure) {
186
+ const size = ctx.sizePt;
187
+ const scriptSize = size * SCRIPT_SIZE;
188
+ const baseBox = layoutMath(node.base, ctx, measure);
189
+ const supBox = node.sup ? layoutMath(node.sup, { sizePt: scriptSize }, measure) : void 0;
190
+ const subBox = node.sub ? layoutMath(node.sub, { sizePt: scriptSize }, measure) : void 0;
191
+ const kern = .05 * size;
192
+ const scriptW = Math.max(supBox?.width ?? 0, subBox?.width ?? 0);
193
+ const baseX = node.pre ? scriptW + kern : 0;
194
+ const scriptX = node.pre ? 0 : baseBox.width + kern;
195
+ const items = [...shiftItems(baseBox.items, baseX, 0)];
196
+ let ascent = baseBox.ascent;
197
+ let descent = baseBox.descent;
198
+ if (supBox) {
199
+ const supShift = Math.max(baseBox.ascent - .25 * scriptSize, .45 * size);
200
+ for (const it of shiftItems(supBox.items, scriptX, supShift)) items.push(it);
201
+ ascent = Math.max(ascent, supShift + supBox.ascent);
202
+ }
203
+ if (subBox) {
204
+ const subShift = Math.max(baseBox.descent + .2 * scriptSize, .18 * size);
205
+ for (const it of shiftItems(subBox.items, scriptX, -subShift)) items.push(it);
206
+ descent = Math.max(descent, subShift + subBox.descent);
207
+ }
208
+ return {
209
+ width: baseBox.width + kern + scriptW,
210
+ ascent,
211
+ descent,
212
+ items
213
+ };
214
+ }
215
+ function layoutRadical(node, ctx, measure) {
216
+ const size = ctx.sizePt;
217
+ const radBox = layoutMath(node.radicand, ctx, measure);
218
+ const rule = Math.max(.05 * size, .6);
219
+ const gap = .12 * size;
220
+ const radAsc = radBox.ascent;
221
+ const radDesc = radBox.descent;
222
+ const radH = radAsc + radDesc;
223
+ const barY = radAsc + gap;
224
+ const surdW = Math.max(.5 * size, radH * .45);
225
+ const bottom = -radDesc - rule * .5;
226
+ const pad = .12 * size;
227
+ const items = [];
228
+ let degW = 0;
229
+ if (node.degree) {
230
+ const degBox = layoutMath(node.degree, { sizePt: size * .5 }, measure);
231
+ degW = degBox.width;
232
+ for (const it of shiftItems(degBox.items, 0, barY * .35)) items.push(it);
233
+ }
234
+ const surdX = degW;
235
+ const surd = [
236
+ {
237
+ op: "move",
238
+ x: surdX,
239
+ y: barY - radH * .5
240
+ },
241
+ {
242
+ op: "line",
243
+ x: surdX + surdW * .45,
244
+ y: bottom
245
+ },
246
+ {
247
+ op: "line",
248
+ x: surdX + surdW * .85,
249
+ y: barY
250
+ },
251
+ {
252
+ op: "line",
253
+ x: surdX + surdW + radBox.width + pad,
254
+ y: barY
255
+ }
256
+ ];
257
+ items.push({
258
+ kind: "path",
259
+ segments: surd,
260
+ strokeWidthPt: Math.max(rule, .8)
261
+ });
262
+ for (const it of shiftItems(radBox.items, surdX + surdW, 0)) items.push(it);
263
+ return {
264
+ width: degW + surdW + radBox.width + pad,
265
+ ascent: barY + rule,
266
+ descent: radDesc + rule,
267
+ items
268
+ };
269
+ }
270
+ var NARY_AXIS = .28;
271
+ var SUM_LIKE = new Set([
272
+ "∑",
273
+ "∏",
274
+ "∐",
275
+ "⋃",
276
+ "⋂",
277
+ "⋁",
278
+ "⋀",
279
+ "⨀",
280
+ "⨁",
281
+ "⨂"
282
+ ]);
283
+ function layoutBigOp(op, size, measure) {
284
+ const axisC = NARY_AXIS * size;
285
+ if (op === "∑") {
286
+ const half = size * .75;
287
+ const top = axisC + half;
288
+ const bot = axisC - half;
289
+ const w = size * .85;
290
+ const segs = [
291
+ {
292
+ op: "move",
293
+ x: w,
294
+ y: top
295
+ },
296
+ {
297
+ op: "line",
298
+ x: 0,
299
+ y: top
300
+ },
301
+ {
302
+ op: "line",
303
+ x: w * .52,
304
+ y: axisC
305
+ },
306
+ {
307
+ op: "line",
308
+ x: 0,
309
+ y: bot
310
+ },
311
+ {
312
+ op: "line",
313
+ x: w,
314
+ y: bot
315
+ }
316
+ ];
317
+ return bigOpBox(w + size * .08, top, bot, segs, Math.max(size * .075, 1));
318
+ }
319
+ if (op === "∏") {
320
+ const half = size * .75;
321
+ const top = axisC + half;
322
+ const bot = axisC - half;
323
+ const w = size * .9;
324
+ const segs = [
325
+ {
326
+ op: "move",
327
+ x: 0,
328
+ y: top
329
+ },
330
+ {
331
+ op: "line",
332
+ x: w,
333
+ y: top
334
+ },
335
+ {
336
+ op: "move",
337
+ x: w * .22,
338
+ y: top
339
+ },
340
+ {
341
+ op: "line",
342
+ x: w * .22,
343
+ y: bot
344
+ },
345
+ {
346
+ op: "move",
347
+ x: w * .78,
348
+ y: top
349
+ },
350
+ {
351
+ op: "line",
352
+ x: w * .78,
353
+ y: bot
354
+ }
355
+ ];
356
+ return bigOpBox(w + size * .08, top, bot, segs, Math.max(size * .08, 1));
357
+ }
358
+ if (op === "∫" || op === "∮") {
359
+ const half = size * .95;
360
+ const top = axisC + half;
361
+ const bot = axisC - half;
362
+ const w = size * .5;
363
+ const segs = [
364
+ {
365
+ op: "move",
366
+ x: w * .72,
367
+ y: top
368
+ },
369
+ {
370
+ op: "cubic",
371
+ x1: w * .2,
372
+ y1: top,
373
+ x2: w * .78,
374
+ y2: axisC,
375
+ x: w * .42,
376
+ y: axisC
377
+ },
378
+ {
379
+ op: "cubic",
380
+ x1: w * .06,
381
+ y1: axisC,
382
+ x2: w * .64,
383
+ y2: bot,
384
+ x: w * .12,
385
+ y: bot
386
+ }
387
+ ];
388
+ return bigOpBox(w + size * .06, top, bot, segs, Math.max(size * .06, .9));
389
+ }
390
+ const opSize = size * 1.4;
391
+ return {
392
+ width: measure(op, opSize, "regular"),
393
+ ascent: opSize * ASCENT,
394
+ descent: opSize * DESCENT,
395
+ items: [{
396
+ kind: "glyph",
397
+ x: 0,
398
+ y: 0,
399
+ text: op,
400
+ variant: "regular",
401
+ sizePt: opSize
402
+ }]
403
+ };
404
+ }
405
+ function bigOpBox(width, top, bot, segments, strokeWidthPt) {
406
+ return {
407
+ width,
408
+ ascent: top,
409
+ descent: -bot,
410
+ items: [{
411
+ kind: "path",
412
+ segments,
413
+ strokeWidthPt
414
+ }]
415
+ };
416
+ }
417
+ function layoutNary(node, ctx, measure) {
418
+ const size = ctx.sizePt;
419
+ const opBox = layoutBigOp(node.op, size, measure);
420
+ const scriptSize = size * SCRIPT_SIZE;
421
+ const subBox = node.sub ? layoutMath(node.sub, { sizePt: scriptSize }, measure) : void 0;
422
+ const supBox = node.sup ? layoutMath(node.sup, { sizePt: scriptSize }, measure) : void 0;
423
+ const bodyBox = layoutMath(node.body, ctx, measure);
424
+ const undOvr = node.limLoc === "undOvr" || node.limLoc === void 0 && SUM_LIKE.has(node.op);
425
+ const items = [];
426
+ let ascent = opBox.ascent;
427
+ let descent = opBox.descent;
428
+ let opGroupW;
429
+ if (undOvr) {
430
+ const stackW = Math.max(opBox.width, subBox?.width ?? 0, supBox?.width ?? 0);
431
+ for (const it of shiftItems(opBox.items, (stackW - opBox.width) / 2, 0)) items.push(it);
432
+ const gap = .06 * size;
433
+ if (supBox) {
434
+ const supY = opBox.ascent + gap + supBox.descent;
435
+ for (const it of shiftItems(supBox.items, (stackW - supBox.width) / 2, supY)) items.push(it);
436
+ ascent = Math.max(ascent, supY + supBox.ascent);
437
+ }
438
+ if (subBox) {
439
+ const subY = -(opBox.descent + gap + subBox.ascent);
440
+ for (const it of shiftItems(subBox.items, (stackW - subBox.width) / 2, subY)) items.push(it);
441
+ descent = Math.max(descent, -(subY - subBox.descent));
442
+ }
443
+ opGroupW = stackW;
444
+ } else {
445
+ for (const it of opBox.items) items.push(it);
446
+ const scriptX = opBox.width + .02 * size;
447
+ let scriptW = 0;
448
+ if (supBox) {
449
+ const supY = opBox.ascent - .4 * scriptSize;
450
+ for (const it of shiftItems(supBox.items, scriptX, supY)) items.push(it);
451
+ ascent = Math.max(ascent, supY + supBox.ascent);
452
+ scriptW = Math.max(scriptW, supBox.width);
453
+ }
454
+ if (subBox) {
455
+ const subY = -opBox.descent + .2 * scriptSize - subBox.ascent;
456
+ for (const it of shiftItems(subBox.items, scriptX, subY)) items.push(it);
457
+ descent = Math.max(descent, -(subY - subBox.descent));
458
+ scriptW = Math.max(scriptW, subBox.width);
459
+ }
460
+ opGroupW = opBox.width + .02 * size + scriptW;
461
+ }
462
+ const bodyX = opGroupW + .12 * size;
463
+ for (const it of shiftItems(bodyBox.items, bodyX, 0)) items.push(it);
464
+ return {
465
+ width: bodyX + bodyBox.width,
466
+ ascent: Math.max(ascent, bodyBox.ascent),
467
+ descent: Math.max(descent, bodyBox.descent),
468
+ items
469
+ };
470
+ }
471
+ function layoutFunc(node, ctx, measure) {
472
+ const nameBox = layoutMath(node.name, ctx, measure);
473
+ const bodyBox = layoutMath(node.body, ctx, measure);
474
+ const sp = .16 * ctx.sizePt;
475
+ const items = [...nameBox.items, ...shiftItems(bodyBox.items, nameBox.width + sp, 0)];
476
+ return {
477
+ width: nameBox.width + sp + bodyBox.width,
478
+ ascent: Math.max(nameBox.ascent, bodyBox.ascent),
479
+ descent: Math.max(nameBox.descent, bodyBox.descent),
480
+ items
481
+ };
482
+ }
483
+ function layoutLimit(node, ctx, measure) {
484
+ const size = ctx.sizePt;
485
+ const baseBox = layoutMath(node.base, ctx, measure);
486
+ const limBox = layoutMath(node.lim, { sizePt: size * SCRIPT_SIZE }, measure);
487
+ const w = Math.max(baseBox.width, limBox.width);
488
+ const items = [...shiftItems(baseBox.items, (w - baseBox.width) / 2, 0)];
489
+ const gap = .08 * size;
490
+ let ascent = baseBox.ascent;
491
+ let descent = baseBox.descent;
492
+ if (node.pos === "low") {
493
+ const limY = -(baseBox.descent + gap + limBox.ascent);
494
+ for (const it of shiftItems(limBox.items, (w - limBox.width) / 2, limY)) items.push(it);
495
+ descent = -(limY - limBox.descent);
496
+ } else {
497
+ const limY = baseBox.ascent + gap + limBox.descent;
498
+ for (const it of shiftItems(limBox.items, (w - limBox.width) / 2, limY)) items.push(it);
499
+ ascent = limY + limBox.ascent;
500
+ }
501
+ return {
502
+ width: w,
503
+ ascent,
504
+ descent,
505
+ items
506
+ };
507
+ }
508
+ function bracketGlyph(chr, asc, desc, size) {
509
+ if (chr === "") return {
510
+ width: 0,
511
+ items: []
512
+ };
513
+ const margin = .1 * size;
514
+ const top = asc + margin;
515
+ const bot = -desc - margin;
516
+ const mid = (top + bot) / 2;
517
+ const stroke = Math.max(.06 * size, .8);
518
+ const isOpen = "([{⟨〈⌊⌈".includes(chr);
519
+ const path = (segments, width) => ({
520
+ width,
521
+ items: [{
522
+ kind: "path",
523
+ segments,
524
+ strokeWidthPt: stroke
525
+ }]
526
+ });
527
+ if (chr === "(" || chr === ")") {
528
+ const w = .32 * size;
529
+ const bulge = w * .85;
530
+ const x0 = isOpen ? w : 0;
531
+ const dir = isOpen ? -1 : 1;
532
+ return path([{
533
+ op: "move",
534
+ x: x0,
535
+ y: top
536
+ }, {
537
+ op: "cubic",
538
+ x1: x0 + dir * bulge,
539
+ y1: mid + .45 * (top - mid),
540
+ x2: x0 + dir * bulge,
541
+ y2: mid - .45 * (top - mid),
542
+ x: x0,
543
+ y: bot
544
+ }], w);
545
+ }
546
+ if (chr === "[" || chr === "]") {
547
+ const w = .26 * size;
548
+ const xV = isOpen ? 0 : w;
549
+ const xA = isOpen ? w : 0;
550
+ return path([
551
+ {
552
+ op: "move",
553
+ x: xA,
554
+ y: top
555
+ },
556
+ {
557
+ op: "line",
558
+ x: xV,
559
+ y: top
560
+ },
561
+ {
562
+ op: "line",
563
+ x: xV,
564
+ y: bot
565
+ },
566
+ {
567
+ op: "line",
568
+ x: xA,
569
+ y: bot
570
+ }
571
+ ], w);
572
+ }
573
+ if (chr === "{" || chr === "}") {
574
+ const w = .4 * size;
575
+ const dir = isOpen ? 1 : -1;
576
+ const xb = isOpen ? w : 0;
577
+ const tip = xb - dir * w;
578
+ return path([
579
+ {
580
+ op: "move",
581
+ x: xb,
582
+ y: top
583
+ },
584
+ {
585
+ op: "cubic",
586
+ x1: xb - dir * w * .5,
587
+ y1: top,
588
+ x2: xb - dir * w * .5,
589
+ y2: mid + .25 * (top - mid),
590
+ x: tip,
591
+ y: mid
592
+ },
593
+ {
594
+ op: "cubic",
595
+ x1: xb - dir * w * .5,
596
+ y1: mid - .25 * (top - mid),
597
+ x2: xb - dir * w * .5,
598
+ y2: bot,
599
+ x: xb,
600
+ y: bot
601
+ }
602
+ ], w);
603
+ }
604
+ if (chr === "⟨" || chr === "⟩" || chr === "〈" || chr === "〉") {
605
+ const w = .3 * size;
606
+ const xPoint = isOpen ? 0 : w;
607
+ const xOpen = isOpen ? w : 0;
608
+ return path([
609
+ {
610
+ op: "move",
611
+ x: xOpen,
612
+ y: top
613
+ },
614
+ {
615
+ op: "line",
616
+ x: xPoint,
617
+ y: mid
618
+ },
619
+ {
620
+ op: "line",
621
+ x: xOpen,
622
+ y: bot
623
+ }
624
+ ], w);
625
+ }
626
+ if (chr === "‖") {
627
+ const w = .3 * size;
628
+ return path([
629
+ {
630
+ op: "move",
631
+ x: w * .3,
632
+ y: top
633
+ },
634
+ {
635
+ op: "line",
636
+ x: w * .3,
637
+ y: bot
638
+ },
639
+ {
640
+ op: "move",
641
+ x: w * .7,
642
+ y: top
643
+ },
644
+ {
645
+ op: "line",
646
+ x: w * .7,
647
+ y: bot
648
+ }
649
+ ], w);
650
+ }
651
+ const w = .18 * size;
652
+ return path([{
653
+ op: "move",
654
+ x: w / 2,
655
+ y: top
656
+ }, {
657
+ op: "line",
658
+ x: w / 2,
659
+ y: bot
660
+ }], w);
661
+ }
662
+ function layoutDelimiter(node, ctx, measure) {
663
+ const size = ctx.sizePt;
664
+ const inner = [];
665
+ let innerW = 0;
666
+ let innerAsc = 0;
667
+ let innerDesc = 0;
668
+ node.children.forEach((child, i) => {
669
+ if (i > 0 && node.sepChr) {
670
+ const sepBox = layoutMath({
671
+ type: "run",
672
+ text: node.sepChr,
673
+ nor: true
674
+ }, ctx, measure);
675
+ for (const it of shiftItems(sepBox.items, innerW, 0)) inner.push(it);
676
+ innerW += sepBox.width;
677
+ innerAsc = Math.max(innerAsc, sepBox.ascent);
678
+ innerDesc = Math.max(innerDesc, sepBox.descent);
679
+ }
680
+ const box = layoutMath(child, ctx, measure);
681
+ for (const it of shiftItems(box.items, innerW, 0)) inner.push(it);
682
+ innerW += box.width;
683
+ innerAsc = Math.max(innerAsc, box.ascent);
684
+ innerDesc = Math.max(innerDesc, box.descent);
685
+ });
686
+ innerAsc = Math.max(innerAsc, size * .6);
687
+ innerDesc = Math.max(innerDesc, size * .2);
688
+ const open = bracketGlyph(node.begChr, innerAsc, innerDesc, size);
689
+ const close = bracketGlyph(node.endChr, innerAsc, innerDesc, size);
690
+ const items = [...open.items];
691
+ for (const it of shiftItems(inner, open.width, 0)) items.push(it);
692
+ for (const it of shiftItems(close.items, open.width + innerW, 0)) items.push(it);
693
+ const margin = .1 * size;
694
+ return {
695
+ width: open.width + innerW + close.width,
696
+ ascent: innerAsc + margin,
697
+ descent: innerDesc + margin,
698
+ items
699
+ };
700
+ }
701
+ function layoutMatrix(node, ctx, measure) {
702
+ const size = ctx.sizePt;
703
+ const cells = node.rows.map((row) => row.map((cell) => layoutMath(cell, ctx, measure)));
704
+ const nCols = Math.max(0, ...cells.map((r) => r.length));
705
+ const colW = new Array(nCols).fill(0);
706
+ const rowAsc = [];
707
+ const rowDesc = [];
708
+ cells.forEach((row, ri) => {
709
+ let a = 0;
710
+ let d = 0;
711
+ row.forEach((cb, ci) => {
712
+ colW[ci] = Math.max(colW[ci], cb.width);
713
+ a = Math.max(a, cb.ascent);
714
+ d = Math.max(d, cb.descent);
715
+ });
716
+ rowAsc[ri] = a;
717
+ rowDesc[ri] = d;
718
+ });
719
+ const colGap = .7 * size;
720
+ const rowGap = .35 * size;
721
+ const totalW = colW.reduce((s, w) => s + w, 0) + colGap * Math.max(0, nCols - 1);
722
+ const rowH = rowAsc.map((a, i) => a + rowDesc[i]);
723
+ const totalH = rowH.reduce((s, h) => s + h, 0) + rowGap * Math.max(0, cells.length - 1);
724
+ const axis = AXIS * size;
725
+ const items = [];
726
+ let y = totalH / 2 + axis;
727
+ cells.forEach((row, ri) => {
728
+ const baseline = y - rowAsc[ri];
729
+ let x = 0;
730
+ row.forEach((cb, ci) => {
731
+ const cellX = x + (colW[ci] - cb.width) / 2;
732
+ for (const it of shiftItems(cb.items, cellX, baseline)) items.push(it);
733
+ x += colW[ci] + colGap;
734
+ });
735
+ y -= rowH[ri] + rowGap;
736
+ });
737
+ return {
738
+ width: totalW,
739
+ ascent: totalH / 2 + axis,
740
+ descent: totalH / 2 - axis,
741
+ items
742
+ };
743
+ }
744
+ function layoutEqArray(node, ctx, measure) {
745
+ const size = ctx.sizePt;
746
+ const boxes = node.rows.map((r) => layoutMath(r, ctx, measure));
747
+ const width = Math.max(0, ...boxes.map((b) => b.width));
748
+ const rowGap = .5 * size;
749
+ const rowH = boxes.map((b) => b.ascent + b.descent);
750
+ const totalH = rowH.reduce((s, h) => s + h, 0) + rowGap * Math.max(0, boxes.length - 1);
751
+ const axis = AXIS * size;
752
+ const items = [];
753
+ let y = totalH / 2 + axis;
754
+ boxes.forEach((b, i) => {
755
+ const baseline = y - b.ascent;
756
+ for (const it of shiftItems(b.items, 0, baseline)) items.push(it);
757
+ y -= rowH[i] + rowGap;
758
+ });
759
+ return {
760
+ width,
761
+ ascent: totalH / 2 + axis,
762
+ descent: totalH / 2 - axis,
763
+ items
764
+ };
765
+ }
766
+ function layoutAccent(node, ctx, measure) {
767
+ const baseBox = layoutMath(node.base, ctx, measure);
768
+ const size = ctx.sizePt;
769
+ const y = baseBox.ascent + .04 * size;
770
+ const cx = baseBox.width / 2;
771
+ const items = [...baseBox.items];
772
+ const accH = drawAccent(node.char, cx, y, baseBox.width, size, items);
773
+ return {
774
+ width: baseBox.width,
775
+ ascent: y + accH,
776
+ descent: baseBox.descent,
777
+ items
778
+ };
779
+ }
780
+ function drawAccent(char, cx, y, baseW, size, items) {
781
+ const aw = Math.min(baseW * .85, .7 * size);
782
+ const stroke = Math.max(.05 * size, .7);
783
+ const cp = char.codePointAt(0) ?? 0;
784
+ if (char === "^" || char === "ˆ" || cp === 770) {
785
+ const h = .18 * size;
786
+ items.push({
787
+ kind: "path",
788
+ segments: [
789
+ {
790
+ op: "move",
791
+ x: cx - aw / 2,
792
+ y
793
+ },
794
+ {
795
+ op: "line",
796
+ x: cx,
797
+ y: y + h
798
+ },
799
+ {
800
+ op: "line",
801
+ x: cx + aw / 2,
802
+ y
803
+ }
804
+ ],
805
+ strokeWidthPt: stroke
806
+ });
807
+ return h;
808
+ }
809
+ if (char === "~" || char === "˜" || cp === 771) {
810
+ const h = .12 * size;
811
+ items.push({
812
+ kind: "path",
813
+ segments: [
814
+ {
815
+ op: "move",
816
+ x: cx - aw / 2,
817
+ y
818
+ },
819
+ {
820
+ op: "cubic",
821
+ x1: cx - aw * .25,
822
+ y1: y + h,
823
+ x2: cx - aw * .1,
824
+ y2: y - h * .4,
825
+ x: cx,
826
+ y: y + h * .3
827
+ },
828
+ {
829
+ op: "cubic",
830
+ x1: cx + aw * .1,
831
+ y1: y + h,
832
+ x2: cx + aw * .25,
833
+ y2: y - h * .4,
834
+ x: cx + aw / 2,
835
+ y
836
+ }
837
+ ],
838
+ strokeWidthPt: stroke
839
+ });
840
+ return h;
841
+ }
842
+ if (char === "→" || cp === 8407) {
843
+ const sh = y + .06 * size;
844
+ const head = .06 * size;
845
+ items.push({
846
+ kind: "path",
847
+ segments: [
848
+ {
849
+ op: "move",
850
+ x: cx - aw / 2,
851
+ y: sh
852
+ },
853
+ {
854
+ op: "line",
855
+ x: cx + aw / 2,
856
+ y: sh
857
+ },
858
+ {
859
+ op: "move",
860
+ x: cx + aw / 2 - head,
861
+ y: sh + head
862
+ },
863
+ {
864
+ op: "line",
865
+ x: cx + aw / 2,
866
+ y: sh
867
+ },
868
+ {
869
+ op: "line",
870
+ x: cx + aw / 2 - head,
871
+ y: sh - head
872
+ }
873
+ ],
874
+ strokeWidthPt: stroke
875
+ });
876
+ return .14 * size;
877
+ }
878
+ if (char === "." || cp === 775) {
879
+ const d = Math.max(.07 * size, 1);
880
+ items.push({
881
+ kind: "rule",
882
+ x: cx - d / 2,
883
+ y,
884
+ w: d,
885
+ h: d
886
+ });
887
+ return .1 * size + d;
888
+ }
889
+ if (cp === 776) {
890
+ const d = Math.max(.07 * size, 1);
891
+ const off = .12 * size;
892
+ items.push({
893
+ kind: "rule",
894
+ x: cx - off - d / 2,
895
+ y,
896
+ w: d,
897
+ h: d
898
+ });
899
+ items.push({
900
+ kind: "rule",
901
+ x: cx + off - d / 2,
902
+ y,
903
+ w: d,
904
+ h: d
905
+ });
906
+ return .1 * size + d;
907
+ }
908
+ items.push({
909
+ kind: "rule",
910
+ x: cx - aw / 2,
911
+ y,
912
+ w: aw,
913
+ h: stroke
914
+ });
915
+ return .08 * size;
916
+ }
917
+ function layoutBar(node, ctx, measure) {
918
+ const baseBox = layoutMath(node.base, ctx, measure);
919
+ const size = ctx.sizePt;
920
+ const rule = Math.max(.05 * size, .6);
921
+ const gap = .08 * size;
922
+ const items = [...baseBox.items];
923
+ if (node.pos === "top") {
924
+ const y = baseBox.ascent + gap;
925
+ items.push({
926
+ kind: "rule",
927
+ x: 0,
928
+ y,
929
+ w: baseBox.width,
930
+ h: rule
931
+ });
932
+ return {
933
+ width: baseBox.width,
934
+ ascent: y + rule,
935
+ descent: baseBox.descent,
936
+ items
937
+ };
938
+ }
939
+ const y = -baseBox.descent - gap - rule;
940
+ items.push({
941
+ kind: "rule",
942
+ x: 0,
943
+ y,
944
+ w: baseBox.width,
945
+ h: rule
946
+ });
947
+ return {
948
+ width: baseBox.width,
949
+ ascent: baseBox.ascent,
950
+ descent: -y,
951
+ items
952
+ };
953
+ }
954
+ function layoutGroupChr(node, ctx, measure) {
955
+ const baseBox = layoutMath(node.base, ctx, measure);
956
+ const size = ctx.sizePt;
957
+ const gap = .06 * size;
958
+ const braceH = .18 * size;
959
+ const stroke = Math.max(.05 * size, .7);
960
+ const w = baseBox.width;
961
+ const items = [...baseBox.items];
962
+ const hbrace = (yBase, dir) => [
963
+ {
964
+ op: "move",
965
+ x: 0,
966
+ y: yBase
967
+ },
968
+ {
969
+ op: "cubic",
970
+ x1: w * .1,
971
+ y1: yBase,
972
+ x2: w * .4,
973
+ y2: yBase,
974
+ x: w / 2 - .02 * size,
975
+ y: yBase + dir * braceH
976
+ },
977
+ {
978
+ op: "move",
979
+ x: w,
980
+ y: yBase
981
+ },
982
+ {
983
+ op: "cubic",
984
+ x1: w * .9,
985
+ y1: yBase,
986
+ x2: w * .6,
987
+ y2: yBase,
988
+ x: w / 2 + .02 * size,
989
+ y: yBase + dir * braceH
990
+ }
991
+ ];
992
+ if (node.pos === "top") {
993
+ const yBase = baseBox.ascent + gap + braceH;
994
+ items.push({
995
+ kind: "path",
996
+ segments: hbrace(yBase, -1),
997
+ strokeWidthPt: stroke
998
+ });
999
+ return {
1000
+ width: w,
1001
+ ascent: yBase,
1002
+ descent: baseBox.descent,
1003
+ items
1004
+ };
1005
+ }
1006
+ const yBase = -baseBox.descent - gap - braceH;
1007
+ items.push({
1008
+ kind: "path",
1009
+ segments: hbrace(yBase, 1),
1010
+ strokeWidthPt: stroke
1011
+ });
1012
+ return {
1013
+ width: w,
1014
+ ascent: baseBox.ascent,
1015
+ descent: -yBase,
1016
+ items
1017
+ };
1018
+ }
1019
+ function shiftItems(items, dx, dy) {
1020
+ return items.map((it) => {
1021
+ if (it.kind === "glyph") return {
1022
+ ...it,
1023
+ x: it.x + dx,
1024
+ y: it.y + dy
1025
+ };
1026
+ if (it.kind === "rule") return {
1027
+ ...it,
1028
+ x: it.x + dx,
1029
+ y: it.y + dy
1030
+ };
1031
+ return {
1032
+ ...it,
1033
+ segments: it.segments.map((s) => shiftSegment(s, dx, dy))
1034
+ };
1035
+ });
1036
+ }
1037
+ function shiftSegment(s, dx, dy) {
1038
+ switch (s.op) {
1039
+ case "move":
1040
+ case "line": return {
1041
+ ...s,
1042
+ x: s.x + dx,
1043
+ y: s.y + dy
1044
+ };
1045
+ case "cubic": return {
1046
+ ...s,
1047
+ x1: s.x1 + dx,
1048
+ y1: s.y1 + dy,
1049
+ x2: s.x2 + dx,
1050
+ y2: s.y2 + dy,
1051
+ x: s.x + dx,
1052
+ y: s.y + dy
1053
+ };
1054
+ case "close": return s;
1055
+ }
1056
+ }
1057
+ function mathGlyphSegments(node) {
1058
+ const out = [];
1059
+ const visit = (n) => {
1060
+ switch (n.type) {
1061
+ case "run": {
1062
+ const chars = [...n.text];
1063
+ let i = 0;
1064
+ while (i < chars.length) {
1065
+ const v = runCharVariant(chars[i], n);
1066
+ let seg = "";
1067
+ let j = i;
1068
+ while (j < chars.length && runCharVariant(chars[j], n) === v) {
1069
+ seg += chars[j];
1070
+ j++;
1071
+ }
1072
+ out.push({
1073
+ variant: v,
1074
+ text: seg
1075
+ });
1076
+ i = j;
1077
+ }
1078
+ break;
1079
+ }
1080
+ case "row":
1081
+ n.children.forEach(visit);
1082
+ break;
1083
+ case "fraction":
1084
+ visit(n.num);
1085
+ visit(n.den);
1086
+ break;
1087
+ case "script":
1088
+ visit(n.base);
1089
+ if (n.sub) visit(n.sub);
1090
+ if (n.sup) visit(n.sup);
1091
+ break;
1092
+ case "radical":
1093
+ visit(n.radicand);
1094
+ if (n.degree) visit(n.degree);
1095
+ break;
1096
+ case "nary":
1097
+ out.push({
1098
+ variant: "regular",
1099
+ text: n.op
1100
+ });
1101
+ visit(n.body);
1102
+ if (n.sub) visit(n.sub);
1103
+ if (n.sup) visit(n.sup);
1104
+ break;
1105
+ case "func":
1106
+ visit(n.name);
1107
+ visit(n.body);
1108
+ break;
1109
+ case "limit":
1110
+ visit(n.base);
1111
+ visit(n.lim);
1112
+ break;
1113
+ case "delimiter":
1114
+ if (n.sepChr) out.push({
1115
+ variant: "regular",
1116
+ text: n.sepChr
1117
+ });
1118
+ n.children.forEach(visit);
1119
+ break;
1120
+ case "matrix":
1121
+ n.rows.forEach((row) => row.forEach(visit));
1122
+ break;
1123
+ case "eqArr":
1124
+ n.rows.forEach(visit);
1125
+ break;
1126
+ case "accent":
1127
+ case "bar":
1128
+ case "groupChr":
1129
+ visit(n.base);
1130
+ break;
1131
+ default: break;
1132
+ }
1133
+ };
1134
+ visit(node);
1135
+ return out;
1136
+ }
1137
+ //#endregion
1138
+ export { layoutMath, mathGlyphSegments, variantStyle };