ooxml-core 0.7.0 → 0.9.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 (48) hide show
  1. package/README.md +7 -0
  2. package/dist/chart/blank-display.d.ts +37 -0
  3. package/dist/chart/blank-display.d.ts.map +1 -0
  4. package/dist/chart/box-stats.d.ts +28 -0
  5. package/dist/chart/box-stats.d.ts.map +1 -0
  6. package/dist/chart/index.cjs +229 -0
  7. package/dist/chart/index.d.ts +6 -0
  8. package/dist/chart/index.d.ts.map +1 -0
  9. package/dist/chart/index.mjs +220 -0
  10. package/dist/chart/regression.d.ts +40 -0
  11. package/dist/chart/regression.d.ts.map +1 -0
  12. package/dist/chart/stacked-series.d.ts +39 -0
  13. package/dist/chart/stacked-series.d.ts.map +1 -0
  14. package/dist/docx/embedded.cjs +23 -2
  15. package/dist/docx/embedded.mjs +23 -2
  16. package/dist/docx/index.cjs +23 -2
  17. package/dist/docx/index.mjs +23 -2
  18. package/dist/docx/layout/index.cjs +2 -0
  19. package/dist/docx/layout/index.mjs +2 -0
  20. package/dist/docx/layout/paragraph-layout.d.ts.map +1 -1
  21. package/dist/docx/layout/result.d.ts +3 -0
  22. package/dist/docx/layout/result.d.ts.map +1 -1
  23. package/dist/docx/load/index.cjs +23 -2
  24. package/dist/docx/load/index.mjs +23 -2
  25. package/dist/docx/write-table-properties.d.ts +2 -0
  26. package/dist/docx/write-table-properties.d.ts.map +1 -1
  27. package/dist/docx/write-table.d.ts.map +1 -1
  28. package/dist/geometry/index.cjs +192 -0
  29. package/dist/geometry/index.d.ts +1 -0
  30. package/dist/geometry/index.d.ts.map +1 -1
  31. package/dist/geometry/index.mjs +192 -1
  32. package/dist/geometry/svg-path-curves.d.ts +11 -0
  33. package/dist/geometry/svg-path-curves.d.ts.map +1 -0
  34. package/dist/geometry/svg-path-flatten.d.ts +26 -0
  35. package/dist/geometry/svg-path-flatten.d.ts.map +1 -0
  36. package/dist/geometry/svg-path-types.d.ts +6 -0
  37. package/dist/geometry/svg-path-types.d.ts.map +1 -0
  38. package/dist/index.cjs +554 -3
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.mjs +553 -4
  42. package/dist/text/index.cjs +122 -0
  43. package/dist/text/index.d.ts +3 -0
  44. package/dist/text/index.d.ts.map +1 -0
  45. package/dist/text/index.mjs +117 -0
  46. package/dist/text/unicode-script-detection.d.ts +54 -0
  47. package/dist/text/unicode-script-detection.d.ts.map +1 -0
  48. package/package.json +11 -1
package/dist/index.mjs CHANGED
@@ -186,6 +186,363 @@ function linearToSrgb255(linear) {
186
186
  return 255 * (c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055);
187
187
  }
188
188
 
