ooxml-core 1.17.0 → 1.19.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 (137) hide show
  1. package/dist/{PptxHandler-K7GMS2ST.mjs → PptxHandler-5GBBVJCR.mjs} +2 -2
  2. package/dist/{PptxHandler-L3JPWOBN.mjs → PptxHandler-H43MAMTO.mjs} +1 -1
  3. package/dist/{PptxHandler-U6EFO73T.cjs → PptxHandler-ZHPGBSAF.cjs} +2 -2
  4. package/dist/{PresentationBuilder-XC3F3OPY.mjs → PresentationBuilder-7ZSUKCX5.mjs} +1 -1
  5. package/dist/{PresentationBuilder-OK526SZ4.mjs → PresentationBuilder-IJW42L3R.mjs} +2 -2
  6. package/dist/{PresentationBuilder-LUR6LGHU.cjs → PresentationBuilder-O4H4MMWB.cjs} +4 -4
  7. package/dist/automation/index.cjs +5198 -3235
  8. package/dist/automation/index.mjs +5198 -3235
  9. package/dist/chart/axis-range-auto.d.ts +10 -0
  10. package/dist/chart/axis-range-auto.d.ts.map +1 -0
  11. package/dist/chart/axis-range-types.d.ts +27 -0
  12. package/dist/chart/axis-range-types.d.ts.map +1 -0
  13. package/dist/chart/axis-range.d.ts +37 -0
  14. package/dist/chart/axis-range.d.ts.map +1 -0
  15. package/dist/chart/axis-ticks.d.ts +8 -0
  16. package/dist/chart/axis-ticks.d.ts.map +1 -0
  17. package/dist/chart/data-label-text.d.ts +70 -0
  18. package/dist/chart/data-label-text.d.ts.map +1 -0
  19. package/dist/chart/formatting-nodes.d.ts +6 -0
  20. package/dist/chart/formatting-nodes.d.ts.map +1 -1
  21. package/dist/chart/index.cjs +1536 -571
  22. package/dist/chart/index.d.ts +7 -0
  23. package/dist/chart/index.d.ts.map +1 -1
  24. package/dist/chart/index.mjs +1512 -572
  25. package/dist/chart/line-dash.d.ts +2 -0
  26. package/dist/chart/line-dash.d.ts.map +1 -0
  27. package/dist/chart/marker-shape.d.ts +70 -0
  28. package/dist/chart/marker-shape.d.ts.map +1 -0
  29. package/dist/chart/read-formatting.d.ts.map +1 -1
  30. package/dist/chart/render/chart-svg-axes.d.ts +9 -0
  31. package/dist/chart/render/chart-svg-axes.d.ts.map +1 -0
  32. package/dist/chart/render/chart-svg-bars.d.ts.map +1 -1
  33. package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
  34. package/dist/chart/render/chart-svg-labels.d.ts +42 -0
  35. package/dist/chart/render/chart-svg-labels.d.ts.map +1 -0
  36. package/dist/chart/render/chart-svg-markers.d.ts +6 -0
  37. package/dist/chart/render/chart-svg-markers.d.ts.map +1 -0
  38. package/dist/chart/render/chart-svg-radial.d.ts.map +1 -1
  39. package/dist/chart/render/chart-svg-xy.d.ts.map +1 -1
  40. package/dist/chart/render/chart-view-axes.d.ts +30 -0
  41. package/dist/chart/render/chart-view-axes.d.ts.map +1 -0
  42. package/dist/chart/render/chart-view-labels.d.ts +16 -0
  43. package/dist/chart/render/chart-view-labels.d.ts.map +1 -0
  44. package/dist/chart/render/chart-view-markers.d.ts +27 -0
  45. package/dist/chart/render/chart-view-markers.d.ts.map +1 -0
  46. package/dist/chart/render/chart-view-series.d.ts.map +1 -1
  47. package/dist/chart/render/chart-view.d.ts +7 -1
  48. package/dist/chart/render/chart-view.d.ts.map +1 -1
  49. package/dist/chart/render/index.d.ts +2 -0
  50. package/dist/chart/render/index.d.ts.map +1 -1
  51. package/dist/chart/render/summary-from-space.d.ts +2 -2
  52. package/dist/chart/render/summary-from-space.d.ts.map +1 -1
  53. package/dist/chart/render/summary-labels.d.ts +9 -0
  54. package/dist/chart/render/summary-labels.d.ts.map +1 -0
  55. package/dist/chart/render/summary.d.ts +29 -1
  56. package/dist/chart/render/summary.d.ts.map +1 -1
  57. package/dist/{chunk-IM5LFEA2.mjs → chunk-3XFPCZKB.mjs} +1 -1
  58. package/dist/{chunk-YS43OMM3.mjs → chunk-75GLSRZE.mjs} +4 -4
  59. package/dist/{chunk-A7S2NYAU.mjs → chunk-BIVNVDAH.mjs} +1 -1
  60. package/dist/{chunk-UFGJNXRG.mjs → chunk-QBJRB6WW.mjs} +1 -1
  61. package/dist/{chunk-HLZIALC5.mjs → chunk-RUZEMWDI.mjs} +1 -1
  62. package/dist/docx/embedded.cjs +15 -0
  63. package/dist/docx/embedded.mjs +15 -0
  64. package/dist/docx/index.cjs +1825 -693
  65. package/dist/docx/index.mjs +1825 -693
  66. package/dist/docx/layout/index.cjs +1684 -567
  67. package/dist/docx/layout/index.mjs +1684 -567
  68. package/dist/docx/load/index.cjs +15 -0
  69. package/dist/docx/load/index.mjs +15 -0
  70. package/dist/docx/ui/index.cjs +1696 -579
  71. package/dist/docx/ui/index.mjs +1696 -579
  72. package/dist/index.cjs +1623 -658
  73. package/dist/index.mjs +1623 -658
  74. package/dist/pptx/automation/index.cjs +61 -0
  75. package/dist/pptx/automation/index.mjs +5 -5
  76. package/dist/pptx/cli/index.cjs +61 -0
  77. package/dist/pptx/cli/index.mjs +4 -4
  78. package/dist/pptx/converter/index.mjs +2 -2
  79. package/dist/pptx/editor/render/slide-operations.cjs +1 -1
  80. package/dist/pptx/editor/render/slide-operations.mjs +1 -1
  81. package/dist/pptx/index.cjs +61 -0
  82. package/dist/pptx/index.mjs +5 -5
  83. package/dist/teams/index.cjs +212 -50
  84. package/dist/teams/index.mjs +212 -50
  85. package/dist/visio/edit-chart-object-commands.d.ts +36 -0
  86. package/dist/visio/edit-chart-object-commands.d.ts.map +1 -0
  87. package/dist/visio/edit-chart-object.d.ts +7 -0
  88. package/dist/visio/edit-chart-object.d.ts.map +1 -0
  89. package/dist/visio/edit-commands.d.ts +2 -1
  90. package/dist/visio/edit-commands.d.ts.map +1 -1
  91. package/dist/visio/edit-foreign-frame.d.ts +8 -0
  92. package/dist/visio/edit-foreign-frame.d.ts.map +1 -0
  93. package/dist/visio/edit-metadata-commands.d.ts +7 -0
  94. package/dist/visio/edit-metadata-commands.d.ts.map +1 -1
  95. package/dist/visio/edit-picture.d.ts +8 -0
  96. package/dist/visio/edit-picture.d.ts.map +1 -1
  97. package/dist/visio/edit.d.ts.map +1 -1
  98. package/dist/visio/emf-bitmap.d.ts +8 -0
  99. package/dist/visio/emf-bitmap.d.ts.map +1 -0
  100. package/dist/visio/index.cjs +17505 -6279
  101. package/dist/visio/index.d.ts +2 -0
  102. package/dist/visio/index.d.ts.map +1 -1
  103. package/dist/visio/index.mjs +17503 -6280
  104. package/dist/visio/model.d.ts +18 -0
  105. package/dist/visio/model.d.ts.map +1 -1
  106. package/dist/visio/prepare-embedded.d.ts +10 -0
  107. package/dist/visio/prepare-embedded.d.ts.map +1 -0
  108. package/dist/visio/prepare-images.d.ts.map +1 -1
  109. package/dist/visio/shapes.d.ts.map +1 -1
  110. package/dist/visio/sheet.d.ts +2 -1
  111. package/dist/visio/sheet.d.ts.map +1 -1
  112. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  113. package/dist/visio/ui/index.cjs +33580 -22875
  114. package/dist/visio/ui/index.mjs +33578 -22875
  115. package/dist/visio/ui/insert.d.ts +11 -0
  116. package/dist/visio/ui/insert.d.ts.map +1 -1
  117. package/dist/xlsx/edit/chart-colors.d.ts.map +1 -1
  118. package/dist/xlsx/index.cjs +1965 -817
  119. package/dist/xlsx/index.mjs +1965 -817
  120. package/dist/xlsx/load/index.cjs +190 -51
  121. package/dist/xlsx/load/index.mjs +190 -51
  122. package/dist/xlsx/model.d.ts +5 -0
  123. package/dist/xlsx/model.d.ts.map +1 -1
  124. package/dist/xlsx/read/chart.d.ts.map +1 -1
  125. package/dist/xlsx/read/load.d.ts.map +1 -1
  126. package/dist/xlsx/read/workbook-part.d.ts +2 -0
  127. package/dist/xlsx/read/workbook-part.d.ts.map +1 -1
  128. package/dist/xlsx/ui/dialogs/grid-chart.d.ts +22 -1
  129. package/dist/xlsx/ui/dialogs/grid-chart.d.ts.map +1 -1
  130. package/dist/xlsx/ui/index.cjs +17482 -4364
  131. package/dist/xlsx/ui/index.mjs +17472 -4362
  132. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  133. package/package.json +1 -1
  134. package/dist/visio/edit-foreign-bitmap.d.ts +0 -7
  135. package/dist/visio/edit-foreign-bitmap.d.ts.map +0 -1
  136. /package/dist/{chunk-KU3SMBFU.mjs → chunk-H6TNNXJK.mjs} +0 -0
  137. /package/dist/{chunk-UWWS6VVJ.cjs → chunk-MHMVD23Y.cjs} +0 -0
@@ -48,17 +48,17 @@ function checkXmlLimits(xml, label, limits = {}) {
48
48
  throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
49
49
  }
50
50
  }