189
+ // src/chart/index.ts
190
+ var chart_exports = {};
191
+ __export(chart_exports, {
192
+ computeBoxStats: () => computeBoxStats,
193
+ computeLinearRegression: () => computeLinearRegression,
194
+ computeRSquared: () => computeRSquared,
195
+ computeStackedSeriesPlots: () => computeStackedSeriesPlots,
196
+ fitPolynomial: () => fitPolynomial,
197
+ groupRowsByCategory: () => groupRowsByCategory,
198
+ resolveBlankDisplay: () => resolveBlankDisplay,
199
+ visibleRuns: () => visibleRuns
200
+ });
201
+
202
+ // src/chart/regression.ts
203
+ function computeLinearRegression(xVals, yVals) {
204
+ const n = xVals.length;
205
+ if (n < 2) {
206
+ return { slope: 0, intercept: 0, rSquared: 0 };
207
+ }
208
+ let sumX = 0;
209
+ let sumY = 0;
210
+ let sumXY = 0;
211
+ let sumXX = 0;
212
+ for (let i = 0; i < n; i++) {
213
+ sumX += xVals[i];
214
+ sumY += yVals[i];
215
+ sumXY += xVals[i] * yVals[i];
216
+ sumXX += xVals[i] * xVals[i];
217
+ }
218
+ const denom = n * sumXX - sumX * sumX;
219
+ if (Math.abs(denom) < 1e-12) {
220
+ return { slope: 0, intercept: sumY / n, rSquared: 0 };
221
+ }
222
+ const slope = (n * sumXY - sumX * sumY) / denom;
223
+ const intercept = (sumY - slope * sumX) / n;
224
+ const ssRes = yVals.reduce((s, y, i) => s + (y - (slope * xVals[i] + intercept)) ** 2, 0);
225
+ const meanY = sumY / n;
226
+ const ssTot = yVals.reduce((s, y) => s + (y - meanY) ** 2, 0);
227
+ const rSquared = ssTot > 0 ? 1 - ssRes / ssTot : 0;
228
+ return { slope, intercept, rSquared };
229
+ }
230
+ function fitPolynomial(xVals, yVals, order) {
231
+ const n = xVals.length;
232
+ const m = order + 1;
233
+ const matrix = Array.from({ length: m }, () => Array(m + 1).fill(0));
234
+ for (let i = 0; i < m; i++) {
235
+ for (let j = 0; j < m; j++) {
236
+ let sum2 = 0;
237
+ for (let k = 0; k < n; k++) {
238
+ sum2 += xVals[k] ** (i + j);
239
+ }
240
+ matrix[i][j] = sum2;
241
+ }
242
+ let sum = 0;
243
+ for (let k = 0; k < n; k++) {
244
+ sum += yVals[k] * xVals[k] ** i;
245
+ }
246
+ matrix[i][m] = sum;
247
+ }
248
+ for (let i = 0; i < m; i++) {
249
+ let maxRow = i;
250
+ for (let k = i + 1; k < m; k++) {
251
+ if (Math.abs(matrix[k][i]) > Math.abs(matrix[maxRow][i])) {
252
+ maxRow = k;
253
+ }
254
+ }
255
+ [matrix[i], matrix[maxRow]] = [matrix[maxRow], matrix[i]];
256
+ const pivot = matrix[i][i];
257
+ if (Math.abs(pivot) < 1e-12) {
258
+ continue;
259
+ }
260
+ for (let j = i; j <= m; j++) {
261
+ matrix[i][j] = matrix[i][j] / pivot;
262
+ }
263
+ for (let k = 0; k < m; k++) {
264
+ if (k === i) {
265
+ continue;
266
+ }
267
+ const factor = matrix[k][i];
268
+ for (let j = i; j <= m; j++) {
269
+ matrix[k][j] = matrix[k][j] - factor * matrix[i][j];
270
+ }
271
+ }
272
+ }
273
+ return matrix.map((row) => row[m]);
274
+ }
275
+ function computeRSquared(xVals, yVals, evalFn) {
276
+ const n = xVals.length;
277
+ if (n === 0) {
278
+ return 0;
279
+ }
280
+ const meanY = yVals.reduce((s, y) => s + y, 0) / n;
281
+ let ssRes = 0;
282
+ let ssTot = 0;
283
+ for (let i = 0; i < n; i++) {
284
+ ssRes += (yVals[i] - evalFn(xVals[i])) ** 2;
285
+ ssTot += (yVals[i] - meanY) ** 2;
286
+ }
287
+ return ssTot > 0 ? 1 - ssRes / ssTot : 0;
288
+ }
289
+
290
+ // src/chart/box-stats.ts
291
+ function groupRowsByCategory(rawCategories) {
292
+ const uniqueCategories = [];
293
+ const rowIndexesByCategory = /* @__PURE__ */ new Map();
294
+ rawCategories.forEach((rawLabel, rowIndex) => {
295
+ const label = rawLabel ?? "";
296
+ let rows = rowIndexesByCategory.get(label);
297
+ if (!rows) {
298
+ rows = [];
299
+ rowIndexesByCategory.set(label, rows);
300
+ uniqueCategories.push(label);
301
+ }
302
+ rows.push(rowIndex);
303
+ });
304
+ return { uniqueCategories, rowIndexesByCategory };
305
+ }
306
+ function percentile(sorted, p, method) {
307
+ const rank = method === "inclusive" ? (sorted.length - 1) * p : (sorted.length + 1) * p - 1;
308
+ const clamped = Math.max(0, Math.min(rank, sorted.length - 1));
309
+ const lower = Math.floor(clamped);
310
+ const upper = Math.ceil(clamped);
311
+ const fraction = clamped - lower;
312
+ return sorted[lower] + (sorted[upper] - sorted[lower]) * fraction;
313
+ }
314
+ function computeBoxStats(values, method) {
315
+ if (values.length < 2) {
316
+ return void 0;
317
+ }
318
+ const sorted = [...values].sort((a, b) => a - b);
319
+ if (!method) {
320
+ return {
321
+ min: sorted[0],
322
+ q1: sorted[Math.floor(sorted.length * 0.25)],
323
+ median: sorted[Math.floor(sorted.length * 0.5)],
324
+ q3: sorted[Math.floor(sorted.length * 0.75)],
325
+ max: sorted[sorted.length - 1]
326
+ };
327
+ }
328
+ return {
329
+ min: sorted[0],
330
+ q1: percentile(sorted, 0.25, method),
331
+ median: percentile(sorted, 0.5, method),
332
+ q3: percentile(sorted, 0.75, method),
333
+ max: sorted[sorted.length - 1]
334
+ };
335
+ }
336
+
337
+ // src/chart/blank-display.ts
338
+ function interpolate(values, blank) {
339
+ const out = [...values];
340
+ for (let i = 0; i < out.length; i++) {
341
+ if (!blank[i]) {
342
+ continue;
343
+ }
344
+ let prev = i - 1;
345
+ while (prev >= 0 && blank[prev]) {
346
+ prev--;
347
+ }
348
+ let next = i + 1;
349
+ while (next < out.length && blank[next]) {
350
+ next++;
351
+ }
352
+ const hasPrev = prev >= 0;
353
+ const hasNext = next < out.length;
354
+ if (hasPrev && hasNext) {
355
+ const t = (i - prev) / (next - prev);
356
+ out[i] = values[prev] + (values[next] - values[prev]) * t;
357
+ } else if (hasPrev) {
358
+ out[i] = values[prev];
359
+ } else if (hasNext) {
360
+ out[i] = values[next];
361
+ }
362
+ }
363
+ return out;
364
+ }
365
+ function resolveBlankDisplay(values, blanks, mode) {
366
+ const visible = values.map(() => true);
367
+ if (!blanks || !blanks.some(Boolean) || mode === void 0 || mode === "zero") {
368
+ return { values: [...values], visible };
369
+ }
370
+ if (mode === "span") {
371
+ return { values: interpolate(values, blanks), visible };
372
+ }
373
+ return {
374
+ values: [...values],
375
+ visible: values.map((_v, i) => !blanks[i])
376
+ };
377
+ }
378
+ function visibleRuns(visible) {
379
+ const runs = [];
380
+ let current = [];
381
+ for (let i = 0; i < visible.length; i++) {
382
+ if (visible[i]) {
383
+ current.push(i);
384
+ } else if (current.length > 0) {
385
+ runs.push(current);
386
+ current = [];
387
+ }
388
+ }
389
+ if (current.length > 0) {
390
+ runs.push(current);
391
+ }
392
+ return runs;
393
+ }
394
+
395
+ // src/chart/stacked-series.ts
396
+ function categoryAbsTotals(seriesValues, catCount) {
397
+ return Array.from(
398
+ { length: catCount },
399
+ (_, ci) => seriesValues.reduce((sum, values) => sum + Math.abs(values[ci] ?? 0), 0)
400
+ );
401
+ }
402
+ function computeStackedSeriesPlots(seriesValues, catCount, percent) {
403
+ const totals = percent ? categoryAbsTotals(seriesValues, catCount) : void 0, posRunning = new Array(catCount).fill(0), negRunning = new Array(catCount).fill(0);
404
+ return seriesValues.map((values) => {
405
+ const cumulative = [], base = [], own = [];
406
+ for (let ci = 0; ci < catCount; ci++) {
407
+ const raw = values[ci] ?? 0, total = totals?.[ci] ?? 0, val2 = percent ? total > 0 ? raw / total * 100 : 0 : raw, isNeg = val2 < 0, from = isNeg ? negRunning[ci] : posRunning[ci], to = from + val2;
408
+ base.push(from);
409
+ cumulative.push(to);
410
+ own.push(val2);
411
+ if (isNeg) {
412
+ negRunning[ci] = to;
413
+ } else {
414
+ posRunning[ci] = to;
415
+ }
416
+ }
417
+ return { cumulative, base, own };
418
+ });
419
+ }
420
+
421
+ // src/text/index.ts
422
+ var text_exports = {};
423
+ __export(text_exports, {
424
+ detectFontScript: () => detectFontScript,
425
+ hasDistinctScriptFonts: () => hasDistinctScriptFonts,
426
+ resolveFontForScript: () => resolveFontForScript,
427
+ segmentByScript: () => segmentByScript
428
+ });
429
+
430
+ // src/text/unicode-script-detection.ts
431
+ function detectFontScript(codePoint) {
432
+ if (codePoint >= 11904 && codePoint <= 40959 || // CJK radicals, unified ideographs
433
+ codePoint >= 44032 && codePoint <= 55215 || // Hangul syllables
434
+ codePoint >= 63744 && codePoint <= 64255 || // CJK compatibility ideographs
435
+ codePoint >= 65072 && codePoint <= 65103 || // CJK compatibility forms
436
+ codePoint >= 131072 && codePoint <= 195103 || // CJK extension B-F
437
+ codePoint >= 12288 && codePoint <= 12351 || // CJK symbols & punctuation
438
+ codePoint >= 12352 && codePoint <= 12447 || // Hiragana
439
+ codePoint >= 12448 && codePoint <= 12543 || // Katakana
440
+ codePoint >= 12784 && codePoint <= 12799 || // Katakana extensions
441
+ codePoint >= 65280 && codePoint <= 65519) {
442
+ return "eastAsia";
443
+ }
444
+ if (codePoint >= 1424 && codePoint <= 1535 || // Hebrew
445
+ codePoint >= 1536 && codePoint <= 1791 || // Arabic
446
+ codePoint >= 1792 && codePoint <= 1871 || // Syriac
447
+ codePoint >= 1872 && codePoint <= 1919 || // Arabic Supplement
448
+ codePoint >= 1920 && codePoint <= 1983 || // Thaana
449
+ codePoint >= 1984 && codePoint <= 2047 || // NKo
450
+ codePoint >= 2048 && codePoint <= 2111 || // Samaritan
451
+ codePoint >= 2304 && codePoint <= 2431 || // Devanagari
452
+ codePoint >= 2432 && codePoint <= 2559 || // Bengali
453
+ codePoint >= 2560 && codePoint <= 2687 || // Gurmukhi
454
+ codePoint >= 2688 && codePoint <= 2815 || // Gujarati
455
+ codePoint >= 2816 && codePoint <= 2943 || // Oriya
456
+ codePoint >= 2944 && codePoint <= 3071 || // Tamil
457
+ codePoint >= 3072 && codePoint <= 3199 || // Telugu
458
+ codePoint >= 3200 && codePoint <= 3327 || // Kannada
459
+ codePoint >= 3328 && codePoint <= 3455 || // Malayalam
460
+ codePoint >= 3456 && codePoint <= 3583 || // Sinhala
461
+ codePoint >= 3584 && codePoint <= 3711 || // Thai
462
+ codePoint >= 3712 && codePoint <= 3839 || // Lao
463
+ codePoint >= 3840 && codePoint <= 4095 || // Tibetan
464
+ codePoint >= 4096 && codePoint <= 4255 || // Myanmar
465
+ codePoint >= 4256 && codePoint <= 4351 || // Georgian
466
+ codePoint >= 6016 && codePoint <= 6143 || // Khmer
467
+ codePoint >= 64336 && codePoint <= 65023 || // Arabic Presentation Forms-A
468
+ codePoint >= 65136 && codePoint <= 65279) {
469
+ return "complexScript";
470
+ }
471
+ if (codePoint >= 8592 && codePoint <= 8703 || // Arrows
472
+ codePoint >= 8704 && codePoint <= 8959 || // Mathematical operators
473
+ codePoint >= 8960 && codePoint <= 9215 || // Misc technical
474
+ codePoint >= 9472 && codePoint <= 9599 || // Box drawing
475
+ codePoint >= 9600 && codePoint <= 9631 || // Block elements
476
+ codePoint >= 9632 && codePoint <= 9727 || // Geometric shapes
477
+ codePoint >= 9728 && codePoint <= 9983 || // Misc symbols
478
+ codePoint >= 9984 && codePoint <= 10175 || // Dingbats
479
+ codePoint >= 57344 && codePoint <= 63743 || // Private Use Area
480
+ codePoint >= 126976 && codePoint <= 129535) {
481
+ return "symbol";
482
+ }
483
+ return "latin";
484
+ }
485
+ function segmentByScript(text) {
486
+ if (!text) {
487
+ return [];
488
+ }
489
+ const runs = [];
490
+ let currentScript = null;
491
+ let currentStart = 0;
492
+ let currentText = "";
493
+ for (let i = 0; i < text.length; i++) {
494
+ const codePoint = text.codePointAt(i);
495
+ if (codePoint === void 0) {
496
+ continue;
497
+ }
498
+ const charLength = codePoint > 65535 ? 2 : 1;
499
+ const char = text.substring(i, i + charLength);
500
+ const isNeutral = codePoint <= 127 && !/[a-zA-Z0-9]/u.test(char);
501
+ const script = isNeutral ? currentScript ?? "latin" : detectFontScript(codePoint);
502
+ if (script !== currentScript && currentScript !== null) {
503
+ runs.push({
504
+ text: currentText,
505
+ script: currentScript,
506
+ startIndex: currentStart
507
+ });
508
+ currentStart = i;
509
+ currentText = "";
510
+ }
511
+ currentScript = script;
512
+ currentText += char;
513
+ if (charLength === 2) {
514
+ i++;
515
+ }
516
+ }
517
+ if (currentText && currentScript) {
518
+ runs.push({
519
+ text: currentText,
520
+ script: currentScript,
521
+ startIndex: currentStart
522
+ });
523
+ }
524
+ return runs;
525
+ }
526
+ function resolveFontForScript(script, fonts) {
527
+ switch (script) {
528
+ case "latin":
529
+ return fonts.latin;
530
+ case "eastAsia":
531
+ return fonts.eastAsia || fonts.latin;
532
+ case "complexScript":
533
+ return fonts.complexScript || fonts.latin;
534
+ case "symbol":
535
+ return fonts.symbol || fonts.latin;
536
+ }
537
+ }
538
+ function hasDistinctScriptFonts(fonts) {
539
+ const base = fonts.latin;
540
+ if (!base) {
541
+ return false;
542
+ }
543
+ return Boolean(fonts.eastAsia) && fonts.eastAsia !== base || Boolean(fonts.complexScript) && fonts.complexScript !== base || Boolean(fonts.symbol) && fonts.symbol !== base;
544
+ }
545
+
189
546
  // src/diagram/index.ts