51
- function parseXml(xml, options = {}) {
52
- const label = options.label ?? "OOXML";
51
+ function parseXml(xml, options2 = {}) {
52
+ const label = options2.label ?? "OOXML";
53
53
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
54
54
  throw new Error(`${label} XML with DTD or entity declarations is not supported`);
55
- checkXmlLimits(xml, label, options.limits);
55
+ checkXmlLimits(xml, label, options2.limits);
56
56
  let parseError = "";
57
57
  let parsed;
58
58
  try {
59
59
  parsed = new DOMParser({
60
- onError: (level, message) => {
61
- if (level !== "warning") parseError = message;
60
+ onError: (level2, message) => {
61
+ if (level2 !== "warning") parseError = message;
62
62
  }
63
63
  }).parseFromString(xml, "application/xml");
64
64
  } catch (error) {
@@ -728,8 +728,8 @@ function resolveRunFormatting(run, context = {}) {
728
728
  if (state) result[key] = true;
729
729
  }
730
730
  for (const key of OVERRIDE_KEYS) {
731
- for (const level of levels) {
732
- const value = level[key];
731
+ for (const level2 of levels) {
732
+ const value = level2[key];
733
733
  if (value !== void 0) result[key] = value;
734
734
  }
735
735
  }
@@ -802,8 +802,8 @@ function rgbToHsl(r, g, b) {
802
802
  }
803
803
  return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
804
804
  }
805
- function hslToRgb(h, s, l, roundChannel = Math.round, options) {
806
- const sC = options?.clampSaturation === false ? s : clampUnitInterval(s);
805
+ function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
806
+ const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
807
807
  const lC = clampUnitInterval(l);
808
808
  const hN = (h % 360 + 360) % 360;
809
809
  const c = (1 - Math.abs(2 * lC - 1)) * sC;
@@ -1292,13 +1292,13 @@ var APPLIED = /* @__PURE__ */ new Set([
1292
1292
  "lumMod",
1293
1293
  "lumOff"
1294
1294
  ]);
1295
- function resolveDrawingColor(color, theme, options) {
1295
+ function resolveDrawingColor(color, theme, options2) {
1296
1296
  const base = baseHex(color, theme);
1297
1297
  const rgb = base ? hexToRgbChannels(base) : null;
1298
1298
  if (!rgb) return void 0;
1299
- if (options?.transformOrder === "document") {
1299
+ if (options2?.transformOrder === "document") {
1300
1300
  const value = orderedColorTransforms(rgb, color.transforms);
1301
- const round3 = options.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
1301
+ const round3 = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
1302
1302
  return {
1303
1303
  hex: `#${toHex(round3(value.r))}${toHex(round3(value.g))}${toHex(round3(value.b))}`,
1304
1304
  alpha: value.alpha,
@@ -1349,7 +1349,7 @@ function resolveDrawingColor(color, theme, options) {
1349
1349
  if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
1350
1350
  const lumOff = parseDrawingFraction(find("lumOff"));
1351
1351
  if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
1352
- const round3 = options?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
1352
+ const round3 = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
1353
1353
  ({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round3));
1354
1354
  }
1355
1355
  let alpha = parseDrawingPercent(find("alpha")) ?? 1;
@@ -1806,7 +1806,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
1806
1806
  function lerpEdge(inner, outer, t) {
1807
1807
  return inner + (outer - inner) * t;
1808
1808
  }
1809
- function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
1809
+ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
1810
1810
  if (stops.length === 0) {
1811
1811
  return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
1812
1812
  }
@@ -1815,7 +1815,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
1815
1815
  const rects = [];
1816
1816
  const alphaRects = [];
1817
1817
  const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
1818
- const bands = options?.bands;
1818
+ const bands = options2?.bands;
1819
1819
  if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
1820
1820
  for (let i = bands; i >= 0; i -= 1) {
1821
1821
  const t = i / bands;
@@ -11339,13 +11339,297 @@ function groupRowsByCategory(rawCategories) {
11339
11339
  return { uniqueCategories, rowIndexesByCategory };
11340
11340
  }
11341
11341
 
11342
+ // chart/number-format-pattern.ts
11343
+ var NAMED_FORMAT_COLORS = {
11344
+ black: "#000000",
11345
+ blue: "#0000FF",
11346
+ cyan: "#00FFFF",
11347
+ green: "#00FF00",
11348
+ magenta: "#FF00FF",
11349
+ red: "#FF0000",
11350
+ white: "#FFFFFF",
11351
+ yellow: "#FFFF00"
11352
+ };
11353
+ var PLACEHOLDER = /[0#?]/u;
11354
+ function parsePattern(code) {
11355
+ let scale = 1;
11356
+ let scientific = false;
11357
+ let color;
11358
+ const chars = [];
11359
+ let inQuotes = false;
11360
+ for (let i = 0; i < code.length; i += 1) {
11361
+ const ch = code[i] ?? "";
11362
+ if (ch === '"') {
11363
+ inQuotes = !inQuotes;
11364
+ continue;
11365
+ }
11366
+ if (inQuotes) {
11367
+ chars.push({ ch, literal: true });
11368
+ continue;
11369
+ }
11370
+ if (ch === "\\" || ch === "*" || ch === "_") {
11371
+ const next = code[i + 1];
11372
+ i += 1;
11373
+ if (ch === "\\" && next !== void 0) {
11374
+ chars.push({ ch: next, literal: true });
11375
+ }
11376
+ continue;
11377
+ }
11378
+ if (ch === "%") {
11379
+ scale *= 100;
11380
+ chars.push({ ch, literal: true });
11381
+ continue;
11382
+ }
11383
+ if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
11384
+ scientific = true;
11385
+ chars.push({ ch: "E", literal: false });
11386
+ i += 1;
11387
+ continue;
11388
+ }
11389
+ if (ch === "[") {
11390
+ const close = code.indexOf("]", i);
11391
+ const token = code.slice(i + 1, close === -1 ? code.length : close);
11392
+ const named3 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
11393
+ if (named3 && color === void 0) {
11394
+ color = named3;
11395
+ }
11396
+ i = close === -1 ? code.length : close;
11397
+ continue;
11398
+ }
11399
+ chars.push({ ch, literal: false });
11400
+ }
11401
+ const firstDigit = chars.findIndex((c) => !c.literal && PLACEHOLDER.test(c.ch));
11402
+ if (firstDigit === -1) {
11403
+ return void 0;
11404
+ }
11405
+ let lastDigit = firstDigit;
11406
+ for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
11407
+ const c = chars[i];
11408
+ if (c && !c.literal && (PLACEHOLDER.test(c.ch) || c.ch === "." || c.ch === "," || c.ch === "E")) {
11409
+ lastDigit = i;
11410
+ break;
11411
+ }
11412
+ }
11413
+ const numeric = chars.slice(firstDigit, lastDigit + 1);
11414
+ const prefix2 = chars.slice(0, firstDigit).map((c) => c.ch).join("");
11415
+ const suffix = chars.slice(lastDigit + 1).map((c) => c.ch).join("");
11416
+ let grouped = false;
11417
+ let intDigits = 0;
11418
+ let required = 0;
11419
+ let optional = 0;
11420
+ let afterPoint = false;
11421
+ let inExponent = false;
11422
+ for (let i = 0; i < numeric.length; i += 1) {
11423
+ const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
11424
+ if (literal) {
11425
+ continue;
11426
+ }
11427
+ if (ch === "E") {
11428
+ inExponent = true;
11429
+ continue;
11430
+ }
11431
+ if (inExponent) {
11432
+ continue;
11433
+ }
11434
+ if (ch === ".") {
11435
+ afterPoint = true;
11436
+ continue;
11437
+ }
11438
+ if (ch === ",") {
11439
+ const next = numeric.slice(i + 1).find((c) => !c.literal);
11440
+ if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
11441
+ scale /= 1e3;
11442
+ } else {
11443
+ grouped = true;
11444
+ }
11445
+ continue;
11446
+ }
11447
+ if (!PLACEHOLDER.test(ch)) {
11448
+ continue;
11449
+ }
11450
+ if (afterPoint) {
11451
+ if (ch === "0") {
11452
+ required += 1;
11453
+ } else {
11454
+ optional += 1;
11455
+ }
11456
+ } else if (ch === "0") {
11457
+ intDigits += 1;
11458
+ }
11459
+ }
11460
+ return {
11461
+ prefix: prefix2,
11462
+ suffix,
11463
+ intDigits,
11464
+ decimals: { required, optional },
11465
+ grouped,
11466
+ scale,
11467
+ scientific,
11468
+ color
11469
+ };
11470
+ }
11471
+ function group(intPart) {
11472
+ return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
11473
+ }
11474
+ function applyPattern(value, pattern, forcePositive) {
11475
+ const scaled = value * pattern.scale;
11476
+ const magnitude = forcePositive ? Math.abs(scaled) : scaled;
11477
+ if (pattern.scientific) {
11478
+ const digits = pattern.decimals.required + pattern.decimals.optional;
11479
+ const exponential = magnitude.toExponential(digits);
11480
+ const [mantissa = "", exponent = "0"] = exponential.split("e");
11481
+ const sign = exponent.startsWith("-") ? "-" : "+";
11482
+ const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
11483
+ return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
11484
+ }
11485
+ const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
11486
+ let body = magnitude.toFixed(maxDecimals);
11487
+ if (pattern.decimals.optional > 0) {
11488
+ body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
11489
+ const [, frac = ""] = body.split(".");
11490
+ if (frac.length < pattern.decimals.required) {
11491
+ body = Number(body).toFixed(pattern.decimals.required);
11492
+ }
11493
+ }
11494
+ const [rawIntPart = "", fracPart] = body.split(".");
11495
+ let intPart = rawIntPart;
11496
+ const hasMinusChar = intPart.startsWith("-");
11497
+ const negative = hasMinusChar && Number(body) !== 0;
11498
+ if (hasMinusChar) {
11499
+ intPart = intPart.slice(1);
11500
+ }
11501
+ if (intPart.length < pattern.intDigits) {
11502
+ intPart = intPart.padStart(pattern.intDigits, "0");
11503
+ }
11504
+ if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
11505
+ intPart = "";
11506
+ }
11507
+ if (pattern.grouped) {
11508
+ intPart = group(intPart);
11509
+ }
11510
+ const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
11511
+ return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
11512
+ }
11513
+
11514
+ // chart/number-format.ts
11515
+ var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
11516
+ function sections(code) {
11517
+ const out = [];
11518
+ let current = "";
11519
+ let inQuotes = false;
11520
+ for (let i = 0; i < code.length; i += 1) {
11521
+ const ch = code[i];
11522
+ if (ch === '"') {
11523
+ inQuotes = !inQuotes;
11524
+ current += ch;
11525
+ continue;
11526
+ }
11527
+ if (ch === "\\") {
11528
+ current += ch + (code[i + 1] ?? "");
11529
+ i += 1;
11530
+ continue;
11531
+ }
11532
+ if (ch === ";" && !inQuotes) {
11533
+ out.push(current);
11534
+ current = "";
11535
+ continue;
11536
+ }
11537
+ current += ch;
11538
+ }
11539
+ out.push(current);
11540
+ return out;
11541
+ }
11542
+ function sectionFor(value, parts) {
11543
+ if (parts.length === 1) {
11544
+ return { code: parts[0] ?? "", forcePositive: false };
11545
+ }
11546
+ if (value < 0 && parts[1] !== void 0) {
11547
+ return { code: parts[1] ?? "", forcePositive: true };
11548
+ }
11549
+ if (value === 0 && parts[2] !== void 0) {
11550
+ return { code: parts[2] ?? "", forcePositive: false };
11551
+ }
11552
+ return { code: parts[0] ?? "", forcePositive: false };
11553
+ }
11554
+ function formatChartNumberWithColor(value, formatCode) {
11555
+ if (!Number.isFinite(value)) {
11556
+ return void 0;
11557
+ }
11558
+ const code = (formatCode ?? "").trim();
11559
+ if (GENERAL.has(code.toLowerCase())) {
11560
+ return void 0;
11561
+ }
11562
+ if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
11563
+ return void 0;
11564
+ }
11565
+ const { code: section, forcePositive } = sectionFor(value, sections(code));
11566
+ const pattern = parsePattern(section);
11567
+ if (!pattern) {
11568
+ return void 0;
11569
+ }
11570
+ try {
11571
+ return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
11572
+ } catch {
11573
+ return void 0;
11574
+ }
11575
+ }
11576
+ function formatChartNumber(value, formatCode) {
11577
+ return formatChartNumberWithColor(value, formatCode)?.text;
11578
+ }
11579
+
11580
+ // chart/data-label-text.ts
11581
+ var DATA_LABEL_SEPARATOR = ", ";
11582
+ var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
11583
+ var FLAG_KEYS = [
11584
+ "showValue",
11585
+ "showCategory",
11586
+ "showSeriesName",
11587
+ "showPercent",
11588
+ "showBubbleSize"
11589
+ ];
11590
+ function resolveDataLabelFlags(levels) {
11591
+ const { point, series, chart } = levels;
11592
+ const picked = {};
11593
+ for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
11594
+ const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
11595
+ return {
11596
+ showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
11597
+ showCategory: picked.showCategory === true,
11598
+ showSeriesName: picked.showSeriesName === true,
11599
+ showPercent: picked.showPercent === true,
11600
+ showBubbleSize: picked.showBubbleSize === true,
11601
+ separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
11602
+ };
11603
+ }
11604
+ function composeDataLabelText(input) {
11605
+ const { flags, value, numberFormat } = input;
11606
+ const parts = [];
11607
+ let valueColor;
11608
+ if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
11609
+ if (flags.showCategory && input.category) parts.push(input.category);
11610
+ if (flags.showValue) {
11611
+ const formatted = formatChartNumberWithColor(value, numberFormat);
11612
+ parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat));
11613
+ valueColor = formatted?.color;
11614
+ }
11615
+ if (flags.showPercent) {
11616
+ const base = input.percentBase;
11617
+ parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
11618
+ }
11619
+ if (flags.showBubbleSize && input.bubbleSize !== void 0)
11620
+ parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
11621
+ const text2 = parts.join(flags.separator);
11622
+ if (text2.length === 0) return void 0;
11623
+ return { text: text2, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
11624
+ }
11625
+
11342
11626
  // chart/bubble-radius.ts
11343
- function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
11344
- const scale = (options?.bubbleScale ?? 100) / 100;
11627
+ function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
11628
+ const scale = (options2?.bubbleScale ?? 100) / 100;
11345
11629
  if (sizeVal === void 0) return medianRadius * scale;
11346
11630
  const denom = maxBubble > 0 ? maxBubble : 1;
11347
11631
  const magnitude = Math.abs(sizeVal);
11348
- const ratio = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
11632
+ const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
11349
11633
  return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
11350
11634
  }
11351
11635
  function maxBubbleSize(sizes) {
@@ -11451,10 +11735,10 @@ function squarify(nodes, box) {
11451
11735
 
11452
11736
  // chart/hierarchy.ts
11453
11737
  function normalizeLevels(levels, pointCount) {
11454
- return levels.map((level) => {
11738
+ return levels.map((level2) => {
11455
11739
  let previous = "";
11456
11740
  return Array.from({ length: pointCount }, (_, index) => {
11457
- const label = level[index]?.trim() ?? "";
11741
+ const label = level2[index]?.trim() ?? "";
11458
11742
  if (label) previous = label;
11459
11743
  return label || previous;
11460
11744
  });
@@ -11612,12 +11896,12 @@ function computeSunburstArcs(series, cx, cy, maxR) {
11612
11896
  });
11613
11897
  return out;
11614
11898
  }
11615
- function hierarchyKey(levels, level, index) {
11616
- return levels.slice(level).map((labels) => labels[index] ?? "").join("\0");
11899
+ function hierarchyKey(levels, level2, index) {
11900
+ return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
11617
11901
  }
11618
11902
  function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
11619
- const levels = categoryLevels.filter((level) => level.length > 0);
11620
- const leafCount = Math.max(values.length, ...levels.map((level) => level.length), 0);
11903
+ const levels = categoryLevels.filter((level2) => level2.length > 0);
11904
+ const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
11621
11905
  if (levels.length === 0 || leafCount === 0) return [];
11622
11906
  const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
11623
11907
  const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
@@ -11628,15 +11912,15 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
11628
11912
  const rootLabels = levels[levels.length - 1] ?? [];
11629
11913
  const rootColors = /* @__PURE__ */ new Map();
11630
11914
  const out = [];
11631
- for (let level = levels.length - 1; level >= 0; level--) {
11632
- const ringIndex = levels.length - 1 - level;
11915
+ for (let level2 = levels.length - 1; level2 >= 0; level2--) {
11916
+ const ringIndex = levels.length - 1 - level2;
11633
11917
  const innerRadius = ringWidth * (ringIndex + 0.5);
11634
11918
  const outerRadius = ringWidth * (ringIndex + 1.5);
11635
11919
  let start = 0;
11636
11920
  while (start < leafCount) {
11637
- const key = hierarchyKey(levels, level, start);
11921
+ const key = hierarchyKey(levels, level2, start);
11638
11922
  let end = start + 1;
11639
- while (end < leafCount && hierarchyKey(levels, level, end) === key) end++;
11923
+ while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
11640
11924
  const startAngle = -Math.PI / 2 + (prefix2[start] ?? 0) / total * Math.PI * 2;
11641
11925
  const endAngle = -Math.PI / 2 + (prefix2[end] ?? 0) / total * Math.PI * 2;
11642
11926
  const rootLabel = rootLabels[start] ?? "";
@@ -11646,8 +11930,8 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
11646
11930
  colorIndex: rootColors.get(rootLabel) ?? start,
11647
11931
  opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
11648
11932
  level: ringIndex,
11649
- label: levels[level]?.[start] ?? "",
11650
- ...level === 0 && end === start + 1 ? { pointIndex: start } : {},
11933
+ label: levels[level2]?.[start] ?? "",
11934
+ ...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
11651
11935
  ...arcLabelPlacement(cx, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
11652
11936
  });
11653
11937
  start = end;
@@ -11673,14 +11957,14 @@ function scottBinCount(values, min, max) {
11673
11957
  const width = 3.49 * sd * values.length ** (-1 / 3);
11674
11958
  return Math.max(1, Math.ceil((max - min) / width));
11675
11959
  }
11676
- function computeHistogramBins(values, options, format = String) {
11677
- const closed = options.intervalClosed ?? "l";
11960
+ function computeHistogramBins(values, options2, format = String) {
11961
+ const closed = options2.intervalClosed ?? "l";
11678
11962
  const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
11679
11963
  if (finite2.length === 0) {
11680
11964
  return [];
11681
11965
  }
11682
- const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
11683
- const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
11966
+ const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
11967
+ const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
11684
11968
  const under = underflow === void 0 ? [] : finite2.filter(
11685
11969
  (item) => closed === "r" ? item.value <= underflow : item.value < underflow
11686
11970
  );
@@ -11697,8 +11981,8 @@ function computeHistogramBins(values, options, format = String) {
11697
11981
  if (regular.length > 0) {
11698
11982
  const min = Math.min(...regular.map((item) => item.value));
11699
11983
  const max = Math.max(...regular.map((item) => item.value));
11700
- const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
11701
- const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
11984
+ const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
11985
+ const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
11702
11986
  const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
11703
11987
  const count = requestedSize ? Math.max(
11704
11988
  closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
@@ -11749,9 +12033,9 @@ function aggregateByCategory(values, rawCategories) {
11749
12033
  }
11750
12034
 
11751
12035
  // chart/waterfall.ts
11752
- function buildWaterfallSteps(values, options) {
12036
+ function buildWaterfallSteps(values, options2) {
11753
12037
  const subtotalIndices = new Set(
11754
- options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
12038
+ options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
11755
12039
  );
11756
12040
  const steps = [];
11757
12041
  let runningTotal = 0;
@@ -11811,13 +12095,13 @@ var noFit = () => ({
11811
12095
  rSquared: 0,
11812
12096
  coefficients: []
11813
12097
  });
11814
- function fitModel(options, xVals, yVals) {
12098
+ function fitModel(options2, xVals, yVals) {
11815
12099
  const xs = [...xVals];
11816
12100
  const ys = [...yVals];
11817
- switch (options.kind) {
12101
+ switch (options2.kind) {
11818
12102
  case "linear": {
11819
12103
  const reg = computeLinearRegression(xs, ys);
11820
- const fixed = options.intercept;
12104
+ const fixed = options2.intercept;
11821
12105
  const slope = fixed !== void 0 ? ys.reduce((s, y, i) => s + (y - fixed) * xs[i], 0) / xs.reduce((s, x) => s + x * x, 0) : reg.slope;
11822
12106
  const b = fixed ?? reg.intercept;
11823
12107
  return {
@@ -11867,7 +12151,7 @@ function fitModel(options, xVals, yVals) {
11867
12151
  };
11868
12152
  }
11869
12153
  case "polynomial": {
11870
- const order = Math.min(options.order ?? 2, 6);
12154
+ const order = Math.min(options2.order ?? 2, 6);
11871
12155
  const coeffs = fitPolynomial(xs, ys, order);
11872
12156
  const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
11873
12157
  return {
@@ -11881,11 +12165,11 @@ function fitModel(options, xVals, yVals) {
11881
12165
  return void 0;
11882
12166
  }
11883
12167
  }
11884
- function fitChartTrendline(options, xVals, yVals) {
12168
+ function fitChartTrendline(options2, xVals, yVals) {
11885
12169
  const count = yVals.length;
11886
12170
  if (count < 2) return noFit();
11887
- if (options.kind === "movingAvg") {
11888
- const period = options.period ?? 2;
12171
+ if (options2.kind === "movingAvg") {
12172
+ const period = options2.period ?? 2;
11889
12173
  const points2 = [];
11890
12174
  for (let i = period - 1; i < count; i++) {
11891
12175
  let sum = 0;
@@ -11894,10 +12178,10 @@ function fitChartTrendline(options, xVals, yVals) {
11894
12178
  }
11895
12179
  return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
11896
12180
  }
11897
- const model = fitModel(options, xVals, yVals);
12181
+ const model = fitModel(options2, xVals, yVals);
11898
12182
  if (!model) return noFit();
11899
- const startX = Math.min(...xVals) - (options.backward ?? 0);
11900
- const endX = Math.max(...xVals) + (options.forward ?? 0);
12183
+ const startX = Math.min(...xVals) - (options2.backward ?? 0);
12184
+ const endX = Math.max(...xVals) + (options2.forward ?? 0);
11901
12185
  const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
11902
12186
  const points = [];
11903
12187
  for (let step = 0; step <= steps; step++) {
@@ -11920,19 +12204,78 @@ function chartSampleVariance(values) {
11920
12204
  const mean = values.reduce((sum, value) => sum + value, 0) / count;
11921
12205
  return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
11922
12206
  }
11923
- function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
11924
- switch (options.valueType) {
12207
+ function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
12208
+ switch (options2.valueType) {
11925
12209
  case "fixedVal":
11926
- return options.value ?? 0;
12210
+ return options2.value ?? 0;
11927
12211
  case "percentage":
11928
- return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
12212
+ return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
11929
12213
  case "stdDev":
11930
- return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
12214
+ return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
11931
12215
  case "stdErr":
11932
12216
  return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
11933
12217
  case "cust":
11934
- return side === "plus" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
12218
+ return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
12219
+ }
12220
+ }
12221
+
12222
+ // chart/pie-best-fit.ts
12223
+ var PX_PER_PT = 4 / 3;
12224
+ var BEST_FIT_RIM_INSET = 4 * PX_PER_PT;
12225
+ var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT;
12226
+ var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT;
12227
+ function farCorner(x, y, w, h) {
12228
+ return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h / 2);
12229
+ }
12230
+ function insideDistance(ux, uy, w, h, limit) {
12231
+ if (farCorner(0, 0, w, h) > limit) {
12232
+ return void 0;
11935
12233
  }
12234
+ let lo = 0;
12235
+ let hi = limit;
12236
+ for (let i = 0; i < 40; i++) {
12237
+ const mid = (lo + hi) / 2;
12238
+ if (farCorner(mid * ux, mid * uy, w, h) > limit) {
12239
+ hi = mid;
12240
+ } else {
12241
+ lo = mid;
12242
+ }
12243
+ }
12244
+ return lo;
12245
+ }
12246
+ function edgeOverhang(x, y, w, h, slice) {
12247
+ let worst = Number.NEGATIVE_INFINITY;
12248
+ const corners = [
12249
+ [-w / 2, -h / 2],
12250
+ [w / 2, -h / 2],
12251
+ [-w / 2, h / 2],
12252
+ [w / 2, h / 2]
12253
+ ];
12254
+ for (const [dx, dy] of corners) {
12255
+ const px = x + dx;
12256
+ const py = y + dy;
12257
+ const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px;
12258
+ const fromEnd = Math.sin(slice.endAngle) * px - Math.cos(slice.endAngle) * py;
12259
+ worst = Math.max(worst, -fromStart, -fromEnd);
12260
+ }
12261
+ return worst;
12262
+ }
12263
+ function placeBestFitLabel(slice, w, h) {
12264
+ const mid = (slice.startAngle + slice.endAngle) / 2;
12265
+ const ux = Math.cos(mid);
12266
+ const uy = Math.sin(mid);
12267
+ const distance = insideDistance(ux, uy, w, h, slice.outerR - BEST_FIT_RIM_INSET);
12268
+ if (distance !== void 0) {
12269
+ const x = distance * ux;
12270
+ const y = distance * uy;
12271
+ const reflex = slice.endAngle - slice.startAngle >= Math.PI;
12272
+ if (reflex || edgeOverhang(x, y, w, h, slice) <= BEST_FIT_EDGE_TOLERANCE) {
12273
+ return { x: slice.cx + x, y: slice.cy + y, inside: true };
12274
+ }
12275
+ }
12276
+ const extent = Math.abs(ux) * w / 2 + Math.abs(uy) * h / 2;
12277
+ const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent;
12278
+ return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
11936
12279
  }
11937
12280
 
11938
12281
  // chart/color-palettes.ts
@@ -12248,6 +12591,191 @@ function chartCacheValues(cache2) {
12248
12591
  }
12249
12592
  var chartSourceValues = (source) => chartCacheValues(source?.cache ?? source?.levels?.[0]);
12250
12593
 
12594
+ // chart/marker-shape.ts
12595
+ var CHART_PX_PER_PT = 4 / 3;
12596
+ var DEFAULT_MARKER_OUTLINE_PT = 0.75;
12597
+ var AUTOMATIC_MARKER_CYCLE = [
12598
+ "diamond",
12599
+ "square",
12600
+ "triangle",
12601
+ "x",
12602
+ "star",
12603
+ "circle",
12604
+ "plus",
12605
+ "dot",
12606
+ "dash"
12607
+ ];
12608
+ function automaticMarkerSymbol(seriesIdx) {
12609
+ const length = AUTOMATIC_MARKER_CYCLE.length;
12610
+ const normalized = (Math.trunc(seriesIdx) % length + length) % length;
12611
+ return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
12612
+ }
12613
+ function markerRadius(size, defaultRadius) {
12614
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
12615
+ return defaultRadius;
12616
+ }
12617
+ return size / 2;
12618
+ }
12619
+ function polygonPoints(vertices) {
12620
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
12621
+ }
12622
+ function starVertices(cx, cy, r) {
12623
+ const inner = r * 0.5;
12624
+ const out = [];
12625
+ for (let i = 0; i < 10; i++) {
12626
+ const radius = i % 2 === 0 ? r : inner;
12627
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
12628
+ out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
12629
+ }
12630
+ return out;
12631
+ }
12632
+ function rectPolygon(x, y, w, h) {
12633
+ return polygonPoints([
12634
+ [x, y],
12635
+ [x + w, y],
12636
+ [x + w, y + h],
12637
+ [x, y + h]
12638
+ ]);
12639
+ }
12640
+ function buildMarkerPrimitive(input) {
12641
+ const { symbol, cx, cy, fill } = input;
12642
+ const part = input.part === void 0 ? {} : { part: input.part };
12643
+ if (symbol === "none") {
12644
+ return null;
12645
+ }
12646
+ const r = markerRadius(input.size, input.defaultRadius);
12647
+ const outline = input.stroke ? {
12648
+ stroke: input.stroke,
12649
+ strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
12650
+ } : void 0;
12651
+ const polygonStroke = outline ?? { stroke: fill, strokeWidth: 0 };
12652
+ const lineStroke = input.stroke ?? fill;
12653
+ switch (symbol) {
12654
+ case "square":
12655
+ case "dash": {
12656
+ const h = symbol === "dash" ? r * 0.64 : r * 2;
12657
+ const y = cy - h / 2;
12658
+ if (outline) {
12659
+ return {
12660
+ kind: "polygon",
12661
+ points: rectPolygon(cx - r, y, r * 2, h),
12662
+ fill,
12663
+ ...outline,
12664
+ ...part
12665
+ };
12666
+ }
12667
+ return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
12668
+ }
12669
+ case "diamond":
12670
+ return {
12671
+ kind: "polygon",
12672
+ points: polygonPoints([
12673
+ [cx, cy - r],
12674
+ [cx + r, cy],
12675
+ [cx, cy + r],
12676
+ [cx - r, cy]
12677
+ ]),
12678
+ fill,
12679
+ ...polygonStroke,
12680
+ ...part
12681
+ };
12682
+ case "triangle":
12683
+ return {
12684
+ kind: "polygon",
12685
+ points: polygonPoints([
12686
+ [cx, cy - r],
12687
+ [cx + r * 0.9, cy + r * 0.75],
12688
+ [cx - r * 0.9, cy + r * 0.75]
12689
+ ]),
12690
+ fill,
12691
+ ...polygonStroke,
12692
+ ...part
12693
+ };
12694
+ case "star":
12695
+ return {
12696
+ kind: "polygon",
12697
+ points: polygonPoints(starVertices(cx, cy, r)),
12698
+ fill,
12699
+ ...polygonStroke,
12700
+ ...part
12701
+ };
12702
+ case "plus":
12703
+ return {
12704
+ kind: "path",
12705
+ d: `M${(cx - r).toFixed(2)},${cy.toFixed(2)} L${(cx + r).toFixed(2)},${cy.toFixed(2)} M${cx.toFixed(2)},${(cy - r).toFixed(2)} L${cx.toFixed(2)},${(cy + r).toFixed(2)}`,
12706
+ fill: "none",
12707
+ stroke: lineStroke,
12708
+ strokeWidth: Math.max(1, r * 0.4),
12709
+ ...part
12710
+ };
12711
+ case "x":
12712
+ return {
12713
+ kind: "path",
12714
+ d: `M${(cx - r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx + r).toFixed(2)},${(cy + r).toFixed(2)} M${(cx + r).toFixed(2)},${(cy - r).toFixed(2)} L${(cx - r).toFixed(2)},${(cy + r).toFixed(2)}`,
12715
+ fill: "none",
12716
+ stroke: lineStroke,
12717
+ strokeWidth: Math.max(1, r * 0.4),
12718
+ ...part
12719
+ };
12720
+ case "dot":
12721
+ return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline };
12722
+ default:
12723
+ return { kind: "circle", cx, cy, r, fill, ...part, ...outline };
12724
+ }
12725
+ }
12726
+
12727
+ // chart/render/chart-view-markers.ts
12728
+ function summaryMarkers(source, group2, seriesPosition) {
12729
+ if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
12730
+ const enabled = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
12731
+ const symbol = source.marker?.symbol;
12732
+ const marker = {
12733
+ ...source.marker,
12734
+ symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
12735
+ };
12736
+ const pointMarkers = {};
12737
+ for (const point of source.dataPoints) {
12738
+ if (point.index === void 0 || !point.marker) continue;
12739
+ const override = point.marker;
12740
+ pointMarkers[point.index] = {
12741
+ ...marker,
12742
+ ...override,
12743
+ ...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
12744
+ ...marker.spPr || override.spPr ? {
12745
+ spPr: {
12746
+ ...marker.spPr,
12747
+ ...override.spPr,
12748
+ ...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
12749
+ }
12750
+ } : {}
12751
+ };
12752
+ }
12753
+ return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
12754
+ }
12755
+ function seriesMarkerViews(source, drawingColor) {
12756
+ const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
12757
+ const resolve = (marker) => {
12758
+ const fill = fillColor(marker.spPr?.fill);
12759
+ const stroke = fillColor(marker.spPr?.line?.fill);
12760
+ const width = marker.spPr?.line?.widthEmu;
12761
+ return {
12762
+ ...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
12763
+ ...marker.size !== void 0 ? { size: marker.size } : {},
12764
+ ...fill !== void 0 ? { fill } : {},
12765
+ ...stroke !== void 0 ? { stroke } : {},
12766
+ ...width !== void 0 ? { strokeWidth: width / 9525 } : {}
12767
+ };
12768
+ };
12769
+ return {
12770
+ ...source.marker ? { marker: resolve(source.marker) } : {},
12771
+ ...source.pointMarkers ? {
12772
+ pointMarkers: Object.fromEntries(
12773
+ Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
12774
+ )
12775
+ } : {}
12776
+ };
12777
+ }
12778
+
12251
12779
  // chart/render/summary-analysis.ts
12252
12780
  function summaryTrendline(source) {
12253
12781
  const kind = chartTrendlineKind(source.trendlineType);
@@ -12288,6 +12816,41 @@ function summaryAnalysis(series) {
12288
12816
  };
12289
12817
  }
12290
12818
 
12819
+ // chart/render/summary-labels.ts
12820
+ function level(options2, custom) {
12821
+ const out = {};
12822
+ if (options2.deleted !== void 0) out.deleted = options2.deleted;
12823
+ if (options2.showValue !== void 0) out.showValue = options2.showValue;
12824
+ if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
12825
+ if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
12826
+ if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
12827
+ if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
12828
+ if (options2.separator !== void 0) out.separator = options2.separator;
12829
+ if (options2.position) out.position = options2.position;
12830
+ if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
12831
+ if (custom?.text !== void 0) out.text = custom.text;
12832
+ return out;
12833
+ }
12834
+ function shows(levels, point) {
12835
+ const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
12836
+ return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
12837
+ }
12838
+ function summaryDataLabels(series, group2) {
12839
+ const own2 = series.dataLabels;
12840
+ if (!own2 && !group2) return void 0;
12841
+ const out = {};
12842
+ if (group2) out.chart = level(group2);
12843
+ if (own2) out.series = level(own2);
12844
+ const points = {};
12845
+ for (const labels of [group2, own2])
12846
+ for (const label of labels?.labels ?? [])
12847
+ if (label.index !== void 0)
12848
+ points[label.index] = { ...points[label.index], ...level(label, label.tx) };
12849
+ if (Object.keys(points).length) out.points = points;
12850
+ if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
12851
+ return out;
12852
+ }
12853
+
12291
12854
  // chart/render/summary-from-space.ts
12292
12855
  var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
12293
12856
  var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
@@ -12305,7 +12868,7 @@ var GROUP_TYPES = {
12305
12868
  surface: "surface"
12306
12869
  };
12307
12870
  var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
12308
- function chartSummarySeries(source, chartType) {
12871
+ function chartSummarySeries(source, chartType, groupLabels) {
12309
12872
  const categories = source.categories ?? source.xValues;
12310
12873
  const values = source.values ?? source.yValues;
12311
12874
  const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
@@ -12313,6 +12876,7 @@ function chartSummarySeries(source, chartType) {
12313
12876
  categories: chartSourceValues(categories),
12314
12877
  values: chartSourceValues(values).map(numeric)
12315
12878
  };
12879
+ if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
12316
12880
  if (source.bubbleSizes) {
12317
12881
  out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
12318
12882
  if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
@@ -12341,6 +12905,8 @@ function chartSummarySeries(source, chartType) {
12341
12905
  }
12342
12906
  if (Object.keys(points).length) out.pointColors = points;
12343
12907
  if (Object.keys(pointFills).length) out.pointFills = pointFills;
12908
+ const dataLabels = summaryDataLabels(source, groupLabels);
12909
+ if (dataLabels) out.dataLabels = dataLabels;
12344
12910
  Object.assign(out, summaryAnalysis(source));
12345
12911
  return out;
12346
12912
  }
@@ -12349,12 +12915,12 @@ function valueAxisId(chartSpace, axisIds) {
12349
12915
  (id) => chartSpace.plotArea.axes.some((a) => a.id === id && a.kind === "val")
12350
12916
  );
12351
12917
  }
12352
- function stockStyle(group) {
12918
+ function stockStyle(group2) {
12353
12919
  return {
12354
- ...group.hiLowLinesSpPr ? { hiLowLines: group.hiLowLinesSpPr } : {},
12355
- ...group.upBars?.spPr ? { upBars: group.upBars.spPr } : {},
12356
- ...group.downBars?.spPr ? { downBars: group.downBars.spPr } : {},
12357
- ...group.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group.upDownBarsGapWidth }
12920
+ ...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
12921
+ ...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
12922
+ ...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
12923
+ ...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
12358
12924
  };
12359
12925
  }
12360
12926
  function extraGroups(chartSpace, firstType) {
@@ -12362,54 +12928,62 @@ function extraGroups(chartSpace, firstType) {
12362
12928
  if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
12363
12929
  const primary = valueAxisId(chartSpace, first3.axisIds);
12364
12930
  const out = [];
12365
- for (const group of rest) {
12366
- const stockOverColumns = group.kind === "stock" && firstType === "column";
12367
- if (group.is3D || !(["bar", "line", "area"].includes(group.kind) || stockOverColumns)) continue;
12368
- const type = group.kind === "bar" ? "column" : group.kind;
12931
+ for (const group2 of rest) {
12932
+ const stockOverColumns = group2.kind === "stock" && firstType === "column";
12933
+ if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
12934
+ const type = group2.kind === "bar" ? "column" : group2.kind;
12369
12935
  const entry = {
12370
12936
  chartType: type,
12371
- series: group.series.map((source) => chartSummarySeries(source, type)),
12372
- secondary: valueAxisId(chartSpace, group.axisIds) !== primary
12937
+ series: group2.series.map((source, index) => ({
12938
+ ...chartSummarySeries(source, type, group2.dataLabels),
12939
+ ...summaryMarkers(source, group2, index)
12940
+ })),
12941
+ secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
12373
12942
  };
12374
- if (group.grouping && GROUPINGS.has(group.grouping))
12375
- entry.grouping = group.grouping;
12376
- if (type === "stock") entry.stock = stockStyle(group);
12943
+ if (group2.grouping && GROUPINGS.has(group2.grouping))
12944
+ entry.grouping = group2.grouping;
12945
+ if (type === "stock") entry.stock = stockStyle(group2);
12377
12946
  if (type === "column") {
12378
- if (group.gapWidth !== void 0) entry.barGapWidth = group.gapWidth;
12379
- if (group.overlap !== void 0) entry.barOverlap = group.overlap;
12947
+ if (group2.gapWidth !== void 0) entry.barGapWidth = group2.gapWidth;
12948
+ if (group2.overlap !== void 0) entry.barOverlap = group2.overlap;
12380
12949
  }
12381
12950
  if (entry.series.length) out.push(entry);
12382
12951
  }
12383
12952
  return out;
12384
12953
  }
12385
12954
  function chartSummaryFromSpace(chartSpace, extras = {}) {
12386
- const group = chartSpace.plotArea.groups[0];
12387
- let chartType = group ? GROUP_TYPES[group.kind] : "column";
12388
- if (chartType === "bar" && group?.barDirection !== "bar") chartType = "column";
12389
- const series = (group?.series ?? []).map((source) => chartSummarySeries(source, chartType));
12955
+ const group2 = chartSpace.plotArea.groups[0];
12956
+ let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
12957
+ if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
12958
+ const series = (group2?.series ?? []).map((source, index) => ({
12959
+ ...chartSummarySeries(source, chartType, group2?.dataLabels),
12960
+ ...group2 ? summaryMarkers(source, group2, index) : {}
12961
+ }));
12390
12962
  const summary = {
12391
12963
  chartType,
12392
12964
  series,
12393
- showLegend: chartSpace.legend !== void 0
12965
+ showLegend: chartSpace.legend !== void 0,
12966
+ axes: chartSpace.plotArea.axes,
12967
+ axisIds: group2?.axisIds ?? []
12394
12968
  };
12395
12969
  const combined = extraGroups(chartSpace, chartType);
12396
12970
  if (combined.length) summary.extraGroups = combined;
12397
- if (chartType === "stock" && group) summary.stock = stockStyle(group);
12398
- if (chartType === "bubble" && group) {
12399
- const sizeRepresents = group.sizeRepresents === "w" ? "w" : "area";
12971
+ if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
12972
+ if (chartType === "bubble" && group2) {
12973
+ const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
12400
12974
  summary.bubble = {
12401
12975
  sizeRepresents,
12402
- ...group.bubbleScale === void 0 ? {} : { bubbleScale: group.bubbleScale },
12403
- showNegativeBubbles: group.showNegativeBubbles === true
12976
+ ...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
12977
+ showNegativeBubbles: group2.showNegativeBubbles === true
12404
12978
  };
12405
12979
  }
12406
- const grouping = group?.grouping;
12980
+ const grouping = group2?.grouping;
12407
12981
  if (grouping && GROUPINGS.has(grouping))
12408
12982
  summary.grouping = grouping;
12409
12983
  if (chartType === "bar" || chartType === "column") {
12410
12984
  for (const [value, field, fallback, min, max] of [
12411
- [group?.gapWidth, "barGapWidth", 150, 0, 500],
12412
- [group?.overlap, "barOverlap", 0, -100, 100]
12985
+ [group2?.gapWidth, "barGapWidth", 150, 0, 500],
12986
+ [group2?.overlap, "barOverlap", 0, -100, 100]
12413
12987
  ]) {
12414
12988
  const resolved = value ?? fallback;
12415
12989
  if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
@@ -12471,72 +13045,438 @@ function chartBarSpacing(chart) {
12471
13045
  };
12472
13046
  }
12473
13047
 
12474
- // chart/render/chart-svg-bars.ts
12475
- function barLayout(model, frame2) {
12476
- const count = Math.max(1, model.series.length);
12477
- const geometry = clusteredBarGeometry(frame2.bandSize, count, chartBarSpacing(model));
12478
- const barSize = geometry.singleBarWidth;
12479
- const offset = (si) => model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
12480
- return { barSize, offset };
12481
- }
12482
- function bars(model, frame2, out, values) {
12483
- const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
12484
- const { barSize, offset: barOffset } = barLayout(model, frame2);
12485
- const base = frame2.value(0);
12486
- const pos = new Array(model.categories.length).fill(0);
12487
- const neg = new Array(model.categories.length).fill(0);
12488
- model.series.forEach((s, si) => {
12489
- values[si]?.forEach((v, i) => {
12490
- if (v === null || i >= model.categories.length) return;
12491
- let from = 0;
12492
- let to = v;
12493
- if (stacked) {
12494
- const acc = v >= 0 ? pos : neg;
12495
- from = acc[i] ?? 0;
12496
- to = from + v;
12497
- acc[i] = to;
12498
- }
12499
- const a = stacked ? frame2.value(from) : base;
12500
- const b = frame2.value(to);
12501
- const offset = barOffset(si);
12502
- const center = frame2.band(i);
12503
- const width = model.horizontal ? Math.abs(b - a) : barSize;
12504
- const height = model.horizontal ? barSize : Math.abs(b - a);
12505
- let color = s.pointColors?.[i] ?? s.color;
12506
- const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
12507
- if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
12508
- const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
12509
- if (baseId) {
12510
- const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
12511
- const def = buildChartGradientDef(id, gradient, {
12512
- width: Number(n(width)),
12513
- height: Number(n(height)),
12514
- shape: "rect"
12515
- });
12516
- out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
12517
- color = `url(#${id})`;
12518
- }
12519
- }
12520
- out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
12521
- if (model.horizontal)
12522
- out.push(
12523
- rect2(Math.min(a, b), center + offset, Math.abs(b - a), barSize, color, s.shadowFilter)
12524
- );
12525
- else
12526
- out.push(
12527
- rect2(center + offset, Math.min(a, b), barSize, Math.abs(b - a), color, s.shadowFilter)
12528
- );
12529
- out.push("</g>");
12530
- });
12531
- });
13048
+ // chart/render/theme-palette.ts
13049
+ var THEME_SLOTS = [
13050
+ "lt1",
13051
+ "dk1",
13052
+ "lt2",
13053
+ "dk2",
13054
+ "accent1",
13055
+ "accent2",
13056
+ "accent3",
13057
+ "accent4",
13058
+ "accent5",
13059
+ "accent6",
13060
+ "hlink",
13061
+ "folHlink"
13062
+ ];
13063
+ var DEFAULT_THEME_COLORS = [
13064
+ "FFFFFF",
13065
+ "000000",
13066
+ "E7E6E6",
13067
+ "44546A",
13068
+ "4472C4",
13069
+ "ED7D31",
13070
+ "A5A5A5",
13071
+ "FFC000",
13072
+ "5B9BD5",
13073
+ "70AD47",
13074
+ "0563C1",
13075
+ "954F72"
13076
+ ];
13077
+ function themeColor(theme, index) {
13078
+ const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
13079
+ return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
12532
13080
  }
12533
13081
 
12534
- // chart/render/chart-svg-analysis.ts
12535
- var DASHES = {
12536
- dot: [1, 3],
12537
- dash: [4, 3],
12538
- lgDash: [8, 3],
12539
- dashDot: [4, 3, 1, 3],
13082
+ // chart/render/chart-colors.ts
13083
+ function chartColorScheme(theme) {
13084
+ const slots = Object.fromEntries(
13085
+ THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
13086
+ );
13087
+ return {
13088
+ ...slots,
13089
+ bg1: slots.lt1,
13090
+ tx1: slots.dk1,
13091
+ bg2: slots.lt2,
13092
+ tx2: slots.dk2
13093
+ };
13094
+ }
13095
+ function autoSeriesColor(theme, index) {
13096
+ const i = Math.max(0, Math.floor(index));
13097
+ return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
13098
+ }
13099
+
13100
+ // chart/text-inheritance.ts
13101
+ var TEXT_KEYS = [
13102
+ "fontSize",
13103
+ "bold",
13104
+ "italic",
13105
+ "underline",
13106
+ "typeface",
13107
+ "textColor",
13108
+ "fontRef"
13109
+ ];
13110
+ var TEXT_PARTS = [
13111
+ "title",
13112
+ "axisTitle",
13113
+ "categoryAxis",
13114
+ "valueAxis",
13115
+ "legend",
13116
+ "dataLabel"
13117
+ ];
13118
+ function inheritChartText(part, entry, builtIn, root) {
13119
+ if (!root || !TEXT_PARTS.includes(part)) return entry;
13120
+ const out = { ...entry };
13121
+ for (const key of TEXT_KEYS) {
13122
+ delete out[key];
13123
+ const value = root[key] ?? builtIn?.[key];
13124
+ if (value !== void 0) Object.assign(out, { [key]: value });
13125
+ }
13126
+ if (part === "title" && root.fontSize !== void 0) out.fontSize = root.fontSize * 1.2;
13127
+ if (root.textEffectsXml !== void 0) out.textEffectsXml = root.textEffectsXml;
13128
+ return out;
13129
+ }
13130
+
13131
+ // chart/render/chart-appearance.ts
13132
+ var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
13133
+ function typeface(entry, theme) {
13134
+ const name = entry.typeface;
13135
+ if (name?.startsWith("+mj-")) return theme.majorFont;
13136
+ if (name?.startsWith("+mn-")) return theme.minorFont;
13137
+ return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
13138
+ }
13139
+ function chartAppearance(chart, theme) {
13140
+ const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
13141
+ const entries = {};
13142
+ for (const part of CHART_STYLE_PARTS) {
13143
+ const base = chart.styleDefinition?.entries[part];
13144
+ const direct = chart.formatting?.entries[part];
13145
+ if (!defaults[part] && !base && !direct) continue;
13146
+ const entry = {
13147
+ ...inheritChartText(
13148
+ part,
13149
+ { ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
13150
+ defaults[part],
13151
+ chart.formatting?.textDefaults
13152
+ ),
13153
+ ...direct,
13154
+ sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
13155
+ };
13156
+ if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
13157
+ entries[part] = entry;
13158
+ }
13159
+ const scheme = chartColorScheme(theme);
13160
+ const resolve = (color) => resolveDrawingColor(
13161
+ color,
13162
+ { scheme: (name) => scheme[name] },
13163
+ { hslRounding: "halfDown", transformOrder: "document" }
13164
+ );
13165
+ const out = resolveChartStyleDefinition(
13166
+ { entries},
13167
+ (color) => drawingColorCss(resolve(color))
13168
+ ) ?? {};
13169
+ for (const part of CHART_STYLE_PARTS) {
13170
+ const entry = entries[part];
13171
+ if (!entry) continue;
13172
+ const family = typeface(entry, theme);
13173
+ const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
13174
+ scheme: (name) => scheme[name]
13175
+ });
13176
+ if (shadow) (out[part] ??= {}).textShadow = shadow;
13177
+ if (family) (out[part] ??= {}).typeface = family;
13178
+ if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
13179
+ if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
13180
+ if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
13181
+ if (entry.fill?.kind === "gradient") {
13182
+ (out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
13183
+ }
13184
+ }
13185
+ return out;
13186
+ }
13187
+
13188
+ // text/css-font-family.ts
13189
+ var FALLBACKS = {
13190
+ calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
13191
+ "calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
13192
+ cambria: '"Cambria", "Caladea", Georgia, serif',
13193
+ arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
13194
+ "times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
13195
+ "courier new": '"Courier New", "Liberation Mono", monospace',
13196
+ aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
13197
+ };
13198
+ function cssFontFamily(name) {
13199
+ const known = FALLBACKS[name.toLowerCase()];
13200
+ if (known) return known;
13201
+ const quoted = `"${name.replace(/["\\]/g, "")}"`;
13202
+ return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
13203
+ }
13204
+
13205
+ // chart/render/chart-svg-appearance.ts
13206
+ var nextPaintId = 0;
13207
+ function chartGradientPaint(model, width = 1024, height = 768) {
13208
+ const prefix2 = `xlsx-chart-${++nextPaintId}`;
13209
+ const appearance = { ...model.appearance };
13210
+ const defs = [];
13211
+ const shadowPaint = (shadow, suffix) => {
13212
+ const id = `${prefix2}-${suffix}`;
13213
+ const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
13214
+ defs.push(
13215
+ `<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
13216
+ );
13217
+ return `url(#${id})`;
13218
+ };
13219
+ for (const [part, entry] of Object.entries(appearance)) {
13220
+ if (entry?.textShadow)
13221
+ appearance[part] = {
13222
+ ...entry,
13223
+ textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
13224
+ };
13225
+ }
13226
+ const paint2 = (gradient, suffix, bounds) => {
13227
+ const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
13228
+ defs.push(chartGradientMarkup(def));
13229
+ return `url(#${def.id})`;
13230
+ };
13231
+ for (const part of ["chartArea", "plotArea"]) {
13232
+ const entry = appearance[part];
13233
+ if (!entry?.gradient) continue;
13234
+ if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
13235
+ appearance[part] = {
13236
+ ...entry,
13237
+ fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
13238
+ };
13239
+ }
13240
+ const series = model.series.map((source, index) => {
13241
+ const view = { ...source };
13242
+ if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
13243
+ const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
13244
+ if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
13245
+ if (source.pointGradients) {
13246
+ view.pointColors = [...source.pointColors ?? []];
13247
+ for (const [key, gradient] of Object.entries(source.pointGradients))
13248
+ view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
13249
+ }
13250
+ return view;
13251
+ });
13252
+ return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
13253
+ }
13254
+ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
13255
+ const entry = model.appearance?.[part];
13256
+ return {
13257
+ size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
13258
+ ...entry?.color === void 0 ? {} : { fill: entry.color },
13259
+ ...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
13260
+ ...entry?.italic === void 0 ? {} : { italic: entry.italic },
13261
+ ...entry?.underline === void 0 ? {} : { underline: entry.underline },
13262
+ ...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
13263
+ ...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
13264
+ };
13265
+ }
13266
+ function chartStroke(model, part) {
13267
+ const entry = model.appearance?.[part];
13268
+ return {
13269
+ color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
13270
+ width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
13271
+ };
13272
+ }
13273
+ function chartAreaRect(model, part, area) {
13274
+ if (area.w <= 0 || area.h <= 0) return "";
13275
+ const entry = model.appearance?.[part];
13276
+ let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
13277
+ let defs = "";
13278
+ if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
13279
+ const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
13280
+ width: area.w,
13281
+ height: area.h,
13282
+ shape: "rect"
13283
+ });
13284
+ defs = `<defs>${chartGradientMarkup(def)}</defs>`;
13285
+ fill = `url(#${def.id})`;
13286
+ }
13287
+ const stroke = entry?.lineColor ?? "none";
13288
+ if (fill === "none" && stroke === "none") return "";
13289
+ const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
13290
+ return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
13291
+ }
13292
+
13293
+ // chart/render/chart-svg-labels.ts
13294
+ var GAP = 3;
13295
+ var LINE = 1.2;
13296
+ var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
13297
+ function measure(model, label) {
13298
+ const attrs = chartTextAttributes(model, "dataLabel", 10);
13299
+ const size = attrs.size ?? 10;
13300
+ const lines = label.text.split("\n");
13301
+ return {
13302
+ lines,
13303
+ size,
13304
+ w: Math.max(...lines.map((l) => textWidth(l, size))),
13305
+ h: lines.length * size * LINE,
13306
+ attrs
13307
+ };
13308
+ }
13309
+ function draw(m, label, x, y, anchor, out) {
13310
+ const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
13311
+ m.lines.forEach((line3, k) => {
13312
+ const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
13313
+ out.push(text(x, lineY, line3, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
13314
+ });
13315
+ }
13316
+ function barLabels(model, marks, out) {
13317
+ const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
13318
+ for (const mark of marks) {
13319
+ const label = mark.series.labels?.[mark.index];
13320
+ if (!label) continue;
13321
+ const m = measure(model, label);
13322
+ let position = label.position ?? (stacked ? "ctr" : "outEnd");
13323
+ if (stacked && position === "outEnd") position = "ctr";
13324
+ const cx = mark.x + mark.w / 2;
13325
+ const cy = mark.y + mark.h / 2;
13326
+ if (model.horizontal) {
13327
+ const end = mark.negative ? mark.x : mark.x + mark.w;
13328
+ const base = mark.negative ? mark.x + mark.w : mark.x;
13329
+ const dir2 = mark.negative ? -1 : 1;
13330
+ const side = (at, outward) => [
13331
+ at + (outward ? dir2 : -dir2) * GAP,
13332
+ (outward ? dir2 : -dir2) > 0 ? "start" : "end"
13333
+ ];
13334
+ const [x, anchor] = position === "ctr" ? [cx, "middle"] : position === "inEnd" ? side(end, false) : position === "inBase" ? side(base, true) : side(end, true);
13335
+ draw(m, label, x, cy, anchor, out);
13336
+ continue;
13337
+ }
13338
+ const top = mark.negative ? mark.y + mark.h : mark.y;
13339
+ const bottom = mark.negative ? mark.y : mark.y + mark.h;
13340
+ const dir = mark.negative ? 1 : -1;
13341
+ const y = position === "ctr" ? cy : position === "inEnd" ? top - dir * (GAP + m.h / 2) : position === "inBase" ? bottom + dir * (GAP + m.h / 2) : top + dir * (GAP + m.h / 2);
13342
+ draw(m, label, cx, y, "middle", out);
13343
+ }
13344
+ }
13345
+ function pointLabels(model, marks, out) {
13346
+ for (const mark of marks) {
13347
+ const label = mark.series.labels?.[mark.index];
13348
+ if (!label) continue;
13349
+ const m = measure(model, label);
13350
+ const reach = mark.radius + GAP;
13351
+ switch (model.type === "area" ? "ctr" : label.position ?? "r") {
13352
+ case "ctr":
13353
+ draw(m, label, mark.x, mark.y, "middle", out);
13354
+ break;
13355
+ case "t":
13356
+ draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
13357
+ break;
13358
+ case "b":
13359
+ draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
13360
+ break;
13361
+ case "l":
13362
+ draw(m, label, mark.x - reach, mark.y, "end", out);
13363
+ break;
13364
+ default:
13365
+ draw(m, label, mark.x + reach, mark.y, "start", out);
13366
+ }
13367
+ }
13368
+ }
13369
+ function sliceLabels(model, marks, out) {
13370
+ for (const mark of marks) {
13371
+ const label = mark.series.labels?.[mark.index];
13372
+ if (!label) continue;
13373
+ const m = measure(model, label);
13374
+ const mid = (mark.start + mark.end) / 2;
13375
+ const ux = Math.sin(mid);
13376
+ const uy = -Math.cos(mid);
13377
+ const place2 = (radius) => [
13378
+ mark.cx + radius * ux,
13379
+ mark.cy + radius * uy
13380
+ ];
13381
+ const position = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
13382
+ let x;
13383
+ let y;
13384
+ if (position === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
13385
+ else if (position === "inEnd") {
13386
+ const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
13387
+ [x, y] = place2(Math.max(0, mark.outer - GAP - extent));
13388
+ } else if (position === "outEnd") {
13389
+ const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
13390
+ [x, y] = place2(mark.outer + GAP + extent);
13391
+ } else {
13392
+ const placed2 = placeBestFitLabel(
13393
+ {
13394
+ cx: mark.cx,
13395
+ cy: mark.cy,
13396
+ outerR: mark.outer,
13397
+ startAngle: mark.start - Math.PI / 2,
13398
+ endAngle: mark.end - Math.PI / 2
13399
+ },
13400
+ m.w,
13401
+ m.h
13402
+ );
13403
+ x = placed2.x;
13404
+ y = placed2.y;
13405
+ }
13406
+ draw(m, label, x, y, "middle", out);
13407
+ }
13408
+ }
13409
+ function hasOutsideLabels(model) {
13410
+ return model.series.some(
13411
+ (s) => s.labels?.some(
13412
+ (l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
13413
+ )
13414
+ );
13415
+ }
13416
+
13417
+ // chart/render/chart-svg-bars.ts
13418
+ function barLayout(model, frame2) {
13419
+ const count = Math.max(1, model.series.length);
13420
+ const geometry = clusteredBarGeometry(frame2.bandSize, count, chartBarSpacing(model));
13421
+ const barSize = geometry.singleBarWidth;
13422
+ const offset = (si) => model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
13423
+ return { barSize, offset };
13424
+ }
13425
+ function bars(model, frame2, out, values) {
13426
+ const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
13427
+ const { barSize, offset: barOffset } = barLayout(model, frame2);
13428
+ const base = frame2.value(0);
13429
+ const pos = new Array(model.categories.length).fill(0);
13430
+ const neg = new Array(model.categories.length).fill(0);
13431
+ const marks = [];
13432
+ model.series.forEach((s, si) => {
13433
+ values[si]?.forEach((v, i) => {
13434
+ if (v === null || i >= model.categories.length) return;
13435
+ let from = 0;
13436
+ let to = v;
13437
+ if (stacked) {
13438
+ const acc = v >= 0 ? pos : neg;
13439
+ from = acc[i] ?? 0;
13440
+ to = from + v;
13441
+ acc[i] = to;
13442
+ }
13443
+ const a = stacked ? frame2.value(from) : base;
13444
+ const b = frame2.value(to);
13445
+ const offset = barOffset(si);
13446
+ const center = frame2.band(i);
13447
+ const width = model.horizontal ? Math.abs(b - a) : barSize;
13448
+ const height = model.horizontal ? barSize : Math.abs(b - a);
13449
+ let color = s.pointColors?.[i] ?? s.color;
13450
+ const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
13451
+ if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
13452
+ const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
13453
+ if (baseId) {
13454
+ const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
13455
+ const def = buildChartGradientDef(id, gradient, {
13456
+ width: Number(n(width)),
13457
+ height: Number(n(height)),
13458
+ shape: "rect"
13459
+ });
13460
+ out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
13461
+ color = `url(#${id})`;
13462
+ }
13463
+ }
13464
+ out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
13465
+ const box = model.horizontal ? { x: Math.min(a, b), y: center + offset, w: Math.abs(b - a), h: barSize } : { x: center + offset, y: Math.min(a, b), w: barSize, h: Math.abs(b - a) };
13466
+ out.push(rect2(box.x, box.y, box.w, box.h, color, s.shadowFilter));
13467
+ out.push("</g>");
13468
+ marks.push({ series: s, index: i, ...box, negative: v < 0 });
13469
+ });
13470
+ });
13471
+ barLabels(model, marks, out);
13472
+ }
13473
+
13474
+ // chart/render/chart-svg-analysis.ts
13475
+ var DASHES = {
13476
+ dot: [1, 3],
13477
+ dash: [4, 3],
13478
+ lgDash: [8, 3],
13479
+ dashDot: [4, 3, 1, 3],
12540
13480
  lgDashDot: [8, 3, 1, 3],
12541
13481
  lgDashDotDot: [8, 3, 1, 3, 1, 3],
12542
13482
  sysDash: [3, 1],
@@ -12617,6 +13557,60 @@ function scatterAnalysis(model, px, py, out) {
12617
13557
  });
12618
13558
  }
12619
13559
 
13560
+ // chart/render/chart-svg-markers.ts
13561
+ function chartMarkerRadius(series, index, defaultRadius = 3) {
13562
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
13563
+ if (marker.symbol === "none") return 0;
13564
+ const radius = markerRadius(marker.size, defaultRadius);
13565
+ return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
13566
+ }
13567
+ function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
13568
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
13569
+ const primitive = buildMarkerPrimitive({
13570
+ ...marker,
13571
+ symbol: marker.symbol,
13572
+ size: marker.size,
13573
+ cx,
13574
+ cy,
13575
+ fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
13576
+ defaultRadius
13577
+ });
13578
+ if (!primitive) return "";
13579
+ let geometry;
13580
+ switch (primitive.kind) {
13581
+ case "circle":
13582
+ geometry = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
13583
+ break;
13584
+ case "rect":
13585
+ geometry = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
13586
+ break;
13587
+ case "path":
13588
+ geometry = `d="${esc(primitive.d)}"`;
13589
+ break;
13590
+ case "polygon":
13591
+ geometry = `points="${esc(primitive.points)}"`;
13592
+ break;
13593
+ }
13594
+ const outline = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
13595
+ const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
13596
+ return `<${primitive.kind} ${geometry} fill="${esc(primitive.fill)}"${outline}${filter}/>`;
13597
+ }
13598
+
13599
+ // chart/line-dash.ts
13600
+ function chartLineDashArray(style, width) {
13601
+ if (!style || style === "solid") {
13602
+ return void 0;
13603
+ }
13604
+ const unit = Math.max(width, 1);
13605
+ if (style === "dot" || style === "sysDot") {
13606
+ return `${unit} ${unit * 2}`;
13607
+ }
13608
+ if (style === "lgDash") {
13609
+ return `${unit * 6} ${unit * 3}`;
13610
+ }
13611
+ return `${unit * 3} ${unit * 2}`;
13612
+ }
13613
+
12620
13614
  // chart/render/chart-scale.ts
12621
13615
  var clean = (n2) => Number(n2.toPrecision(12));
12622
13616
  function* units(raw) {
@@ -12627,14 +13621,14 @@ function* units(raw) {
12627
13621
  exp++;
12628
13622
  }
12629
13623
  }
12630
- function niceScale(dataMin, dataMax, options = {}) {
12631
- const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
13624
+ function niceScale(dataMin, dataMax, options2 = {}) {
13625
+ const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
12632
13626
  let lo = Number.isFinite(dataMin) ? dataMin : 0;
12633
13627
  let hi = Number.isFinite(dataMax) ? dataMax : 0;
12634
13628
  if (lo > hi) [lo, hi] = [hi, lo];
12635
13629
  if (lo === hi) {
12636
13630
  if (lo === 0) hi = 1;
12637
- else if (options.noZero) {
13631
+ else if (options2.noZero) {
12638
13632
  const pad = Math.abs(lo) * 0.1 || 1;
12639
13633
  lo -= pad;
12640
13634
  hi += pad;
@@ -12643,7 +13637,7 @@ function niceScale(dataMin, dataMax, options = {}) {
12643
13637
  }
12644
13638
  let fixedLo = false;
12645
13639
  let fixedHi = false;
12646
- if (!options.noZero) {
13640
+ if (!options2.noZero) {
12647
13641
  if (lo >= 0 && hi - lo >= hi / 6) {
12648
13642
  lo = 0;
12649
13643
  fixedLo = true;
@@ -12683,144 +13677,231 @@ function formatAxisValue(value, percent = false) {
12683
13677
  return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
12684
13678
  }
12685
13679
 
12686
- // chart/render/theme-palette.ts
12687
- var THEME_SLOTS = [
12688
- "lt1",
12689
- "dk1",
12690
- "lt2",
12691
- "dk2",
12692
- "accent1",
12693
- "accent2",
12694
- "accent3",
12695
- "accent4",
12696
- "accent5",
12697
- "accent6",
12698
- "hlink",
12699
- "folHlink"
12700
- ];
12701
- var DEFAULT_THEME_COLORS = [
12702
- "FFFFFF",
12703
- "000000",
12704
- "E7E6E6",
12705
- "44546A",
12706
- "4472C4",
12707
- "ED7D31",
12708
- "A5A5A5",
12709
- "FFC000",
12710
- "5B9BD5",
12711
- "70AD47",
12712
- "0563C1",
12713
- "954F72"
12714
- ];
12715
- function themeColor(theme, index) {
12716
- const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
12717
- return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
13680
+ // chart/render/chart-svg-axes.ts
13681
+ function axisTickText(value, axis, percent = false) {
13682
+ return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
13683
+ }
13684
+ function axisLine(model, axis, part, x1, y1, x2, y2) {
13685
+ if (axis?.source.deleted) return "";
13686
+ return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
13687
+ }
13688
+ function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
13689
+ const color = paint2?.color ?? fallback.color;
13690
+ const width = paint2?.width ?? fallback.width;
13691
+ if (color === "none" || width === 0) return "";
13692
+ const dash = chartLineDashArray(paint2?.dash, width);
13693
+ return line2(x1, y1, x2, y2, esc(color), width).replace(
13694
+ "/>",
13695
+ dash ? ` stroke-dasharray="${dash}"/>` : "/>"
13696
+ );
13697
+ }
13698
+ function axisGridlines(model, axis, ticks, position, plot, vertical) {
13699
+ const draw2 = (values, paint2, minor2) => {
13700
+ const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
13701
+ return values.map((value) => {
13702
+ const p = position(value);
13703
+ return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
13704
+ }).join("");
13705
+ };
13706
+ const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
13707
+ const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
13708
+ return major + minor;
12718
13709
  }
12719
13710
 
12720
- // chart/render/chart-colors.ts
12721
- function chartColorScheme(theme) {
12722
- const slots = Object.fromEntries(
12723
- THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
12724
- );
13711
+ // chart/axis-range.ts
13712
+ function computeLogValueRange(series, logBase) {
13713
+ const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
13714
+ if (allValues.length === 0) {
13715
+ return { min: 1, max: logBase, span: 1, logScale: true, logBase };
13716
+ }
13717
+ const dataMin = Math.min(...allValues);
13718
+ const dataMax = Math.max(...allValues);
13719
+ const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
13720
+ const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
13721
+ const min = logBase ** logMin;
13722
+ const max = logBase ** Math.max(logMax, logMin + 1);
12725
13723
  return {
12726
- ...slots,
12727
- bg1: slots.lt1,
12728
- tx1: slots.dk1,
12729
- bg2: slots.lt2,
12730
- tx2: slots.dk2
13724
+ min,
13725
+ max,
13726
+ span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
13727
+ logScale: true,
13728
+ logBase
13729
+ };
13730
+ }
13731
+ function withAxisBounds(automatic, axis, logBase) {
13732
+ const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
13733
+ const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
13734
+ const min = validMin ?? automatic.min;
13735
+ let max = validMax ?? automatic.max;
13736
+ const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
13737
+ if (max <= min) {
13738
+ max = logBase ? min * logBase : min + 1;
13739
+ }
13740
+ const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
13741
+ return {
13742
+ min,
13743
+ max,
13744
+ span: Math.max(span, Number.EPSILON),
13745
+ ...majorUnit !== void 0 ? { majorUnit } : {},
13746
+ ...logBase ? { logScale: true, logBase } : {},
13747
+ ...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
12731
13748
  };
12732
13749
  }
12733
- function autoSeriesColor(theme, index) {
12734
- const i = Math.max(0, Math.floor(index));
12735
- return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
13750
+
13751
+ // chart/axis-ticks.ts
13752
+ var LOG_EXPONENT_TOLERANCE = 1e-12;
13753
+ function generateLogTicks(range) {
13754
+ if (!range.logScale || !range.logBase) {
13755
+ return [];
13756
+ }
13757
+ const base = range.logBase;
13758
+ const logMin = Math.log(range.min) / Math.log(base);
13759
+ const logMax = Math.log(range.max) / Math.log(base);
13760
+ const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
13761
+ const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
13762
+ if (lastExponent < firstExponent) {
13763
+ return range.min === range.max ? [range.min] : [range.min, range.max];
13764
+ }
13765
+ return Array.from(
13766
+ { length: lastExponent - firstExponent + 1 },
13767
+ (_unused, index) => base ** (firstExponent + index)
13768
+ );
13769
+ }
13770
+ function generateIntervalTicks(range, unit) {
13771
+ if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
13772
+ return [];
13773
+ }
13774
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
13775
+ const first3 = Math.ceil((range.min - tolerance) / unit);
13776
+ const last = Math.floor((range.max + tolerance) / unit);
13777
+ const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
13778
+ return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
13779
+ }
13780
+ function generateAxisTicks(range, axis, defaultIntervals) {
13781
+ if (range.logScale && range.logBase) {
13782
+ return generateLogTicks(range);
13783
+ }
13784
+ const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
13785
+ if (explicit.length > 0) {
13786
+ return explicit;
13787
+ }
13788
+ const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
13789
+ if (automatic.length > 0) {
13790
+ return automatic;
13791
+ }
13792
+ return Array.from(
13793
+ { length: defaultIntervals + 1 },
13794
+ (_, index) => range.min + range.span / defaultIntervals * index
13795
+ );
12736
13796
  }
12737
-
12738
- // chart/text-inheritance.ts
12739
- var TEXT_KEYS = [
12740
- "fontSize",
12741
- "bold",
12742
- "italic",
12743
- "underline",
12744
- "typeface",
12745
- "textColor",
12746
- "fontRef"
12747
- ];
12748
- var TEXT_PARTS = [
12749
- "title",
12750
- "axisTitle",
12751
- "categoryAxis",
12752
- "valueAxis",
12753
- "legend",
12754
- "dataLabel"
12755
- ];
12756
- function inheritChartText(part, entry, builtIn, root) {
12757
- if (!root || !TEXT_PARTS.includes(part)) return entry;
12758
- const out = { ...entry };
12759
- for (const key of TEXT_KEYS) {
12760
- delete out[key];
12761
- const value = root[key] ?? builtIn?.[key];
12762
- if (value !== void 0) Object.assign(out, { [key]: value });
13797
+ function generateMinorAxisTicks(range, axis) {
13798
+ const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
13799
+ if (minor.length === 0) {
13800
+ return [];
12763
13801
  }
12764
- if (part === "title" && root.fontSize !== void 0) out.fontSize = root.fontSize * 1.2;
12765
- if (root.textEffectsXml !== void 0) out.textEffectsXml = root.textEffectsXml;
12766
- return out;
13802
+ const majorUnit = axis?.majorUnit;
13803
+ if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
13804
+ return minor;
13805
+ }
13806
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
13807
+ return minor.filter(
13808
+ (value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
13809
+ );
12767
13810
  }
12768
13811
 
12769
- // chart/render/chart-appearance.ts
12770
- var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
12771
- function typeface(entry, theme) {
12772
- const name = entry.typeface;
12773
- if (name?.startsWith("+mj-")) return theme.majorFont;
12774
- if (name?.startsWith("+mn-")) return theme.minorFont;
12775
- return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
13812
+ // chart/render/chart-view-axes.ts
13813
+ function chartAxisRatio(value, scale, axis) {
13814
+ const range = axis?.range;
13815
+ const ratio = range?.logScale ? Math.log(Math.max(value, range.min) / range.min) / Math.log(range.max / range.min) : (value - scale.min) / (scale.max - scale.min || 1);
13816
+ return range?.reverseOrder ? 1 - ratio : ratio;
12776
13817
  }
12777
- function chartAppearance(chart, theme) {
12778
- const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
12779
- const entries = {};
12780
- for (const part of CHART_STYLE_PARTS) {
12781
- const base = chart.styleDefinition?.entries[part];
12782
- const direct = chart.formatting?.entries[part];
12783
- if (!defaults[part] && !base && !direct) continue;
12784
- const entry = {
12785
- ...inheritChartText(
12786
- part,
12787
- { ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
12788
- defaults[part],
12789
- chart.formatting?.textDefaults
12790
- ),
12791
- ...direct,
12792
- sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
12793
- };
12794
- if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
12795
- entries[part] = entry;
12796
- }
12797
- const scheme = chartColorScheme(theme);
12798
- const resolve = (color) => resolveDrawingColor(
12799
- color,
12800
- { scheme: (name) => scheme[name] },
12801
- { hslRounding: "halfDown", transformOrder: "document" }
13818
+ function chartAxisLabels(axis) {
13819
+ return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
13820
+ }
13821
+ function options(axis) {
13822
+ return {
13823
+ ...axis.scaling,
13824
+ ...axis.scaling.logBase === void 0 ? {} : { logScale: true },
13825
+ ...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
13826
+ ...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
13827
+ };
13828
+ }
13829
+ function applyChartAxes(model, chart, color) {
13830
+ if (!chart.axes?.length) return;
13831
+ const axes = chart.axes;
13832
+ const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
13833
+ const candidates = linked.length ? linked : axes;
13834
+ const xy = model.type === "scatter" || model.type === "bubble";
13835
+ const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
13836
+ const category = candidates.find(
13837
+ (axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
12802
13838
  );
12803
- const out = resolveChartStyleDefinition(
12804
- { entries},
12805
- (color) => drawingColorCss(resolve(color))
12806
- ) ?? {};
12807
- for (const part of CHART_STYLE_PARTS) {
12808
- const entry = entries[part];
12809
- if (!entry) continue;
12810
- const family = typeface(entry, theme);
12811
- const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
12812
- scheme: (name) => scheme[name]
12813
- });
12814
- if (shadow) (out[part] ??= {}).textShadow = shadow;
12815
- if (family) (out[part] ??= {}).typeface = family;
12816
- if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
12817
- if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
12818
- if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
12819
- if (entry.fill?.kind === "gradient") {
12820
- (out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
13839
+ const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
13840
+ const paint2 = (shape) => {
13841
+ const ln = shape?.line;
13842
+ const fill = ln?.fill;
13843
+ const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
13844
+ return {
13845
+ ...resolved === void 0 ? {} : { color: resolved },
13846
+ ...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
13847
+ ...ln?.dash === void 0 ? {} : { dash: ln.dash }
13848
+ };
13849
+ };
13850
+ const bind = (axis, scale, values) => {
13851
+ const opts = options(axis);
13852
+ const automatic = opts.logScale ? computeLogValueRange(
13853
+ [{ values: values ?? [] }],
13854
+ opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
13855
+ ) : {
13856
+ min: scale?.min ?? 0,
13857
+ max: scale?.max ?? 1,
13858
+ span: (scale?.max ?? 1) - (scale?.min ?? 0),
13859
+ ...scale ? { majorUnit: scale.majorUnit } : {}
13860
+ };
13861
+ const logBase = automatic.logBase;
13862
+ const range = withAxisBounds(automatic, opts, logBase);
13863
+ if (scale) {
13864
+ scale.min = range.min;
13865
+ scale.max = range.max;
13866
+ scale.ticks = generateAxisTicks(range, opts, 5);
12821
13867
  }
12822
- }
12823
- return out;
13868
+ return {
13869
+ source: axis,
13870
+ range,
13871
+ minorTicks: generateMinorAxisTicks(range, opts),
13872
+ line: paint2(axis.spPr),
13873
+ majorGrid: paint2(axis.majorGridlinesSpPr),
13874
+ minorGrid: paint2(axis.minorGridlinesSpPr)
13875
+ };
13876
+ };
13877
+ const out = {};
13878
+ if (value)
13879
+ out.value = bind(
13880
+ value,
13881
+ model.valueAxis,
13882
+ [
13883
+ ...model.series,
13884
+ ...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
13885
+ ].flatMap((s) => s.values)
13886
+ );
13887
+ if (category)
13888
+ out.category = bind(
13889
+ category,
13890
+ model.xAxis ?? {
13891
+ min: 0,
13892
+ max: Math.max(1, model.categories.length - 1),
13893
+ majorUnit: 1,
13894
+ ticks: []
13895
+ },
13896
+ model.series.flatMap((s) => s.xValues ?? [])
13897
+ );
13898
+ if (secondary)
13899
+ out.secondary = bind(
13900
+ secondary,
13901
+ model.secondaryAxis,
13902
+ model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
13903
+ );
13904
+ model.axes = out;
12824
13905
  }
12825
13906
 
12826
13907
  // chart/render/chart-view-analysis.ts
@@ -12872,15 +13953,15 @@ function seriesName(series, index, evaluateRef) {
12872
13953
  const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
12873
13954
  return fromRef || series.name || `Series${index + 1}`;
12874
13955
  }
12875
- function seriesContext(chart, theme, options) {
13956
+ function seriesContext(chart, theme, options2) {
12876
13957
  const scheme = chartColorScheme(theme);
12877
13958
  const resolver = { scheme: (name) => scheme[name] };
12878
13959
  return {
12879
13960
  theme,
12880
13961
  scheme,
12881
13962
  palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
12882
- evaluateRef: options.evaluateRef ?? (() => []),
12883
- seriesColor: options.seriesColor,
13963
+ evaluateRef: options2.evaluateRef ?? (() => []),
13964
+ seriesColor: options2.seriesColor,
12884
13965
  drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
12885
13966
  gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
12886
13967
  fill,
@@ -12906,7 +13987,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
12906
13987
  })
12907
13988
  );
12908
13989
  if (Object.keys(points).length) view.pointGradients = points;
12909
- Object.assign(view, analysisView(s, color, ctx.drawingColor));
13990
+ Object.assign(
13991
+ view,
13992
+ analysisView(s, color, ctx.drawingColor),
13993
+ seriesMarkerViews(s, ctx.drawingColor)
13994
+ );
12910
13995
  return view;
12911
13996
  }
12912
13997
 
@@ -13079,12 +14164,70 @@ function chartTitleText(chart, theme) {
13079
14164
  };
13080
14165
  }
13081
14166
 
14167
+ // chart/render/chart-view-labels.ts
14168
+ function labelsOf(source, view, categories, numberFormat) {
14169
+ const { chart, series, points } = source;
14170
+ if ((series?.deleted ?? chart?.deleted) === true) return void 0;
14171
+ const percentBase = view.values.reduce(
14172
+ (sum, v) => sum + (v === null ? 0 : Math.abs(v)),
14173
+ 0
14174
+ );
14175
+ const out = [];
14176
+ let any = false;
14177
+ view.values.forEach((value, i) => {
14178
+ const point = points?.[i];
14179
+ if (value === null || point?.deleted === true) return;
14180
+ const position = point?.position ?? series?.position ?? chart?.position;
14181
+ const x = view.xValues?.[i];
14182
+ const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
14183
+ let built;
14184
+ if (point?.text !== void 0) built = { text: point.text };
14185
+ else {
14186
+ const flags = resolveDataLabelFlags({
14187
+ ...point ? { point } : {},
14188
+ ...series ? { series } : {},
14189
+ ...chart ? { chart } : {}
14190
+ });
14191
+ built = composeDataLabelText({
14192
+ flags,
14193
+ seriesName: view.name,
14194
+ category,
14195
+ value,
14196
+ numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat,
14197
+ percentBase,
14198
+ bubbleSize: view.sizes?.[i] ?? void 0,
14199
+ formatValue: (v) => formatAxisValue(v),
14200
+ formatBubbleSize: (size) => formatAxisValue(size)
14201
+ });
14202
+ }
14203
+ if (!built) return;
14204
+ any = true;
14205
+ out[i] = {
14206
+ text: built.text,
14207
+ ...position ? { position } : {},
14208
+ ...built.color ? { color: built.color } : {}
14209
+ };
14210
+ });
14211
+ return any ? out : void 0;
14212
+ }
14213
+ function applyDataLabels(model, sources, extra) {
14214
+ const apply = (source, view) => {
14215
+ if (!source?.dataLabels) return;
14216
+ const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
14217
+ if (labels) view.labels = labels;
14218
+ };
14219
+ model.series.forEach((view, i) => apply(sources[i], view));
14220
+ model.extraGroups?.forEach(
14221
+ (group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
14222
+ );
14223
+ }
14224
+
13082
14225
  // chart/render/chart-view-ex.ts
13083
14226
  function groupsAxis(groups, categories) {
13084
14227
  let min = Infinity;
13085
14228
  let max = -Infinity;
13086
- for (const group of groups) {
13087
- const extent = valueExtent(group.type, group.grouping, group.series, categories);
14229
+ for (const group2 of groups) {
14230
+ const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
13088
14231
  min = Math.min(min, extent.min);
13089
14232
  max = Math.max(max, extent.max);
13090
14233
  }
@@ -13093,17 +14236,17 @@ function groupsAxis(groups, categories) {
13093
14236
  function chartExtraView(chart, model, ctx, total, categoriesOf) {
13094
14237
  let index = chart.series.length;
13095
14238
  const groups = [];
13096
- for (const group of chart.extraGroups ?? []) {
13097
- const series = group.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
14239
+ for (const group2 of chart.extraGroups ?? []) {
14240
+ const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
13098
14241
  const view = {
13099
- type: group.chartType,
13100
- grouping: group.grouping ?? (group.chartType === "column" ? "clustered" : "standard"),
14242
+ type: group2.chartType,
14243
+ grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
13101
14244
  series,
13102
- secondary: group.secondary
14245
+ secondary: group2.secondary
13103
14246
  };
13104
- if (group.chartType === "stock") view.stock = stockView(group.stock, ctx);
13105
- if (group.barGapWidth !== void 0) view.barGapWidth = group.barGapWidth;
13106
- if (group.barOverlap !== void 0) view.barOverlap = group.barOverlap;
14247
+ if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
14248
+ if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
14249
+ if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
13107
14250
  groups.push(view);
13108
14251
  }
13109
14252
  if (!groups.length) return;
@@ -13120,8 +14263,8 @@ function chartExtraAxes(model) {
13120
14263
  const own2 = valueExtent(model.type, model.grouping, model.series, count);
13121
14264
  let min = own2.min;
13122
14265
  let max = own2.max;
13123
- for (const group of shared) {
13124
- const extent = valueExtent(group.type, group.grouping, group.series, count);
14266
+ for (const group2 of shared) {
14267
+ const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
13125
14268
  min = Math.min(min, extent.min);
13126
14269
  max = Math.max(max, extent.max);
13127
14270
  }
@@ -13148,11 +14291,11 @@ function histogramView(chart, model) {
13148
14291
  const first3 = model.series[0];
13149
14292
  if (!first3) return;
13150
14293
  const raw = first3.values.map((v) => v ?? Number.NaN);
13151
- const options = chart.histogram ?? {};
13152
- const bins = options.aggregateByCategory ? aggregateByCategory(
14294
+ const options2 = chart.histogram ?? {};
14295
+ const bins = options2.aggregateByCategory ? aggregateByCategory(
13153
14296
  first3.values.map((v) => v ?? 0),
13154
14297
  model.categories
13155
- ) : computeHistogramBins(raw, options, formatAxisValue);
14298
+ ) : computeHistogramBins(raw, options2, formatAxisValue);
13156
14299
  model.categories = bins.map((bin) => bin.label);
13157
14300
  first3.values = bins.map((bin) => bin.value);
13158
14301
  model.barGapWidth = 0;
@@ -13176,11 +14319,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
13176
14319
  "treemap",
13177
14320
  "sunburst"
13178
14321
  ]);
13179
- function chartSummaryView(chart, theme, options = {}) {
14322
+ function chartSummaryView(chart, theme, options2 = {}) {
13180
14323
  const type = chart.chartType;
13181
14324
  const radial = type === "pie" || type === "doughnut";
13182
14325
  const byPoint = radial || type === "treemap" || type === "sunburst";
13183
- const ctx = seriesContext(chart, theme, options);
14326
+ const ctx = seriesContext(chart, theme, options2);
13184
14327
  const { palette, scheme, drawingColor } = ctx;
13185
14328
  const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
13186
14329
  const rawCategories = [];
@@ -13264,128 +14407,23 @@ function chartSummaryView(chart, theme, options = {}) {
13264
14407
  chartExtraView(chart, model, ctx, total, collect);
13265
14408
  if (type === "waterfall") waterfallView(chart, model, ctx);
13266
14409
  else if (!byPoint) model.valueAxis = valueAxis(model);
14410
+ applyDataLabels(model, chart.series, extra);
13267
14411
  chartExtraAxes(model);
14412
+ applyChartAxes(model, chart, ctx.drawingColor);
13268
14413
  return model;
13269
14414
  }
13270
14415
 
13271
- // text/css-font-family.ts
13272
- var FALLBACKS = {
13273
- calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
13274
- "calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
13275
- cambria: '"Cambria", "Caladea", Georgia, serif',
13276
- arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
13277
- "times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
13278
- "courier new": '"Courier New", "Liberation Mono", monospace',
13279
- aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
13280
- };
13281
- function cssFontFamily(name) {
13282
- const known = FALLBACKS[name.toLowerCase()];
13283
- if (known) return known;
13284
- const quoted = `"${name.replace(/["\\]/g, "")}"`;
13285
- return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
13286
- }
13287
-
13288
- // chart/render/chart-svg-appearance.ts
13289
- var nextPaintId = 0;
13290
- function chartGradientPaint(model, width = 1024, height = 768) {
13291
- const prefix2 = `xlsx-chart-${++nextPaintId}`;
13292
- const appearance = { ...model.appearance };
13293
- const defs = [];
13294
- const shadowPaint = (shadow, suffix) => {
13295
- const id = `${prefix2}-${suffix}`;
13296
- const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
13297
- defs.push(
13298
- `<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
13299
- );
13300
- return `url(#${id})`;
13301
- };
13302
- for (const [part, entry] of Object.entries(appearance)) {
13303
- if (entry?.textShadow)
13304
- appearance[part] = {
13305
- ...entry,
13306
- textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
13307
- };
13308
- }
13309
- const paint2 = (gradient, suffix, bounds) => {
13310
- const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
13311
- defs.push(chartGradientMarkup(def));
13312
- return `url(#${def.id})`;
13313
- };
13314
- for (const part of ["chartArea", "plotArea"]) {
13315
- const entry = appearance[part];
13316
- if (!entry?.gradient) continue;
13317
- if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
13318
- appearance[part] = {
13319
- ...entry,
13320
- fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
13321
- };
13322
- }
13323
- const series = model.series.map((source, index) => {
13324
- const view = { ...source };
13325
- if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
13326
- const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
13327
- if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
13328
- if (source.pointGradients) {
13329
- view.pointColors = [...source.pointColors ?? []];
13330
- for (const [key, gradient] of Object.entries(source.pointGradients))
13331
- view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
13332
- }
13333
- return view;
13334
- });
13335
- return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
13336
- }
13337
- function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
13338
- const entry = model.appearance?.[part];
13339
- return {
13340
- size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
13341
- ...entry?.color === void 0 ? {} : { fill: entry.color },
13342
- ...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
13343
- ...entry?.italic === void 0 ? {} : { italic: entry.italic },
13344
- ...entry?.underline === void 0 ? {} : { underline: entry.underline },
13345
- ...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
13346
- ...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
13347
- };
13348
- }
13349
- function chartStroke(model, part) {
13350
- const entry = model.appearance?.[part];
13351
- return {
13352
- color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
13353
- width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
13354
- };
13355
- }
13356
- function chartAreaRect(model, part, area) {
13357
- if (area.w <= 0 || area.h <= 0) return "";
13358
- const entry = model.appearance?.[part];
13359
- let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
13360
- let defs = "";
13361
- if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
13362
- const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
13363
- width: area.w,
13364
- height: area.h,
13365
- shape: "rect"
13366
- });
13367
- defs = `<defs>${chartGradientMarkup(def)}</defs>`;
13368
- fill = `url(#${def.id})`;
13369
- }
13370
- const stroke = entry?.lineColor ?? "none";
13371
- if (fill === "none" && stroke === "none") return "";
13372
- const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
13373
- return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
13374
- }
13375
-
13376
14416
  // chart/render/chart-svg-cartesian.ts
13377
14417
  function cartesianAxes(model, area, out) {
13378
14418
  const scale = model.valueAxis;
13379
14419
  if (!scale) return void 0;
13380
- const labels = scale.ticks.map((t) => formatAxisValue(t, scale.percent));
14420
+ const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
13381
14421
  const valueAttrs = chartTextAttributes(model, "valueAxis");
13382
14422
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
13383
14423
  const valueSize = valueAttrs.size ?? 10;
13384
14424
  const categorySize = categoryAttrs.size ?? 10;
13385
- const grid = chartStroke(model, "gridlineMajor");
13386
- const axis = chartStroke(model, "categoryAxis");
13387
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
13388
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
14425
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
14426
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
13389
14427
  const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
13390
14428
  const horizontal = model.horizontal;
13391
14429
  const cats = Math.max(1, model.categories.length);
@@ -13394,7 +14432,7 @@ function cartesianAxes(model, area, out) {
13394
14432
  Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
13395
14433
  );
13396
14434
  const second = horizontal ? void 0 : model.secondaryAxis;
13397
- const secondLabels = second?.ticks.map((t) => formatAxisValue(t, second.percent)) ?? [];
14435
+ const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
13398
14436
  const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
13399
14437
  const plot = horizontal ? {
13400
14438
  x: area.x + catW,
@@ -13407,29 +14445,47 @@ function cartesianAxes(model, area, out) {
13407
14445
  w: Math.max(1, area.w - labelW - 4 - secondW),
13408
14446
  h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
13409
14447
  };
13410
- const span = scale.max - scale.min || 1;
13411
- const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
14448
+ const value = horizontal ? (v) => plot.x + chartAxisRatio(v, scale, model.axes?.value) * plot.w : (v) => plot.y + plot.h - chartAxisRatio(v, scale, model.axes?.value) * plot.h;
13412
14449
  const bandSize = (horizontal ? plot.h : plot.w) / cats;
13413
- const band = horizontal ? (i) => plot.y + plot.h - bandSize * (i + 0.5) : (i) => plot.x + bandSize * (i + 0.5);
14450
+ const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
14451
+ const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
13414
14452
  out.push(chartAreaRect(model, "plotArea", plot));
14453
+ out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
14454
+ if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
14455
+ out.push(
14456
+ axisGridlines(
14457
+ model,
14458
+ model.axes.category,
14459
+ model.categories.map((_, i) => i),
14460
+ band,
14461
+ plot,
14462
+ !horizontal
14463
+ )
14464
+ );
13415
14465
  scale.ticks.forEach((t, i) => {
13416
14466
  const p = value(t);
13417
14467
  const label = labels[i] ?? "";
13418
14468
  if (horizontal) {
13419
- out.push(line2(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
13420
14469
  if (valueLabels)
13421
14470
  out.push(
13422
14471
  text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
13423
14472
  );
13424
14473
  } else {
13425
- out.push(line2(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
13426
14474
  if (valueLabels)
13427
14475
  out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
13428
14476
  }
13429
14477
  });
13430
- const zero = value(Math.min(Math.max(0, scale.min), scale.max));
13431
- if (horizontal) out.push(line2(zero, plot.y, zero, plot.y + plot.h, axis.color, axis.width));
13432
- else out.push(line2(plot.x, zero, plot.x + plot.w, zero, axis.color, axis.width));
14478
+ const source = model.axes?.value?.source;
14479
+ const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
14480
+ const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
14481
+ if (horizontal)
14482
+ out.push(
14483
+ axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
14484
+ );
14485
+ else
14486
+ out.push(
14487
+ axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
14488
+ );
13433
14489
  const step = Math.max(
13434
14490
  1,
13435
14491
  Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
@@ -13454,20 +14510,23 @@ function cartesianAxes(model, area, out) {
13454
14510
  });
13455
14511
  const frame2 = { plot, value, band, bandSize };
13456
14512
  if (second) {
13457
- const secondSpan = second.max - second.min || 1;
13458
- frame2.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
13459
- const secondAxis = chartStroke(model, "valueAxis");
14513
+ frame2.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
13460
14514
  out.push(
13461
- line2(
14515
+ axisLine(
14516
+ model,
14517
+ model.axes?.secondary,
14518
+ "valueAxis",
13462
14519
  plot.x + plot.w,
13463
14520
  plot.y,
13464
14521
  plot.x + plot.w,
13465
- plot.y + plot.h,
13466
- secondAxis.color,
13467
- secondAxis.width
14522
+ plot.y + plot.h
13468
14523
  )
13469
14524
  );
13470
- if (valueLabels)
14525
+ if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
14526
+ out.push(
14527
+ axisGridlines(model, model.axes.secondary, second.ticks, frame2.secondary, plot, false)
14528
+ );
14529
+ if (chartAxisLabels(model.axes?.secondary))
13471
14530
  second.ticks.forEach(
13472
14531
  (t, i) => out.push(
13473
14532
  text(plot.x + plot.w + 4, frame2.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
@@ -13491,6 +14550,7 @@ function linesAndAreas(model, frame2, out) {
13491
14550
  const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
13492
14551
  const acc = new Array(model.categories.length).fill(0);
13493
14552
  const area = model.type === "area";
14553
+ const marks = [];
13494
14554
  const layers = [];
13495
14555
  model.series.forEach((s, si) => {
13496
14556
  const points = [];
@@ -13505,16 +14565,24 @@ function linesAndAreas(model, frame2, out) {
13505
14565
  const top = below2 + (v ?? 0);
13506
14566
  if (stacked) acc[i] = top;
13507
14567
  points.push([frame2.band(i), frame2.value(top)]);
14568
+ marks.push({
14569
+ series: s,
14570
+ index: i,
14571
+ x: frame2.band(i),
14572
+ y: frame2.value(top),
14573
+ radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
14574
+ });
13508
14575
  lower.push([frame2.band(i), frame2.value(below2)]);
13509
14576
  });
13510
14577
  layers.push({
14578
+ series: s,
13511
14579
  points,
13512
14580
  lower,
13513
14581
  color: s.color,
13514
14582
  filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
13515
14583
  });
13516
14584
  });
13517
- for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
14585
+ for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
13518
14586
  if (area) {
13519
14587
  const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
13520
14588
  out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
@@ -13533,10 +14601,11 @@ function linesAndAreas(model, frame2, out) {
13533
14601
  else segment2.push(`${n(x)},${n(y)}`);
13534
14602
  }
13535
14603
  flush();
13536
- for (const [x, y] of points)
13537
- if (!Number.isNaN(x))
13538
- out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
14604
+ points.forEach(([x, y], index) => {
14605
+ if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
14606
+ });
13539
14607
  }
14608
+ pointLabels(model, marks, out);
13540
14609
  }
13541
14610
 
13542
14611
  // chart/render/chart-svg-xy.ts
@@ -13544,16 +14613,14 @@ function scatter(model, area, out) {
13544
14613
  const ys = model.valueAxis;
13545
14614
  const xs = model.xAxis;
13546
14615
  if (!ys || !xs) return;
13547
- const yLabels = ys.ticks.map((t) => formatAxisValue(t));
14616
+ const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
13548
14617
  const valueAttrs = chartTextAttributes(model, "valueAxis");
13549
14618
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
13550
14619
  const valueSize = valueAttrs.size ?? 10;
13551
14620
  const categorySize = categoryAttrs.size ?? 10;
13552
- const grid = chartStroke(model, "gridlineMajor");
13553
14621
  const xAxis = chartStroke(model, "categoryAxis");
13554
- const yAxis = chartStroke(model, "valueAxis");
13555
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
13556
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
14622
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
14623
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
13557
14624
  const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
13558
14625
  const plot = {
13559
14626
  x: area.x + labelW,
@@ -13573,17 +14640,24 @@ function scatter(model, area, out) {
13573
14640
  s.values.forEach((_, i) => {
13574
14641
  reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
13575
14642
  });
13576
- const widen = (s, length) => {
14643
+ const widen = (s, length, axis) => {
14644
+ if (axis?.range.logScale) return s;
13577
14645
  const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
13578
- return { ...s, min: s.min - pad, max: s.max + pad };
14646
+ return {
14647
+ ...s,
14648
+ min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
14649
+ max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
14650
+ };
13579
14651
  };
13580
- const xView = widen(xs, plot.w);
13581
- const yView = widen(ys, plot.h);
13582
- const px = (v) => plot.x + (v - xView.min) / (xView.max - xView.min || 1) * plot.w;
13583
- const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
14652
+ const xView = widen(xs, plot.w, model.axes?.category);
14653
+ const yView = widen(ys, plot.h, model.axes?.value);
14654
+ const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
14655
+ const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
13584
14656
  out.push(chartAreaRect(model, "plotArea", plot));
14657
+ out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
14658
+ if (model.axes?.category)
14659
+ out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
13585
14660
  ys.ticks.forEach((t, i) => {
13586
- out.push(line2(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
13587
14661
  if (valueLabels)
13588
14662
  out.push(
13589
14663
  text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
@@ -13593,19 +14667,31 @@ function scatter(model, area, out) {
13593
14667
  );
13594
14668
  });
13595
14669
  for (const t of xs.ticks) {
13596
- out.push(line2(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
14670
+ if (!model.axes?.category?.source.deleted)
14671
+ out.push(line2(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
13597
14672
  if (categoryLabels)
13598
14673
  out.push(
13599
- text(px(t), plot.y + plot.h + categorySize + 3, formatAxisValue(t), {
14674
+ text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
13600
14675
  anchor: "middle",
13601
14676
  ...categoryAttrs
13602
14677
  })
13603
14678
  );
13604
14679
  }
13605
14680
  out.push(
13606
- line2(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
14681
+ axisLine(
14682
+ model,
14683
+ model.axes?.category,
14684
+ "categoryAxis",
14685
+ plot.x,
14686
+ plot.y + plot.h,
14687
+ plot.x + plot.w,
14688
+ plot.y + plot.h
14689
+ )
14690
+ );
14691
+ out.push(
14692
+ axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
13607
14693
  );
13608
- out.push(line2(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
14694
+ const marks = [];
13609
14695
  for (const [si, s] of model.series.entries())
13610
14696
  s.values.forEach((v, i) => {
13611
14697
  const x = s.xValues?.[i] ?? null;
@@ -13613,15 +14699,18 @@ function scatter(model, area, out) {
13613
14699
  const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
13614
14700
  const fill = s.pointColors?.[i] ?? s.color;
13615
14701
  if (!bubble) {
13616
- out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
14702
+ out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
14703
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
13617
14704
  return;
13618
14705
  }
13619
14706
  const r = radiusOf(s.sizes?.[i] ?? void 0);
13620
14707
  if (r === void 0) return;
14708
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: r });
13621
14709
  out.push(
13622
14710
  `<circle cx="${n(px(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i}"${filter}/>`
13623
14711
  );
13624
14712
  });
14713
+ pointLabels(model, marks, out);
13625
14714
  scatterAnalysis(model, px, py, out);
13626
14715
  }
13627
14716
 
@@ -13738,21 +14827,21 @@ function cartesianSvg(model, area) {
13738
14827
  return out.join("");
13739
14828
  }
13740
14829
  const layers = [{ model, frame: frame2 }];
13741
- for (const group of model.extraGroups ?? []) {
14830
+ for (const group2 of model.extraGroups ?? []) {
13742
14831
  const grouped = {
13743
14832
  ...model,
13744
- type: group.type,
13745
- grouping: group.grouping,
13746
- series: group.series,
14833
+ type: group2.type,
14834
+ grouping: group2.grouping,
14835
+ series: group2.series,
13747
14836
  horizontal: false
13748
14837
  };
13749
- if (group.stock) grouped.stock = group.stock;
14838
+ if (group2.stock) grouped.stock = group2.stock;
13750
14839
  else delete grouped.stock;
13751
- if (group.barGapWidth !== void 0) grouped.barGapWidth = group.barGapWidth;
14840
+ if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
13752
14841
  else delete grouped.barGapWidth;
13753
- if (group.barOverlap !== void 0) grouped.barOverlap = group.barOverlap;
14842
+ if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
13754
14843
  else delete grouped.barOverlap;
13755
- const value = group.secondary && frame2.secondary ? frame2.secondary : frame2.value;
14844
+ const value = group2.secondary && frame2.secondary ? frame2.secondary : frame2.value;
13756
14845
  layers.push({ model: grouped, frame: { ...frame2, value } });
13757
14846
  }
13758
14847
  layers.map((layer, order) => ({ layer, order })).sort(
@@ -13786,7 +14875,9 @@ function pieSvg(model, area) {
13786
14875
  const out = [chartAreaRect(model, "plotArea", area)];
13787
14876
  const cx = area.x + area.w / 2;
13788
14877
  const cy = area.y + area.h / 2;
13789
- const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4);
14878
+ const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
14879
+ const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
14880
+ const slices = [];
13790
14881
  const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
13791
14882
  const hole = model.type === "doughnut" ? radius * 0.5 : 0;
13792
14883
  const ringSize = (radius - hole) / Math.max(1, rings.length);
@@ -13803,9 +14894,20 @@ function pieSvg(model, area) {
13803
14894
  out.push(
13804
14895
  `<path d="${slicePath(cx, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
13805
14896
  );
14897
+ slices.push({
14898
+ series: s,
14899
+ index: i,
14900
+ cx,
14901
+ cy,
14902
+ outer,
14903
+ inner,
14904
+ start: angle,
14905
+ end: angle + sweep
14906
+ });
13806
14907
  angle += sweep;
13807
14908
  });
13808
14909
  });
14910
+ sliceLabels(model, slices, out);
13809
14911
  return out.join("");
13810
14912
  }
13811
14913
  function radarSvg(model, area) {
@@ -13818,32 +14920,37 @@ function radarSvg(model, area) {
13818
14920
  const valueSize = valueAttrs.size ?? 9;
13819
14921
  const categorySize = categoryAttrs.size ?? 10;
13820
14922
  const grid = chartStroke(model, "gridlineMajor");
13821
- const axis = chartStroke(model, "categoryAxis");
13822
14923
  const cx = area.x + area.w / 2;
13823
14924
  const cy = area.y + area.h / 2 + 4;
13824
14925
  const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
13825
14926
  const angle = (i) => i / count * Math.PI * 2;
13826
- const r = (v) => (v - scale.min) / (scale.max - scale.min || 1) * radius;
14927
+ const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
13827
14928
  const labelEvery = Math.max(
13828
14929
  1,
13829
14930
  Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
13830
14931
  );
13831
14932
  for (const [k, t] of scale.ticks.entries()) {
13832
14933
  const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
13833
- out.push(
13834
- `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
13835
- );
13836
- if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
14934
+ if (!model.axes?.value || model.axes.value.source.majorGridlines)
14935
+ out.push(
14936
+ `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
14937
+ );
14938
+ if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
13837
14939
  out.push(
13838
- text(cx + 3, cy - r(t) + valueSize * 0.3, formatAxisValue(t, scale.percent), valueAttrs)
14940
+ text(
14941
+ cx + 3,
14942
+ cy - r(t) + valueSize * 0.3,
14943
+ axisTickText(t, model.axes?.value, scale.percent),
14944
+ valueAttrs
14945
+ )
13839
14946
  );
13840
14947
  }
13841
14948
  model.categories.forEach((c, i) => {
13842
14949
  const [x, y] = polar(cx, cy, radius, angle(i));
13843
- out.push(line2(cx, cy, x, y, axis.color, axis.width));
14950
+ out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
13844
14951
  const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
13845
14952
  const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
13846
- if (model.appearance?.categoryAxis?.labelsVisible !== false)
14953
+ if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
13847
14954
  out.push(
13848
14955
  text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
13849
14956
  anchor,
@@ -13851,12 +14958,22 @@ function radarSvg(model, area) {
13851
14958
  })
13852
14959
  );
13853
14960
  });
14961
+ const marks = [];
13854
14962
  for (const s of model.series) {
13855
- const points = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
14963
+ const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
14964
+ vertices.forEach(([x, y], i) => {
14965
+ if (s.values[i] === null) return;
14966
+ const markerSeries = s;
14967
+ if (markerSeries.marker || markerSeries.pointMarkers)
14968
+ out.push(chartSeriesMarkerSvg(s, i, x, y));
14969
+ marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
14970
+ });
14971
+ const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
13856
14972
  out.push(
13857
14973
  `<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
13858
14974
  );
13859
14975
  }
14976
+ pointLabels(model, marks, out);
13860
14977
  return out.join("");
13861
14978
  }
13862
14979
 
@@ -13947,33 +15064,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
13947
15064
  function cssFont(attrs) {
13948
15065
  return `${attrs.italic ? "italic" : "normal"} ${attrs.weight ?? "normal"} ${attrs.size ?? 10}px ${attrs.family ?? CHART_FONT_FAMILY}`;
13949
15066
  }
13950
- function chartFontMetrics(attrs, options) {
13951
- const metrics = options.measureFont?.(cssFont(attrs));
15067
+ function chartFontMetrics(attrs, options2) {
15068
+ const metrics = options2.measureFont?.(cssFont(attrs));
13952
15069
  return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
13953
15070
  }
13954
- function chartTextWidth(content, attrs, options) {
13955
- const width = options.measureText?.(content, cssFont(attrs));
15071
+ function chartTextWidth(content, attrs, options2) {
15072
+ const width = options2.measureText?.(content, cssFont(attrs));
13956
15073
  return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs.size);
13957
15074
  }
13958
- function fitChartText(content, maxWidth, attrs, options) {
13959
- if (!options.measureText) return fit(content, maxWidth, attrs.size);
13960
- if (chartTextWidth(content, attrs, options) <= maxWidth) return content;
15075
+ function fitChartText(content, maxWidth, attrs, options2) {
15076
+ if (!options2.measureText) return fit(content, maxWidth, attrs.size);
15077
+ if (chartTextWidth(content, attrs, options2) <= maxWidth) return content;
13961
15078
  const points = [...content];
13962
15079
  let low = 0;
13963
15080
  let high = points.length;
13964
15081
  while (low < high) {
13965
15082
  const mid = Math.ceil((low + high) / 2);
13966
- if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs, options) <= maxWidth) low = mid;
15083
+ if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs, options2) <= maxWidth) low = mid;
13967
15084
  else high = mid - 1;
13968
15085
  }
13969
15086
  return `${points.slice(0, low).join("")}\u2026`;
13970
15087
  }
13971
15088
 
13972
15089
  // chart/render/chart-svg-legend.ts
13973
- function chartLegendSvg(model, area, frame2, options) {
15090
+ function chartLegendSvg(model, area, frame2, options2) {
13974
15091
  const automatic = [];
13975
15092
  const bounds = {};
13976
- const reserved = automaticLegend(model, area, automatic, options, bounds);
15093
+ const reserved = automaticLegend(model, area, automatic, options2, bounds);
13977
15094
  const plot = model.legendOverlay ? area : reserved;
13978
15095
  const box = bounds.box;
13979
15096
  if (!box) return { plot, markup: "", foreground: false };
@@ -13987,11 +15104,11 @@ function chartLegendSvg(model, area, frame2, options) {
13987
15104
  const entries = legendEntries(model);
13988
15105
  const attrs = chartTextAttributes(model, "legend");
13989
15106
  const size = attrs.size ?? 10;
13990
- const font = chartFontMetrics(attrs, options);
15107
+ const font = chartFontMetrics(attrs, options2);
13991
15108
  const keySize = size / 2;
13992
15109
  const keyGap = size / 4;
13993
15110
  const widths = entries.map(
13994
- (entry) => chartTextWidth(entry.label, attrs, options) + keySize + keyGap
15111
+ (entry) => chartTextWidth(entry.label, attrs, options2) + keySize + keyGap
13995
15112
  );
13996
15113
  const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
13997
15114
  const rowWidth = horizontal ? manual.width / entries.length : manual.width;
@@ -14006,8 +15123,8 @@ function chartLegendSvg(model, area, frame2, options) {
14006
15123
  ];
14007
15124
  const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
14008
15125
  entries.forEach((entry, i) => {
14009
- const available = horizontal ? chartTextWidth(entry.label, attrs, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
14010
- const label = fitChartText(entry.label, available, attrs, options);
15126
+ const available = horizontal ? chartTextWidth(entry.label, attrs, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
15127
+ const label = fitChartText(entry.label, available, attrs, options2);
14011
15128
  const contentWidth = Math.min(
14012
15129
  horizontal ? widths[i] ?? 0 : Math.max(...widths),
14013
15130
  rowWidth - size / 2
@@ -14050,7 +15167,7 @@ function legendEntries(model) {
14050
15167
  color: s.color
14051
15168
  }));
14052
15169
  }
14053
- function automaticLegend(model, area, out, options, bounds) {
15170
+ function automaticLegend(model, area, out, options2, bounds) {
14054
15171
  const entries = legendEntries(model);
14055
15172
  if (!model.showLegend || entries.length === 0) return area;
14056
15173
  const pos = model.legendPosition;
@@ -14059,7 +15176,7 @@ function automaticLegend(model, area, out, options, bounds) {
14059
15176
  const rowH = Math.max(16, size * 1.4);
14060
15177
  if (pos === "t" || pos === "b") {
14061
15178
  const widths = entries.map(
14062
- (e) => Math.min(chartTextWidth(e.label, attrs, options) + 20, area.w / 2)
15179
+ (e) => Math.min(chartTextWidth(e.label, attrs, options2) + 20, area.w / 2)
14063
15180
  );
14064
15181
  const total = widths.reduce((a, b) => a + b, 0);
14065
15182
  let x2 = area.x + Math.max(0, (area.w - total) / 2);
@@ -14076,14 +15193,14 @@ function automaticLegend(model, area, out, options, bounds) {
14076
15193
  entries.forEach((e, i) => {
14077
15194
  const w = widths[i] ?? 0;
14078
15195
  out.push(rect2(x2, y, 8, 8, e.color));
14079
- out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs, options), attrs));
15196
+ out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs, options2), attrs));
14080
15197
  x2 += w;
14081
15198
  });
14082
15199
  return pos === "t" ? { x: area.x, y: area.y + rowH + 4, w: area.w, h: area.h - rowH - 4 } : { x: area.x, y: area.y, w: area.w, h: area.h - rowH - 4 };
14083
15200
  }
14084
15201
  const width = Math.min(
14085
15202
  area.w * 0.35,
14086
- Math.max(...entries.map((e) => chartTextWidth(e.label, attrs, options))) + 22
15203
+ Math.max(...entries.map((e) => chartTextWidth(e.label, attrs, options2))) + 22
14087
15204
  );
14088
15205
  const height = entries.length * rowH;
14089
15206
  const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
@@ -14101,24 +15218,24 @@ function automaticLegend(model, area, out, options, bounds) {
14101
15218
  const y = y0 + i * rowH;
14102
15219
  if (y + rowH > area.y + area.h + 2) return;
14103
15220
  out.push(rect2(x, y + 3, 8, 8, e.color));
14104
- out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs, options), attrs));
15221
+ out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs, options2), attrs));
14105
15222
  });
14106
15223
  return pos === "l" ? { x: area.x + width + 8, y: area.y, w: area.w - width - 8, h: area.h } : { x: area.x, y: area.y, w: area.w - width - 8, h: area.h };
14107
15224
  }
14108
15225
 
14109
15226
  // text/wrap-styled-runs.ts
14110
15227
  var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
14111
- function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
15228
+ function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
14112
15229
  const groups = [];
14113
15230
  for (const [source, run] of runs.entries()) {
14114
15231
  for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
14115
15232
  const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
14116
- let group = groups.at(-1);
14117
- if (!group || group.kind !== kind || kind === "break") {
14118
- group = { kind, pieces: [] };
14119
- groups.push(group);
15233
+ let group2 = groups.at(-1);
15234
+ if (!group2 || group2.kind !== kind || kind === "break") {
15235
+ group2 = { kind, pieces: [] };
15236
+ groups.push(group2);
14120
15237
  }
14121
- if (kind !== "break") group.pieces.push({ run, source, text: token });
15238
+ if (kind !== "break") group2.pieces.push({ run, source, text: token });
14122
15239
  }
14123
15240
  }
14124
15241
  const merged = (left, right) => {
@@ -14131,7 +15248,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
14131
15248
  return result2;
14132
15249
  };
14133
15250
  const width = (pieces) => pieces.reduce((sum, piece) => {
14134
- const advance = measure(piece.text, piece.run);
15251
+ const advance = measure2(piece.text, piece.run);
14135
15252
  return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
14136
15253
  }, 0);
14137
15254
  const result = [];
@@ -14142,29 +15259,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
14142
15259
  line3 = [];
14143
15260
  spaces = [];
14144
15261
  };
14145
- for (const group of groups) {
14146
- if (group.kind === "break") {
15262
+ for (const group2 of groups) {
15263
+ if (group2.kind === "break") {
14147
15264
  flush();
14148
15265
  continue;
14149
15266
  }
14150
- if (group.kind === "space") {
14151
- spaces = group.pieces;
15267
+ if (group2.kind === "space") {
15268
+ spaces = group2.pieces;
14152
15269
  continue;
14153
15270
  }
14154
15271
  const separator = line3.length ? spaces : [];
14155
- const wordWidth = width(group.pieces);
14156
- if (line3.length && width(merged(line3, [...separator, ...group.pieces])) > maxWidth) flush();
15272
+ const wordWidth = width(group2.pieces);
15273
+ if (line3.length && width(merged(line3, [...separator, ...group2.pieces])) > maxWidth) flush();
14157
15274
  else line3 = merged(line3, separator);
14158
15275
  spaces = [];
14159
- if (options.breakWords && wordWidth > maxWidth) {
14160
- for (const piece of group.pieces) {
15276
+ if (options2.breakWords && wordWidth > maxWidth) {
15277
+ for (const piece of group2.pieces) {
14161
15278
  for (const { segment: segment2 } of graphemes.segment(piece.text)) {
14162
15279
  const next = { ...piece, text: segment2 };
14163
15280
  if (line3.length && width(merged(line3, [next])) > maxWidth) flush();
14164
15281
  line3 = merged(line3, [next]);
14165
15282
  }
14166
15283
  }
14167
- } else line3 = merged(line3, group.pieces);
15284
+ } else line3 = merged(line3, group2.pieces);
14168
15285
  }
14169
15286
  flush();
14170
15287
  return result;
@@ -14174,11 +15291,11 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
14174
15291
  function spacing(value, naturalHeight, fallback) {
14175
15292
  return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
14176
15293
  }
14177
- function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
15294
+ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
14178
15295
  if (!model.title) return void 0;
14179
15296
  const base = chartTextAttributes(model, "title", 14);
14180
15297
  const capacity = Math.max(1, width * 0.8 - 8);
14181
- if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options) <= capacity)
15298
+ if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
14182
15299
  return void 0;
14183
15300
  const paragraphs = model.titleText?.paragraphs ?? [
14184
15301
  {
@@ -14214,7 +15331,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
14214
15331
  "title",
14215
15332
  base.size
14216
15333
  ),
14217
- options
15334
+ options2
14218
15335
  ),
14219
15336
  { breakWords: true }
14220
15337
  );
@@ -14238,10 +15355,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
14238
15355
  return {
14239
15356
  ...line3,
14240
15357
  runs,
14241
- width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options), 0),
15358
+ width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
14242
15359
  size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
14243
15360
  fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
14244
- (attrs) => chartFontMetrics(attrs, options)
15361
+ (attrs) => chartFontMetrics(attrs, options2)
14245
15362
  )
14246
15363
  };
14247
15364
  });
@@ -14279,7 +15396,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
14279
15396
  anchor: "start"
14280
15397
  }).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
14281
15398
  );
14282
- x += chartTextWidth(run.text, run.attrs, options);
15399
+ x += chartTextWidth(run.text, run.attrs, options2);
14283
15400
  }
14284
15401
  }
14285
15402
  const parent = text(0, 0, "", { ...base, underline: false }).replace(
@@ -14305,7 +15422,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
14305
15422
  }
14306
15423
 
14307
15424
  // chart/render/chart-svg.ts
14308
- function renderChartSvg(model, width, height, options = {}) {
15425
+ function renderChartSvg(model, width, height, options2 = {}) {
14309
15426
  const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
14310
15427
  model = paint2.model;
14311
15428
  const w = Math.max(1, width);
@@ -14319,7 +15436,7 @@ function renderChartSvg(model, width, height, options = {}) {
14319
15436
  if (paint2.defs) out.push(paint2.defs);
14320
15437
  out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
14321
15438
  let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
14322
- const richTitle = chartRichTitleSvg(model, w, options, h);
15439
+ const richTitle = chartRichTitleSvg(model, w, options2, h);
14323
15440
  if (richTitle) {
14324
15441
  if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
14325
15442
  else out.push(richTitle.markup);
@@ -14328,9 +15445,9 @@ function renderChartSvg(model, width, height, options = {}) {
14328
15445
  } else if (model.title) {
14329
15446
  const attrs = chartTextAttributes(model, "title", 14);
14330
15447
  const size = attrs.size ?? 14;
14331
- const label = fitChartText(model.title, w - 16, attrs, options);
14332
- const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs, options) + 8);
14333
- const font = chartFontMetrics(attrs, options);
15448
+ const label = fitChartText(model.title, w - 16, attrs, options2);
15449
+ const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs, options2) + 8);
15450
+ const font = chartFontMetrics(attrs, options2);
14334
15451
  const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
14335
15452
  out.push(
14336
15453
  chartAreaRect(model, "title", {
@@ -14358,7 +15475,7 @@ function renderChartSvg(model, width, height, options = {}) {
14358
15475
  out.push("</svg>");
14359
15476
  return out.join("");
14360
15477
  }
14361
- const legend = chartLegendSvg(model, area, { width: w, height: h }, options);
15478
+ const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
14362
15479
  area = legend.plot;
14363
15480
  if (!legend.foreground) out.push(legend.markup);
14364
15481
  if (area.w > 4 && area.h > 4) {
@@ -14405,8 +15522,8 @@ function chartSpaceKind(space) {
14405
15522
  const type = chartSummaryFromSpace(space).chartType;
14406
15523
  return { type, drawn: DRAWN_CHART_TYPES.has(type) };
14407
15524
  }
14408
- function renderChartSpaceSvg(space, options) {
14409
- const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options;
15525
+ function renderChartSpaceSvg(space, options2) {
15526
+ const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
14410
15527
  const summary = chartSummaryFromSpace(space, {
14411
15528
  ...formatting ? { formatting } : {},
14412
15529
  ...colorPalette !== void 0 ? { colorPalette } : {},
@@ -14415,8 +15532,8 @@ function renderChartSpaceSvg(space, options) {
14415
15532
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
14416
15533
  return renderChartSvg(view, width, height, svg);
14417
15534
  }
14418
- function renderChartSummarySvg(summary, options) {
14419
- const { width, height, theme, fonts, ...svg } = options;
15535
+ function renderChartSummarySvg(summary, options2) {
15536
+ const { width, height, theme, fonts, ...svg } = options2;
14420
15537
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
14421
15538
  return renderChartSvg(view, width, height, svg);
14422
15539
  }
@@ -14521,11 +15638,11 @@ function parseDirectParagraphProperties(props) {
14521
15638
 
14522
15639
  // docx/numbering-parse.ts
14523
15640
  var own = (map, key) => Object.prototype.hasOwnProperty.call(map, key) ? map[key] : void 0;
14524
- function resolveNumberingLevel(catalog, numId, level) {
15641
+ function resolveNumberingLevel(catalog, numId, level2) {
14525
15642
  const num = own(catalog.nums, numId);
14526
15643
  if (!num) return void 0;
14527
- const override = num.levelOverrides?.[level];
14528
- const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level];
15644
+ const override = num.levelOverrides?.[level2];
15645
+ const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level2];
14529
15646
  const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
14530
15647
  let base = override?.lvl ?? abstract;
14531
15648
  if (!base) return void 0;
@@ -14924,10 +16041,10 @@ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
14924
16041
  const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
14925
16042
  if (!inherited || inherited.numId <= 0) return void 0;
14926
16043
  if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
14927
- for (let level = 0; level < 9; level++) {
14928
- const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level);
16044
+ for (let level2 = 0; level2 < 9; level2++) {
16045
+ const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level2);
14929
16046
  if (definition?.paragraphStyleId === paragraph.style)
14930
- return { numId: inherited.numId, level };
16047
+ return { numId: inherited.numId, level: level2 };
14931
16048
  }
14932
16049
  }
14933
16050
  return inherited;
@@ -14960,23 +16077,23 @@ var NumberingCounters = class {
14960
16077
  return started;
14961
16078
  }
14962
16079
  /** Advances one level and resets deeper counters according to their resolved restart rules. */
14963
- advance(numId, level, def, catalog) {
16080
+ advance(numId, level2, def, catalog) {
14964
16081
  const counts = this.forNum(numId);
14965
16082
  const started = this.startedLevels(numId);
14966
- const next = started.has(level) ? (counts.get(level) ?? def.start) + 1 : def.start;
14967
- counts.set(level, next);
14968
- started.add(level);
16083
+ const next = started.has(level2) ? (counts.get(level2) ?? def.start) + 1 : def.start;
16084
+ counts.set(level2, next);
16085
+ started.add(level2);
14969
16086
  for (const deeper of [...started]) {
14970
- if (deeper <= level) continue;
16087
+ if (deeper <= level2) continue;
14971
16088
  const deeperDef = resolveNumberingLevel(catalog, numId, deeper);
14972
16089
  const restart = deeperDef?.lvlRestart;
14973
16090
  if (restart === 0) continue;
14974
16091
  const trigger = restart !== void 0 && restart > 0 && restart <= deeper ? restart - 1 : deeper - 1;
14975
- if (level > trigger) continue;
16092
+ if (level2 > trigger) continue;
14976
16093
  counts.delete(deeper);
14977
16094
  started.delete(deeper);
14978
16095
  }
14979
- for (let ancestor = 0; ancestor < level; ancestor++) {
16096
+ for (let ancestor = 0; ancestor < level2; ancestor++) {
14980
16097
  if (started.has(ancestor)) continue;
14981
16098
  const ancestorDef = resolveNumberingLevel(catalog, numId, ancestor);
14982
16099
  if (!ancestorDef) continue;
@@ -14986,14 +16103,14 @@ var NumberingCounters = class {
14986
16103
  return next;
14987
16104
  }
14988
16105
  /** Current value for an ancestor placeholder, defaulting to its own start when never instantiated. */
14989
- current(numId, level, start) {
14990
- return this.forNum(numId).get(level) ?? start;
16106
+ current(numId, level2, start) {
16107
+ return this.forNum(numId).get(level2) ?? start;
14991
16108
  }
14992
16109
  };
14993
- function substituteLvlText(lvlText, numId, level, catalog, counters, forceDecimal) {
16110
+ function substituteLvlText(lvlText, numId, level2, catalog, counters, forceDecimal) {
14994
16111
  return lvlText.replace(/%([1-9])/g, (match, digit) => {
14995
16112
  const ancestorLevel = Number(digit) - 1;
14996
- if (ancestorLevel > level) return match;
16113
+ if (ancestorLevel > level2) return match;
14997
16114
  const ancestorDef = resolveNumberingLevel(catalog, numId, ancestorLevel);
14998
16115
  const start = ancestorDef?.start ?? 1;
14999
16116
  const value = counters.current(numId, ancestorLevel, start);
@@ -15010,15 +16127,15 @@ function computeListLabels(model) {
15010
16127
  const numbering = resolveParagraphNumbering(paragraph, model.paragraphStyles, catalog);
15011
16128
  if (!numbering) continue;
15012
16129
  const numId = String(numbering.numId);
15013
- const level = Math.min(8, Math.max(0, numbering.level));
15014
- const def = resolveNumberingLevel(catalog, numId, level);
16130
+ const level2 = Math.min(8, Math.max(0, numbering.level));
16131
+ const def = resolveNumberingLevel(catalog, numId, level2);
15015
16132
  if (!def) continue;
15016
16133
  if (def.numFmt === "none") continue;
15017
- counters.advance(numId, level, def, catalog);
15018
- const text2 = def.numFmt === "bullet" ? def.lvlText : substituteLvlText(def.lvlText, numId, level, catalog, counters, Boolean(def.isLgl));
16134
+ counters.advance(numId, level2, def, catalog);
16135
+ const text2 = def.numFmt === "bullet" ? def.lvlText : substituteLvlText(def.lvlText, numId, level2, catalog, counters, Boolean(def.isLgl));
15019
16136
  labels.set(paragraph.id, {
15020
16137
  numId,
15021
- level,
16138
+ level: level2,
15022
16139
  text: text2,
15023
16140
  suffix: def.suffix ?? "tab",
15024
16141
  ...definedProps({
@@ -15153,7 +16270,7 @@ function datePicture(instr) {
15153
16270
  }
15154
16271
  var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
15155
16272
  function formatWordDate(date, picture, locale = "en-US") {
15156
- const name = (options) => new Intl.DateTimeFormat(locale, options).format(date);
16273
+ const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
15157
16274
  const pad = (value) => String(value).padStart(2, "0");
15158
16275
  const hours12 = date.getHours() % 12 || 12;
15159
16276
  return picture.replace(TOKENS, (token) => {
@@ -15352,9 +16469,9 @@ function fontMetrics(measurer, font) {
15352
16469
  const ascent = Math.min(height, measurer.ascentOf?.(font) ?? height * 0.8);
15353
16470
  return { ascent, descent: height - ascent };
15354
16471
  }
15355
- function createFakeMeasurer(options = {}) {
15356
- const charWidthFactor = options.charWidthFactor ?? 0.6;
15357
- const lineHeightFactor = options.lineHeightFactor ?? 1.15;
16472
+ function createFakeMeasurer(options2 = {}) {
16473
+ const charWidthFactor = options2.charWidthFactor ?? 0.6;
16474
+ const lineHeightFactor = options2.lineHeightFactor ?? 1.15;
15358
16475
  return {
15359
16476
  widthOf(text2, font) {
15360
16477
  let width = 0;
@@ -15481,12 +16598,12 @@ function headerFooterSlotForPage(model, page, pageNumber) {
15481
16598
  return page.pageInSection === 0 && section?.titlePage ? "first" : model.evenAndOddHeaders && pageNumber % 2 === 0 ? "even" : "default";
15482
16599
  }
15483
16600
  function headerFooterForPage(model, page, pageNumber, kind) {
15484
- const sections = model.sections ?? [];
15485
- const section = sections[page.sectionIndex];
16601
+ const sections2 = model.sections ?? [];
16602
+ const section = sections2[page.sectionIndex];
15486
16603
  if (!section) return void 0;
15487
16604
  const slot = headerFooterSlotForPage(model, page, pageNumber);
15488
16605
  for (let index = page.sectionIndex; index >= 0; index--) {
15489
- const content = sections[index]?.[kind]?.[slot];
16606
+ const content = sections2[index]?.[kind]?.[slot];
15490
16607
  if (content) return content;
15491
16608
  }
15492
16609
  return void 0;
@@ -17223,11 +18340,11 @@ function completedNoteStoryMinimum(row2, stories, pendingBlocks, available) {
17223
18340
  for (const [index, cell] of row2.cells.entries()) {
17224
18341
  const groups = /* @__PURE__ */ new Map();
17225
18342
  for (const box of cell) {
17226
- const group = stories.get(box.blockId);
17227
- if (group !== void 0) {
17228
- const boxes = groups.get(group) ?? [];
18343
+ const group2 = stories.get(box.blockId);
18344
+ if (group2 !== void 0) {
18345
+ const boxes = groups.get(group2) ?? [];
17229
18346
  boxes.push(box);
17230
- groups.set(group, boxes);
18347
+ groups.set(group2, boxes);
17231
18348
  }
17232
18349
  }
17233
18350
  for (const boxes of groups.values()) {
@@ -17293,8 +18410,8 @@ var TableFootnotes = class {
17293
18410
  for (const cell of row2.cells) {
17294
18411
  for (const paragraph of cellParagraphs(cell))
17295
18412
  if (paragraph.footnotes?.length) this.paragraphs.set(paragraph.id, paragraph);
17296
- for (const [id, group] of (measured ? independentNoteStories(cell) : void 0) ?? []) {
17297
- this.stories.set(id, group);
18413
+ for (const [id, group2] of (measured ? independentNoteStories(cell) : void 0) ?? []) {
18414
+ this.stories.set(id, group2);
17298
18415
  }
17299
18416
  }
17300
18417
  }
@@ -17427,11 +18544,11 @@ var TableFootnotes = class {
17427
18544
  for (const [index, cell] of row2.cells.entries()) {
17428
18545
  const groups = /* @__PURE__ */ new Map();
17429
18546
  for (const box of cell) {
17430
- const group = this.stories.get(box.blockId);
17431
- if (group !== void 0) {
17432
- const boxes = groups.get(group) ?? [];
18547
+ const group2 = this.stories.get(box.blockId);
18548
+ if (group2 !== void 0) {
18549
+ const boxes = groups.get(group2) ?? [];
17433
18550
  boxes.push(box);
17434
- groups.set(group, boxes);
18551
+ groups.set(group2, boxes);
17435
18552
  }
17436
18553
  }
17437
18554
  for (const boxes of groups.values()) {
@@ -19776,8 +20893,8 @@ function sectionBreak(type, note) {
19776
20893
  return type;
19777
20894
  }
19778
20895
  function adaptDocumentModel(model, note = () => {
19779
- }, options = {}) {
19780
- const reviewMode = options.reviewDisplayMode ?? "all";
20896
+ }, options2 = {}) {
20897
+ const reviewMode = options2.reviewDisplayMode ?? "all";
19781
20898
  const visibleModel = visibleReviewModel(model, reviewMode);
19782
20899
  const catalog = model.paragraphStyles;
19783
20900
  const noted = /* @__PURE__ */ new Set();
@@ -19955,14 +21072,14 @@ function adaptDocumentModel(model, note = () => {
19955
21072
  note2.blocks.filter((block) => block.type === "paragraph").map((paragraph) => adaptParagraph(paragraph))
19956
21073
  ])
19957
21074
  ) : void 0;
19958
- const sections = model.sections;
21075
+ const sections2 = model.sections;
19959
21076
  const modernFootnoteSeparator = model.compatibilityMode === 15;
19960
21077
  const legacyFootnoteColumns = model.compatibilityMode === 12 || model.compatibilityMode === 14;
19961
21078
  if (!modernFootnoteSeparator && !legacyFootnoteColumns && model.sections?.some((section) => section.footnoteColumns !== void 0))
19962
21079
  reportOnce(
19963
21080
  "Footnote column settings are preserved, but this compatibility mode has not been verified against native Word; Print Layout uses the existing page-wide fallback."
19964
21081
  );
19965
- if (!sections || !sections.length) {
21082
+ if (!sections2 || !sections2.length) {
19966
21083
  return {
19967
21084
  sections: [
19968
21085
  {
@@ -19984,8 +21101,8 @@ function adaptDocumentModel(model, note = () => {
19984
21101
  }
19985
21102
  const indexById = new Map(model.blocks.map((block, index) => [block.id, index]));
19986
21103
  let start = 0;
19987
- const result = sections.map((section, index) => {
19988
- const last = index === sections.length - 1;
21104
+ const result = sections2.map((section, index) => {
21105
+ const last = index === sections2.length - 1;
19989
21106
  const endIndex = last ? blocks.length : (indexById.get(section.endsAtBlockId) ?? start - 1) + 1;
19990
21107
  const end = Math.max(start, endIndex);
19991
21108
  const slice = blocks.slice(start, end);
@@ -20170,13 +21287,13 @@ function layoutDocument(input, measurer) {
20170
21287
  }
20171
21288
  return { ...result, approximations: [.../* @__PURE__ */ new Set([...result.approximations, FLOAT_WRAP_NOTE])] };
20172
21289
  }
20173
- function layoutDocumentModel(model, measurer, options = {}, layout = layoutDocument) {
20174
- const projected = reviewDocumentFormatting(model, options.reviewDisplayMode ?? "all");
21290
+ function layoutDocumentModel(model, measurer, options2 = {}, layout = layoutDocument) {
21291
+ const projected = reviewDocumentFormatting(model, options2.reviewDisplayMode ?? "all");
20175
21292
  const approximations = reviewFormattingWarnings(projected.diagnostics);
20176
21293
  const input = adaptDocumentModel(
20177
21294
  projected.model,
20178
21295
  (message) => approximations.push(message),
20179
- options
21296
+ options2
20180
21297
  );
20181
21298
  const result = layout(input, measurer);
20182
21299
  return {
@@ -20359,7 +21476,7 @@ function layoutDocumentIncremental(input, measurer, memory) {
20359
21476
  }
20360
21477
 
20361
21478
  // docx/layout/layout-session.ts
20362
- function createLayoutSession(measurer, options = {}) {
21479
+ function createLayoutSession(measurer, options2 = {}) {
20363
21480
  const sessionMeasurer = {
20364
21481
  widthOf: (text2, font) => measurer.widthOf(text2, font),
20365
21482
  lineHeightOf: (font) => measurer.lineHeightOf(font),
@@ -20367,7 +21484,7 @@ function createLayoutSession(measurer, options = {}) {
20367
21484
  };
20368
21485
  registerParagraphCache(sessionMeasurer);
20369
21486
  const memory = {};
20370
- const paginate = options.incremental ? (input, sessionMeasure) => layoutDocumentIncremental(input, sessionMeasure, memory) : layoutDocument;
21487
+ const paginate = options2.incremental ? (input, sessionMeasure) => layoutDocumentIncremental(input, sessionMeasure, memory) : layoutDocument;
20371
21488
  return {
20372
21489
  layoutDocument: (input) => paginate(input, sessionMeasurer),
20373
21490
  layoutDocumentModel: (model, review = {}) => layoutDocumentModel(model, sessionMeasurer, review, paginate),