190
547
  var diagram_exports = {};
191
548
  __export(diagram_exports, {
@@ -2212,6 +2569,7 @@ __export(geometry_exports, {
2212
2569
  evaluateFormula: () => evaluateFormula,
2213
2570
  evaluateGuides: () => evaluateGuides,
2214
2571
  findAllIntersections: () => findAllIntersections,
2572
+ flattenSvgPath: () => flattenSvgPath,
2215
2573
  fmtNum: () => fmtNum,
2216
2574
  fragmentShapes: () => fragmentShapes,
2217
2575
  gd: () => gd,
@@ -17159,6 +17517,197 @@ function subtractSvgPaths(path1, path2) {
17159
17517
  return subtractShapes(path1, path2);
17160
17518
  }
17161
17519
 
17520
+ // src/geometry/svg-path-curves.ts
17521
+ function sampleCubic(p0, p1, p2, p3, segments, out) {
17522
+ for (let i = 1; i <= segments; i++) {
17523
+ const t = i / segments;
17524
+ const mt = 1 - t;
17525
+ const x = mt * mt * mt * p0.x + 3 * mt * mt * t * p1.x + 3 * mt * t * t * p2.x + t * t * t * p3.x;
17526
+ const y = mt * mt * mt * p0.y + 3 * mt * mt * t * p1.y + 3 * mt * t * t * p2.y + t * t * t * p3.y;
17527
+ out.push({ x, y });
17528
+ }
17529
+ }
17530
+ function sampleQuadratic(p0, p1, p2, segments, out) {
17531
+ for (let i = 1; i <= segments; i++) {
17532
+ const t = i / segments;
17533
+ const mt = 1 - t;
17534
+ const x = mt * mt * p0.x + 2 * mt * t * p1.x + t * t * p2.x;
17535
+ const y = mt * mt * p0.y + 2 * mt * t * p1.y + t * t * p2.y;
17536
+ out.push({ x, y });
17537
+ }
17538
+ }
17539
+ function sampleArc(start, rxIn, ryIn, xAxisRotationDeg, largeArcFlag, sweepFlag, end, segments, out) {
17540
+ if (rxIn === 0 || ryIn === 0 || start.x === end.x && start.y === end.y) {
17541
+ out.push(end);
17542
+ return;
17543
+ }
17544
+ const phi = xAxisRotationDeg * Math.PI / 180;
17545
+ const cosPhi = Math.cos(phi);
17546
+ const sinPhi = Math.sin(phi);
17547
+ let rx = Math.abs(rxIn);
17548
+ let ry = Math.abs(ryIn);
17549
+ const dx2 = (start.x - end.x) / 2;
17550
+ const dy2 = (start.y - end.y) / 2;
17551
+ const x1p = cosPhi * dx2 + sinPhi * dy2;
17552
+ const y1p = -sinPhi * dx2 + cosPhi * dy2;
17553
+ const lambda = x1p * x1p / (rx * rx) + y1p * y1p / (ry * ry);
17554
+ if (lambda > 1) {
17555
+ const scale = Math.sqrt(lambda);
17556
+ rx *= scale;
17557
+ ry *= scale;
17558
+ }
17559
+ const sign = largeArcFlag !== sweepFlag ? 1 : -1;
17560
+ const num = rx * rx * ry * ry - rx * rx * y1p * y1p - ry * ry * x1p * x1p;
17561
+ const den = rx * rx * y1p * y1p + ry * ry * x1p * x1p;
17562
+ const coef = sign * Math.sqrt(Math.max(0, num / den));
17563
+ const cxp = coef * (rx * y1p) / ry;
17564
+ const cyp = coef * -(ry * x1p) / rx;
17565
+ const cx = cosPhi * cxp - sinPhi * cyp + (start.x + end.x) / 2;
17566
+ const cy = sinPhi * cxp + cosPhi * cyp + (start.y + end.y) / 2;
17567
+ const angle = (ux, uy, vx, vy) => {
17568
+ const sign2 = ux * vy - uy * vx < 0 ? -1 : 1;
17569
+ const dot = Math.max(
17570
+ -1,
17571
+ Math.min(1, (ux * vx + uy * vy) / (Math.hypot(ux, uy) * Math.hypot(vx, vy)))
17572
+ );
17573
+ return sign2 * Math.acos(dot);
17574
+ };
17575
+ const theta1 = angle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
17576
+ let deltaTheta = angle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry);
17577
+ if (!sweepFlag && deltaTheta > 0) {
17578
+ deltaTheta -= 2 * Math.PI;
17579
+ } else if (sweepFlag && deltaTheta < 0) {
17580
+ deltaTheta += 2 * Math.PI;
17581
+ }
17582
+ const steps = Math.max(2, Math.round(segments * (Math.abs(deltaTheta) / (Math.PI / 2))));
17583
+ for (let i = 1; i <= steps; i++) {
17584
+ const theta = theta1 + deltaTheta * i / steps;
17585
+ const x = cx + rx * Math.cos(theta) * cosPhi - ry * Math.sin(theta) * sinPhi;
17586
+ const y = cy + rx * Math.cos(theta) * sinPhi + ry * Math.sin(theta) * cosPhi;
17587
+ out.push({ x, y });
17588
+ }
17589
+ }
17590
+
17591
+ // src/geometry/svg-path-flatten.ts
17592
+ var COMMAND_RE = /[MLCQZAHVSmlcqzahvs][^MLCQZAHVSmlcqzahvs]*/gu;
17593
+ var NUMBER_RE = /-?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/gu;
17594
+ function tokenize(d) {
17595
+ const tokens = [];
17596
+ const matches = d.match(COMMAND_RE);
17597
+ if (!matches) {
17598
+ return tokens;
17599
+ }
17600
+ for (const raw of matches) {
17601
+ const type = raw.charAt(0);
17602
+ const nums = raw.slice(1).match(NUMBER_RE);
17603
+ tokens.push({ type, values: nums ? nums.map((n) => Number.parseFloat(n)) : [] });
17604
+ }
17605
+ return tokens;
17606
+ }
17607
+ function flattenSvgPath(d, curveSegments = 16) {
17608
+ if (!Number.isFinite(curveSegments) || curveSegments < 1) curveSegments = 16;
17609
+ curveSegments = Math.min(4096, Math.floor(curveSegments));
17610
+ const tokens = tokenize(d);
17611
+ const loops = [];
17612
+ let current = [];
17613
+ let cursor = { x: 0, y: 0 };
17614
+ let subpathStart = { x: 0, y: 0 };
17615
+ let lastControl;
17616
+ let lastCommand = "";
17617
+ const closeLoop = () => {
17618
+ if (current.length > 0) {
17619
+ loops.push(current);
17620
+ }
17621
+ current = [];
17622
+ };
17623
+ for (const token of tokens) {
17624
+ const type = token.type;
17625
+ const upper = type.toUpperCase();
17626
+ const relative = type !== upper;
17627
+ const v = token.values;
17628
+ if (v.some((value) => !Number.isFinite(value)) || upper === "M" && v.length < 2) continue;
17629
+ if (upper === "M") {
17630
+ closeLoop();
17631
+ const x = relative ? cursor.x + at(v, 0) : at(v, 0);
17632
+ const y = relative ? cursor.y + at(v, 1) : at(v, 1);
17633
+ cursor = { x, y };
17634
+ subpathStart = cursor;
17635
+ current.push(cursor);
17636
+ for (let i = 2; i + 1 < v.length; i += 2) {
17637
+ const lx = relative ? cursor.x + at(v, i) : at(v, i);
17638
+ const ly = relative ? cursor.y + at(v, i + 1) : at(v, i + 1);
17639
+ cursor = { x: lx, y: ly };
17640
+ current.push(cursor);
17641
+ }
17642
+ } else if (upper === "L") {
17643
+ for (let i = 0; i + 1 < v.length; i += 2) {
17644
+ const x = relative ? cursor.x + at(v, i) : at(v, i);
17645
+ const y = relative ? cursor.y + at(v, i + 1) : at(v, i + 1);
17646
+ cursor = { x, y };
17647
+ current.push(cursor);
17648
+ }
17649
+ } else if (upper === "H") {
17650
+ for (const value of v) {
17651
+ const x = relative ? cursor.x + value : value;
17652
+ cursor = { x, y: cursor.y };
17653
+ current.push(cursor);
17654
+ }
17655
+ } else if (upper === "V") {
17656
+ for (const value of v) {
17657
+ const y = relative ? cursor.y + value : value;
17658
+ cursor = { x: cursor.x, y };
17659
+ current.push(cursor);
17660
+ }
17661
+ } else if (upper === "C") {
17662
+ for (let i = 0; i + 5 < v.length; i += 6) {
17663
+ const p1 = relative ? { x: cursor.x + at(v, i), y: cursor.y + at(v, i + 1) } : { x: at(v, i), y: at(v, i + 1) };
17664
+ const p2 = relative ? { x: cursor.x + at(v, i + 2), y: cursor.y + at(v, i + 3) } : { x: at(v, i + 2), y: at(v, i + 3) };
17665
+ const p3 = relative ? { x: cursor.x + at(v, i + 4), y: cursor.y + at(v, i + 5) } : { x: at(v, i + 4), y: at(v, i + 5) };
17666
+ sampleCubic(cursor, p1, p2, p3, curveSegments, current);
17667
+ cursor = p3;
17668
+ lastControl = p2;
17669
+ }
17670
+ } else if (upper === "S") {
17671
+ for (let i = 0; i + 3 < v.length; i += 4) {
17672
+ const p1 = lastCommand === "C" || lastCommand === "S" ? {
17673
+ x: 2 * cursor.x - (lastControl?.x ?? cursor.x),
17674
+ y: 2 * cursor.y - (lastControl?.y ?? cursor.y)
17675
+ } : cursor;
17676
+ const p2 = relative ? { x: cursor.x + at(v, i), y: cursor.y + at(v, i + 1) } : { x: at(v, i), y: at(v, i + 1) };
17677
+ const p3 = relative ? { x: cursor.x + at(v, i + 2), y: cursor.y + at(v, i + 3) } : { x: at(v, i + 2), y: at(v, i + 3) };
17678
+ sampleCubic(cursor, p1, p2, p3, curveSegments, current);
17679
+ cursor = p3;
17680
+ lastControl = p2;
17681
+ }
17682
+ } else if (upper === "Q") {
17683
+ for (let i = 0; i + 3 < v.length; i += 4) {
17684
+ const p1 = relative ? { x: cursor.x + at(v, i), y: cursor.y + at(v, i + 1) } : { x: at(v, i), y: at(v, i + 1) };
17685
+ const p2 = relative ? { x: cursor.x + at(v, i + 2), y: cursor.y + at(v, i + 3) } : { x: at(v, i + 2), y: at(v, i + 3) };
17686
+ sampleQuadratic(cursor, p1, p2, curveSegments, current);
17687
+ cursor = p2;
17688
+ lastControl = p1;
17689
+ }
17690
+ } else if (upper === "A") {
17691
+ for (let i = 0; i + 6 < v.length; i += 7) {
17692
+ const rx = at(v, i);
17693
+ const ry = at(v, i + 1);
17694
+ const rot = at(v, i + 2);
17695
+ const largeArc = at(v, i + 3) !== 0;
17696
+ const sweep = at(v, i + 4) !== 0;
17697
+ const end = relative ? { x: cursor.x + at(v, i + 5), y: cursor.y + at(v, i + 6) } : { x: at(v, i + 5), y: at(v, i + 6) };
17698
+ sampleArc(cursor, rx, ry, rot, largeArc, sweep, end, curveSegments, current);
17699
+ cursor = end;
17700
+ }
17701
+ } else if (upper === "Z") {
17702
+ cursor = subpathStart;
17703
+ current.push(cursor);
17704
+ }
17705
+ lastCommand = upper;
17706
+ }
17707
+ closeLoop();
17708
+ return loops;
17709
+ }
17710
+
17162
17711
  // src/units/index.ts
17163
17712
  var units_exports = {};
17164
17713
  __export(units_exports, {
@@ -17302,7 +17851,7 @@ __export(math_exports, {
17302
17851
  readRunText: () => readRunText,
17303
17852
  rowsToLatex: () => rowsToLatex,
17304
17853
  soleChild: () => soleChild,
17305
- tokenize: () => tokenize,
17854
+ tokenize: () => tokenize2,
17306
17855
  tryParseScripts: () => tryParseScripts,
17307
17856
  wrapDelimited: () => wrapDelimited
17308
17857
  });
@@ -17318,7 +17867,7 @@ function stripXmlOrderSuffix(tagName) {
17318
17867
  // src/math/latex-omml-siblings.ts
17319
17868
  var LETTER_RE = /[a-zA-Z]/u;
17320
17869
  var WHITESPACE_RE = /\s/u;
17321
- function tokenize(latex) {
17870
+ function tokenize2(latex) {
17322
17871
  const tokens = [];
17323
17872
  let i = 0;
17324
17873
  while (i < latex.length) {
@@ -18673,7 +19222,7 @@ function convertLatexToOmml(latex) {
18673
19222
  if (trimmed.length === 0) {
18674
19223
  return {};
18675
19224
  }
18676
- const tokens = tokenize(trimmed);
19225
+ const tokens = tokenize2(trimmed);
18677
19226
  const parser = new LatexParser(tokens);
18678
19227
  const nodes = parser.parseAll();
18679
19228
  if (nodes.length === 0) {
@@ -19266,4 +19815,4 @@ function parseOmml(xml) {
19266
19815
  return ommlFromElement(parseXml(xml, { label: "OMML" }).documentElement);
19267
19816
  }
19268
19817
 
19269
- export { color_exports as color, diagram_exports as diagram, digest_exports as digest, geometry_exports as geometry, math_exports as math, opc_exports as opc, units_exports as units, xml_exports as xml };
19818
+ export { chart_exports as chart, color_exports as color, diagram_exports as diagram, digest_exports as digest, geometry_exports as geometry, math_exports as math, opc_exports as opc, text_exports as text, units_exports as units, xml_exports as xml };