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
@@ -133,8 +133,8 @@ function resolveRunFormatting(run, context = {}) {
133
133
  if (state) result[key] = true;
134
134
  }
135
135
  for (const key of OVERRIDE_KEYS) {
136
- for (const level of levels) {
137
- const value = level[key];
136
+ for (const level2 of levels) {
137
+ const value = level2[key];
138
138
  if (value !== void 0) result[key] = value;
139
139
  }
140
140
  }
@@ -804,17 +804,17 @@ function checkXmlLimits(xml, label, limits = {}) {
804
804
  throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
805
805
  }
806
806
  }
807
- function parseXml(xml, options = {}) {
808
- const label = options.label ?? "OOXML";
807
+ function parseXml(xml, options2 = {}) {
808
+ const label = options2.label ?? "OOXML";
809
809
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
810
810
  throw new Error(`${label} XML with DTD or entity declarations is not supported`);
811
- checkXmlLimits(xml, label, options.limits);
811
+ checkXmlLimits(xml, label, options2.limits);
812
812
  let parseError = "";
813
813
  let parsed;
814
814
  try {
815
815
  parsed = new DOMParser({
816
- onError: (level, message) => {
817
- if (level !== "warning") parseError = message;
816
+ onError: (level2, message) => {
817
+ if (level2 !== "warning") parseError = message;
818
818
  }
819
819
  }).parseFromString(xml, "application/xml");
820
820
  } catch (error) {
@@ -1558,8 +1558,8 @@ function parseTableStyleCatalog(xml) {
1558
1558
 
1559
1559
  // docx/default-styles.ts
1560
1560
  var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
1561
- var heading = (id, name, level, before, size, color) => `<w:style w:type="paragraph" w:styleId="${id}"><w:name w:val="${name}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="9"/><w:qFormat/><w:pPr><w:keepNext/><w:keepLines/><w:spacing w:before="${before}" w:after="0"/><w:outlineLvl w:val="${level}"/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:color w:val="${color}"/><w:sz w:val="${size}"/><w:szCs w:val="${size}"/></w:rPr></w:style>`;
1562
- var toc = (level) => `<w:style w:type="paragraph" w:styleId="TOC${level}"><w:name w:val="toc ${level}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="39"/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="100"/>${level > 1 ? `<w:ind w:left="${(level - 1) * 220}"/>` : ""}</w:pPr></w:style>`;
1561
+ var heading = (id, name, level2, before, size, color) => `<w:style w:type="paragraph" w:styleId="${id}"><w:name w:val="${name}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="9"/><w:qFormat/><w:pPr><w:keepNext/><w:keepLines/><w:spacing w:before="${before}" w:after="0"/><w:outlineLvl w:val="${level2}"/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:color w:val="${color}"/><w:sz w:val="${size}"/><w:szCs w:val="${size}"/></w:rPr></w:style>`;
1562
+ var toc = (level2) => `<w:style w:type="paragraph" w:styleId="TOC${level2}"><w:name w:val="toc ${level2}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="39"/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="100"/>${level2 > 1 ? `<w:ind w:left="${(level2 - 1) * 220}"/>` : ""}</w:pPr></w:style>`;
1563
1563
  var noteStyles = (id, name) => `<w:style w:type="paragraph" w:styleId="${id}Text"><w:name w:val="${name} text"/><w:basedOn w:val="Normal"/><w:link w:val="${id}TextChar"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style><w:style w:type="character" w:styleId="${id}TextChar"><w:name w:val="${name} Text Char"/><w:basedOn w:val="DefaultParagraphFont"/><w:link w:val="${id}Text"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style><w:style w:type="character" w:styleId="${id}Reference"><w:name w:val="${name} reference"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:rPr><w:vertAlign w:val="superscript"/></w:rPr></w:style>`;
1564
1564
  var DEFAULT_STYLES_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles xmlns:w="${W}"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Calibri" w:eastAsia="Calibri" w:hAnsi="Calibri" w:cs="Times New Roman"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="table" w:default="1" w:styleId="TableNormal"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="numbering" w:default="1" w:styleId="NoList"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="paragraph" w:styleId="Title"><w:name w:val="Title"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="10"/><w:qFormat/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/><w:contextualSpacing/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:spacing w:val="-10"/><w:kern w:val="28"/><w:sz w:val="56"/><w:szCs w:val="56"/></w:rPr></w:style>` + heading("Heading1", "heading 1", 0, 240, 32, "2F5496") + heading("Heading2", "heading 2", 1, 40, 26, "2F5496") + heading("Heading3", "heading 3", 2, 40, 24, "1F3763") + toc(1) + toc(2) + toc(3) + noteStyles("Footnote", "footnote") + noteStyles("Endnote", "endnote") + '<w:style w:type="character" w:styleId="Hyperlink"><w:name w:val="Hyperlink"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:unhideWhenUsed/><w:rPr><w:color w:val="0563C1"/><w:u w:val="single"/></w:rPr></w:style><w:style w:type="character" w:styleId="PlaceholderText"><w:name w:val="Placeholder Text"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:color w:val="808080"/></w:rPr></w:style></w:styles>';
1565
1565
  var cached;
@@ -1730,8 +1730,8 @@ function rgbToHsl(r, g, b) {
1730
1730
  }
1731
1731
  return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
1732
1732
  }
1733
- function hslToRgb(h, s, l, roundChannel = Math.round, options) {
1734
- const sC = options?.clampSaturation === false ? s : clampUnitInterval(s);
1733
+ function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
1734
+ const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
1735
1735
  const lC = clampUnitInterval(l);
1736
1736
  const hN = (h % 360 + 360) % 360;
1737
1737
  const c = (1 - Math.abs(2 * lC - 1)) * sC;
@@ -2220,13 +2220,13 @@ var APPLIED = /* @__PURE__ */ new Set([
2220
2220
  "lumMod",
2221
2221
  "lumOff"
2222
2222
  ]);
2223
- function resolveDrawingColor(color, theme, options) {
2223
+ function resolveDrawingColor(color, theme, options2) {
2224
2224
  const base = baseHex(color, theme);
2225
2225
  const rgb = base ? hexToRgbChannels(base) : null;
2226
2226
  if (!rgb) return void 0;
2227
- if (options?.transformOrder === "document") {
2227
+ if (options2?.transformOrder === "document") {
2228
2228
  const value = orderedColorTransforms(rgb, color.transforms);
2229
- const round = options.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
2229
+ const round = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
2230
2230
  return {
2231
2231
  hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
2232
2232
  alpha: value.alpha,
@@ -2277,7 +2277,7 @@ function resolveDrawingColor(color, theme, options) {
2277
2277
  if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
2278
2278
  const lumOff = parseDrawingFraction(find("lumOff"));
2279
2279
  if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
2280
- const round = options?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
2280
+ const round = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
2281
2281
  ({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
2282
2282
  }
2283
2283
  let alpha = parseDrawingPercent(find("alpha")) ?? 1;
@@ -2388,13 +2388,13 @@ function parseKind(sdtPr) {
2388
2388
  return "richText";
2389
2389
  }
2390
2390
  var generated = 0;
2391
- function parseContentControl(sdt, level) {
2391
+ function parseContentControl(sdt, level2) {
2392
2392
  const sdtPr = first2(sdt, "sdtPr");
2393
- if (!sdtPr) return { id: `sdt-gen-${++generated}`, level, kind: "richText" };
2393
+ if (!sdtPr) return { id: `sdt-gen-${++generated}`, level: level2, kind: "richText" };
2394
2394
  const kind = parseKind(sdtPr);
2395
2395
  const control = {
2396
2396
  id: getW(first2(sdtPr, "id"), "val") ?? `sdt-gen-${++generated}`,
2397
- level,
2397
+ level: level2,
2398
2398
  kind
2399
2399
  };
2400
2400
  const alias = getW(first2(sdtPr, "alias"), "val");
@@ -3738,7 +3738,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
3738
3738
  function lerpEdge(inner, outer, t) {
3739
3739
  return inner + (outer - inner) * t;
3740
3740
  }
3741
- function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
3741
+ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
3742
3742
  if (stops.length === 0) {
3743
3743
  return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
3744
3744
  }
@@ -3747,7 +3747,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
3747
3747
  const rects = [];
3748
3748
  const alphaRects = [];
3749
3749
  const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
3750
- const bands = options?.bands;
3750
+ const bands = options2?.bands;
3751
3751
  if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
3752
3752
  for (let i = bands; i >= 0; i -= 1) {
3753
3753
  const t = i / bands;
@@ -3881,13 +3881,297 @@ function groupRowsByCategory(rawCategories) {
3881
3881
  return { uniqueCategories, rowIndexesByCategory };
3882
3882
  }
3883
3883
 
3884
+ // chart/number-format-pattern.ts
3885
+ var NAMED_FORMAT_COLORS = {
3886
+ black: "#000000",
3887
+ blue: "#0000FF",
3888
+ cyan: "#00FFFF",
3889
+ green: "#00FF00",
3890
+ magenta: "#FF00FF",
3891
+ red: "#FF0000",
3892
+ white: "#FFFFFF",
3893
+ yellow: "#FFFF00"
3894
+ };
3895
+ var PLACEHOLDER = /[0#?]/u;
3896
+ function parsePattern(code) {
3897
+ let scale = 1;
3898
+ let scientific = false;
3899
+ let color;
3900
+ const chars = [];
3901
+ let inQuotes = false;
3902
+ for (let i = 0; i < code.length; i += 1) {
3903
+ const ch = code[i] ?? "";
3904
+ if (ch === '"') {
3905
+ inQuotes = !inQuotes;
3906
+ continue;
3907
+ }
3908
+ if (inQuotes) {
3909
+ chars.push({ ch, literal: true });
3910
+ continue;
3911
+ }
3912
+ if (ch === "\\" || ch === "*" || ch === "_") {
3913
+ const next = code[i + 1];
3914
+ i += 1;
3915
+ if (ch === "\\" && next !== void 0) {
3916
+ chars.push({ ch: next, literal: true });
3917
+ }
3918
+ continue;
3919
+ }
3920
+ if (ch === "%") {
3921
+ scale *= 100;
3922
+ chars.push({ ch, literal: true });
3923
+ continue;
3924
+ }
3925
+ if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
3926
+ scientific = true;
3927
+ chars.push({ ch: "E", literal: false });
3928
+ i += 1;
3929
+ continue;
3930
+ }
3931
+ if (ch === "[") {
3932
+ const close = code.indexOf("]", i);
3933
+ const token = code.slice(i + 1, close === -1 ? code.length : close);
3934
+ const named3 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
3935
+ if (named3 && color === void 0) {
3936
+ color = named3;
3937
+ }
3938
+ i = close === -1 ? code.length : close;
3939
+ continue;
3940
+ }
3941
+ chars.push({ ch, literal: false });
3942
+ }
3943
+ const firstDigit = chars.findIndex((c) => !c.literal && PLACEHOLDER.test(c.ch));
3944
+ if (firstDigit === -1) {
3945
+ return void 0;
3946
+ }
3947
+ let lastDigit = firstDigit;
3948
+ for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
3949
+ const c = chars[i];
3950
+ if (c && !c.literal && (PLACEHOLDER.test(c.ch) || c.ch === "." || c.ch === "," || c.ch === "E")) {
3951
+ lastDigit = i;
3952
+ break;
3953
+ }
3954
+ }
3955
+ const numeric = chars.slice(firstDigit, lastDigit + 1);
3956
+ const prefix = chars.slice(0, firstDigit).map((c) => c.ch).join("");
3957
+ const suffix = chars.slice(lastDigit + 1).map((c) => c.ch).join("");
3958
+ let grouped = false;
3959
+ let intDigits = 0;
3960
+ let required = 0;
3961
+ let optional = 0;
3962
+ let afterPoint = false;
3963
+ let inExponent = false;
3964
+ for (let i = 0; i < numeric.length; i += 1) {
3965
+ const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
3966
+ if (literal) {
3967
+ continue;
3968
+ }
3969
+ if (ch === "E") {
3970
+ inExponent = true;
3971
+ continue;
3972
+ }
3973
+ if (inExponent) {
3974
+ continue;
3975
+ }
3976
+ if (ch === ".") {
3977
+ afterPoint = true;
3978
+ continue;
3979
+ }
3980
+ if (ch === ",") {
3981
+ const next = numeric.slice(i + 1).find((c) => !c.literal);
3982
+ if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
3983
+ scale /= 1e3;
3984
+ } else {
3985
+ grouped = true;
3986
+ }
3987
+ continue;
3988
+ }
3989
+ if (!PLACEHOLDER.test(ch)) {
3990
+ continue;
3991
+ }
3992
+ if (afterPoint) {
3993
+ if (ch === "0") {
3994
+ required += 1;
3995
+ } else {
3996
+ optional += 1;
3997
+ }
3998
+ } else if (ch === "0") {
3999
+ intDigits += 1;
4000
+ }
4001
+ }
4002
+ return {
4003
+ prefix,
4004
+ suffix,
4005
+ intDigits,
4006
+ decimals: { required, optional },
4007
+ grouped,
4008
+ scale,
4009
+ scientific,
4010
+ color
4011
+ };
4012
+ }
4013
+ function group(intPart) {
4014
+ return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
4015
+ }
4016
+ function applyPattern(value, pattern, forcePositive) {
4017
+ const scaled = value * pattern.scale;
4018
+ const magnitude = forcePositive ? Math.abs(scaled) : scaled;
4019
+ if (pattern.scientific) {
4020
+ const digits = pattern.decimals.required + pattern.decimals.optional;
4021
+ const exponential = magnitude.toExponential(digits);
4022
+ const [mantissa = "", exponent = "0"] = exponential.split("e");
4023
+ const sign = exponent.startsWith("-") ? "-" : "+";
4024
+ const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
4025
+ return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
4026
+ }
4027
+ const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
4028
+ let body = magnitude.toFixed(maxDecimals);
4029
+ if (pattern.decimals.optional > 0) {
4030
+ body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
4031
+ const [, frac = ""] = body.split(".");
4032
+ if (frac.length < pattern.decimals.required) {
4033
+ body = Number(body).toFixed(pattern.decimals.required);
4034
+ }
4035
+ }
4036
+ const [rawIntPart = "", fracPart] = body.split(".");
4037
+ let intPart = rawIntPart;
4038
+ const hasMinusChar = intPart.startsWith("-");
4039
+ const negative = hasMinusChar && Number(body) !== 0;
4040
+ if (hasMinusChar) {
4041
+ intPart = intPart.slice(1);
4042
+ }
4043
+ if (intPart.length < pattern.intDigits) {
4044
+ intPart = intPart.padStart(pattern.intDigits, "0");
4045
+ }
4046
+ if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
4047
+ intPart = "";
4048
+ }
4049
+ if (pattern.grouped) {
4050
+ intPart = group(intPart);
4051
+ }
4052
+ const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
4053
+ return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
4054
+ }
4055
+
4056
+ // chart/number-format.ts
4057
+ var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
4058
+ function sections(code) {
4059
+ const out = [];
4060
+ let current = "";
4061
+ let inQuotes = false;
4062
+ for (let i = 0; i < code.length; i += 1) {
4063
+ const ch = code[i];
4064
+ if (ch === '"') {
4065
+ inQuotes = !inQuotes;
4066
+ current += ch;
4067
+ continue;
4068
+ }
4069
+ if (ch === "\\") {
4070
+ current += ch + (code[i + 1] ?? "");
4071
+ i += 1;
4072
+ continue;
4073
+ }
4074
+ if (ch === ";" && !inQuotes) {
4075
+ out.push(current);
4076
+ current = "";
4077
+ continue;
4078
+ }
4079
+ current += ch;
4080
+ }
4081
+ out.push(current);
4082
+ return out;
4083
+ }
4084
+ function sectionFor(value, parts) {
4085
+ if (parts.length === 1) {
4086
+ return { code: parts[0] ?? "", forcePositive: false };
4087
+ }
4088
+ if (value < 0 && parts[1] !== void 0) {
4089
+ return { code: parts[1] ?? "", forcePositive: true };
4090
+ }
4091
+ if (value === 0 && parts[2] !== void 0) {
4092
+ return { code: parts[2] ?? "", forcePositive: false };
4093
+ }
4094
+ return { code: parts[0] ?? "", forcePositive: false };
4095
+ }
4096
+ function formatChartNumberWithColor(value, formatCode) {
4097
+ if (!Number.isFinite(value)) {
4098
+ return void 0;
4099
+ }
4100
+ const code = (formatCode ?? "").trim();
4101
+ if (GENERAL.has(code.toLowerCase())) {
4102
+ return void 0;
4103
+ }
4104
+ if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
4105
+ return void 0;
4106
+ }
4107
+ const { code: section, forcePositive } = sectionFor(value, sections(code));
4108
+ const pattern = parsePattern(section);
4109
+ if (!pattern) {
4110
+ return void 0;
4111
+ }
4112
+ try {
4113
+ return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
4114
+ } catch {
4115
+ return void 0;
4116
+ }
4117
+ }
4118
+ function formatChartNumber(value, formatCode) {
4119
+ return formatChartNumberWithColor(value, formatCode)?.text;
4120
+ }
4121
+
4122
+ // chart/data-label-text.ts
4123
+ var DATA_LABEL_SEPARATOR = ", ";
4124
+ var DATA_LABEL_CATEGORY_PERCENT_SEPARATOR = "\n";
4125
+ var FLAG_KEYS = [
4126
+ "showValue",
4127
+ "showCategory",
4128
+ "showSeriesName",
4129
+ "showPercent",
4130
+ "showBubbleSize"
4131
+ ];
4132
+ function resolveDataLabelFlags(levels) {
4133
+ const { point, series, chart } = levels;
4134
+ const picked = {};
4135
+ for (const key of FLAG_KEYS) picked[key] = point?.[key] ?? series?.[key] ?? chart?.[key];
4136
+ const anyDeclared = FLAG_KEYS.some((key) => picked[key] !== void 0);
4137
+ return {
4138
+ showValue: anyDeclared ? picked.showValue === true : levels.siblingOwnsLabels !== true,
4139
+ showCategory: picked.showCategory === true,
4140
+ showSeriesName: picked.showSeriesName === true,
4141
+ showPercent: picked.showPercent === true,
4142
+ showBubbleSize: picked.showBubbleSize === true,
4143
+ separator: point?.separator ?? series?.separator ?? chart?.separator ?? (picked.showCategory === true && picked.showPercent === true ? DATA_LABEL_CATEGORY_PERCENT_SEPARATOR : DATA_LABEL_SEPARATOR)
4144
+ };
4145
+ }
4146
+ function composeDataLabelText(input) {
4147
+ const { flags, value, numberFormat } = input;
4148
+ const parts = [];
4149
+ let valueColor;
4150
+ if (flags.showSeriesName && input.seriesName) parts.push(input.seriesName);
4151
+ if (flags.showCategory && input.category) parts.push(input.category);
4152
+ if (flags.showValue) {
4153
+ const formatted = formatChartNumberWithColor(value, numberFormat);
4154
+ parts.push(formatted?.text ?? (input.formatValue ?? String)(value, numberFormat));
4155
+ valueColor = formatted?.color;
4156
+ }
4157
+ if (flags.showPercent) {
4158
+ const base = input.percentBase;
4159
+ parts.push(base > 0 ? `${Math.round(Math.abs(value) / base * 100)}%` : "0%");
4160
+ }
4161
+ if (flags.showBubbleSize && input.bubbleSize !== void 0)
4162
+ parts.push((input.formatBubbleSize ?? String)(input.bubbleSize));
4163
+ const text2 = parts.join(flags.separator);
4164
+ if (text2.length === 0) return void 0;
4165
+ return { text: text2, color: parts.length === 1 && flags.showValue ? valueColor : void 0 };
4166
+ }
4167
+
3884
4168
  // chart/bubble-radius.ts
3885
- function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
3886
- const scale = (options?.bubbleScale ?? 100) / 100;
4169
+ function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
4170
+ const scale = (options2?.bubbleScale ?? 100) / 100;
3887
4171
  if (sizeVal === void 0) return medianRadius * scale;
3888
4172
  const denom = maxBubble > 0 ? maxBubble : 1;
3889
4173
  const magnitude = Math.abs(sizeVal);
3890
- const ratio = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
4174
+ const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
3891
4175
  return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
3892
4176
  }
3893
4177
  function maxBubbleSize(sizes) {
@@ -3993,10 +4277,10 @@ function squarify(nodes, box) {
3993
4277
 
3994
4278
  // chart/hierarchy.ts
3995
4279
  function normalizeLevels(levels, pointCount) {
3996
- return levels.map((level) => {
4280
+ return levels.map((level2) => {
3997
4281
  let previous = "";
3998
4282
  return Array.from({ length: pointCount }, (_, index) => {
3999
- const label = level[index]?.trim() ?? "";
4283
+ const label = level2[index]?.trim() ?? "";
4000
4284
  if (label) previous = label;
4001
4285
  return label || previous;
4002
4286
  });
@@ -4154,12 +4438,12 @@ function computeSunburstArcs(series, cx, cy, maxR) {
4154
4438
  });
4155
4439
  return out;
4156
4440
  }
4157
- function hierarchyKey(levels, level, index) {
4158
- return levels.slice(level).map((labels) => labels[index] ?? "").join("\0");
4441
+ function hierarchyKey(levels, level2, index) {
4442
+ return levels.slice(level2).map((labels) => labels[index] ?? "").join("\0");
4159
4443
  }
4160
4444
  function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
4161
- const levels = categoryLevels.filter((level) => level.length > 0);
4162
- const leafCount = Math.max(values.length, ...levels.map((level) => level.length), 0);
4445
+ const levels = categoryLevels.filter((level2) => level2.length > 0);
4446
+ const leafCount = Math.max(values.length, ...levels.map((level2) => level2.length), 0);
4163
4447
  if (levels.length === 0 || leafCount === 0) return [];
4164
4448
  const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
4165
4449
  const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
@@ -4170,15 +4454,15 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
4170
4454
  const rootLabels = levels[levels.length - 1] ?? [];
4171
4455
  const rootColors = /* @__PURE__ */ new Map();
4172
4456
  const out = [];
4173
- for (let level = levels.length - 1; level >= 0; level--) {
4174
- const ringIndex = levels.length - 1 - level;
4457
+ for (let level2 = levels.length - 1; level2 >= 0; level2--) {
4458
+ const ringIndex = levels.length - 1 - level2;
4175
4459
  const innerRadius = ringWidth * (ringIndex + 0.5);
4176
4460
  const outerRadius = ringWidth * (ringIndex + 1.5);
4177
4461
  let start = 0;
4178
4462
  while (start < leafCount) {
4179
- const key = hierarchyKey(levels, level, start);
4463
+ const key = hierarchyKey(levels, level2, start);
4180
4464
  let end = start + 1;
4181
- while (end < leafCount && hierarchyKey(levels, level, end) === key) end++;
4465
+ while (end < leafCount && hierarchyKey(levels, level2, end) === key) end++;
4182
4466
  const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total * Math.PI * 2;
4183
4467
  const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total * Math.PI * 2;
4184
4468
  const rootLabel = rootLabels[start] ?? "";
@@ -4188,8 +4472,8 @@ function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
4188
4472
  colorIndex: rootColors.get(rootLabel) ?? start,
4189
4473
  opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
4190
4474
  level: ringIndex,
4191
- label: levels[level]?.[start] ?? "",
4192
- ...level === 0 && end === start + 1 ? { pointIndex: start } : {},
4475
+ label: levels[level2]?.[start] ?? "",
4476
+ ...level2 === 0 && end === start + 1 ? { pointIndex: start } : {},
4193
4477
  ...arcLabelPlacement(cx, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
4194
4478
  });
4195
4479
  start = end;
@@ -4215,14 +4499,14 @@ function scottBinCount(values, min, max) {
4215
4499
  const width = 3.49 * sd * values.length ** (-1 / 3);
4216
4500
  return Math.max(1, Math.ceil((max - min) / width));
4217
4501
  }
4218
- function computeHistogramBins(values, options, format = String) {
4219
- const closed = options.intervalClosed ?? "l";
4502
+ function computeHistogramBins(values, options2, format = String) {
4503
+ const closed = options2.intervalClosed ?? "l";
4220
4504
  const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
4221
4505
  if (finite2.length === 0) {
4222
4506
  return [];
4223
4507
  }
4224
- const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
4225
- const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
4508
+ const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
4509
+ const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
4226
4510
  const under = underflow === void 0 ? [] : finite2.filter(
4227
4511
  (item) => closed === "r" ? item.value <= underflow : item.value < underflow
4228
4512
  );
@@ -4239,8 +4523,8 @@ function computeHistogramBins(values, options, format = String) {
4239
4523
  if (regular.length > 0) {
4240
4524
  const min = Math.min(...regular.map((item) => item.value));
4241
4525
  const max = Math.max(...regular.map((item) => item.value));
4242
- const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
4243
- const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
4526
+ const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
4527
+ const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
4244
4528
  const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
4245
4529
  const count = requestedSize ? Math.max(
4246
4530
  closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
@@ -4291,9 +4575,9 @@ function aggregateByCategory(values, rawCategories) {
4291
4575
  }
4292
4576
 
4293
4577
  // chart/waterfall.ts
4294
- function buildWaterfallSteps(values, options) {
4578
+ function buildWaterfallSteps(values, options2) {
4295
4579
  const subtotalIndices = new Set(
4296
- options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
4580
+ options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
4297
4581
  );
4298
4582
  const steps = [];
4299
4583
  let runningTotal = 0;
@@ -4353,13 +4637,13 @@ var noFit = () => ({
4353
4637
  rSquared: 0,
4354
4638
  coefficients: []
4355
4639
  });
4356
- function fitModel(options, xVals, yVals) {
4640
+ function fitModel(options2, xVals, yVals) {
4357
4641
  const xs = [...xVals];
4358
4642
  const ys = [...yVals];
4359
- switch (options.kind) {
4643
+ switch (options2.kind) {
4360
4644
  case "linear": {
4361
4645
  const reg = computeLinearRegression(xs, ys);
4362
- const fixed = options.intercept;
4646
+ const fixed = options2.intercept;
4363
4647
  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;
4364
4648
  const b = fixed ?? reg.intercept;
4365
4649
  return {
@@ -4409,7 +4693,7 @@ function fitModel(options, xVals, yVals) {
4409
4693
  };
4410
4694
  }
4411
4695
  case "polynomial": {
4412
- const order = Math.min(options.order ?? 2, 6);
4696
+ const order = Math.min(options2.order ?? 2, 6);
4413
4697
  const coeffs = fitPolynomial(xs, ys, order);
4414
4698
  const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
4415
4699
  return {
@@ -4423,11 +4707,11 @@ function fitModel(options, xVals, yVals) {
4423
4707
  return void 0;
4424
4708
  }
4425
4709
  }
4426
- function fitChartTrendline(options, xVals, yVals) {
4710
+ function fitChartTrendline(options2, xVals, yVals) {
4427
4711
  const count = yVals.length;
4428
4712
  if (count < 2) return noFit();
4429
- if (options.kind === "movingAvg") {
4430
- const period = options.period ?? 2;
4713
+ if (options2.kind === "movingAvg") {
4714
+ const period = options2.period ?? 2;
4431
4715
  const points2 = [];
4432
4716
  for (let i = period - 1; i < count; i++) {
4433
4717
  let sum = 0;
@@ -4436,10 +4720,10 @@ function fitChartTrendline(options, xVals, yVals) {
4436
4720
  }
4437
4721
  return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
4438
4722
  }
4439
- const model = fitModel(options, xVals, yVals);
4723
+ const model = fitModel(options2, xVals, yVals);
4440
4724
  if (!model) return noFit();
4441
- const startX = Math.min(...xVals) - (options.backward ?? 0);
4442
- const endX = Math.max(...xVals) + (options.forward ?? 0);
4725
+ const startX = Math.min(...xVals) - (options2.backward ?? 0);
4726
+ const endX = Math.max(...xVals) + (options2.forward ?? 0);
4443
4727
  const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
4444
4728
  const points = [];
4445
4729
  for (let step = 0; step <= steps; step++) {
@@ -4462,19 +4746,78 @@ function chartSampleVariance(values) {
4462
4746
  const mean = values.reduce((sum, value) => sum + value, 0) / count;
4463
4747
  return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
4464
4748
  }
4465
- function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
4466
- switch (options.valueType) {
4749
+ function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
4750
+ switch (options2.valueType) {
4467
4751
  case "fixedVal":
4468
- return options.value ?? 0;
4752
+ return options2.value ?? 0;
4469
4753
  case "percentage":
4470
- return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
4754
+ return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
4471
4755
  case "stdDev":
4472
- return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
4756
+ return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
4473
4757
  case "stdErr":
4474
4758
  return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
4475
4759
  case "cust":
4476
- return side === "plus" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
4760
+ return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
4761
+ }
4762
+ }
4763
+
4764
+ // chart/pie-best-fit.ts
4765
+ var PX_PER_PT = 4 / 3;
4766
+ var BEST_FIT_RIM_INSET = 4 * PX_PER_PT;
4767
+ var BEST_FIT_EDGE_TOLERANCE = 1.5 * PX_PER_PT;
4768
+ var BEST_FIT_OUTSIDE_GAP = 2 * PX_PER_PT;
4769
+ function farCorner(x, y, w, h) {
4770
+ return Math.hypot(Math.abs(x) + w / 2, Math.abs(y) + h / 2);
4771
+ }
4772
+ function insideDistance(ux, uy, w, h, limit) {
4773
+ if (farCorner(0, 0, w, h) > limit) {
4774
+ return void 0;
4775
+ }
4776
+ let lo = 0;
4777
+ let hi = limit;
4778
+ for (let i = 0; i < 40; i++) {
4779
+ const mid = (lo + hi) / 2;
4780
+ if (farCorner(mid * ux, mid * uy, w, h) > limit) {
4781
+ hi = mid;
4782
+ } else {
4783
+ lo = mid;
4784
+ }
4785
+ }
4786
+ return lo;
4787
+ }
4788
+ function edgeOverhang(x, y, w, h, slice) {
4789
+ let worst = Number.NEGATIVE_INFINITY;
4790
+ const corners = [
4791
+ [-w / 2, -h / 2],
4792
+ [w / 2, -h / 2],
4793
+ [-w / 2, h / 2],
4794
+ [w / 2, h / 2]
4795
+ ];
4796
+ for (const [dx, dy] of corners) {
4797
+ const px = x + dx;
4798
+ const py = y + dy;
4799
+ const fromStart = Math.cos(slice.startAngle) * py - Math.sin(slice.startAngle) * px;
4800
+ const fromEnd = Math.sin(slice.endAngle) * px - Math.cos(slice.endAngle) * py;
4801
+ worst = Math.max(worst, -fromStart, -fromEnd);
4477
4802
  }
4803
+ return worst;
4804
+ }
4805
+ function placeBestFitLabel(slice, w, h) {
4806
+ const mid = (slice.startAngle + slice.endAngle) / 2;
4807
+ const ux = Math.cos(mid);
4808
+ const uy = Math.sin(mid);
4809
+ const distance = insideDistance(ux, uy, w, h, slice.outerR - BEST_FIT_RIM_INSET);
4810
+ if (distance !== void 0) {
4811
+ const x = distance * ux;
4812
+ const y = distance * uy;
4813
+ const reflex = slice.endAngle - slice.startAngle >= Math.PI;
4814
+ if (reflex || edgeOverhang(x, y, w, h, slice) <= BEST_FIT_EDGE_TOLERANCE) {
4815
+ return { x: slice.cx + x, y: slice.cy + y, inside: true };
4816
+ }
4817
+ }
4818
+ const extent = Math.abs(ux) * w / 2 + Math.abs(uy) * h / 2;
4819
+ const outside = slice.outerR + BEST_FIT_OUTSIDE_GAP + extent;
4820
+ return { x: slice.cx + outside * ux, y: slice.cy + outside * uy, inside: false };
4478
4821
  }
4479
4822
 
4480
4823
  // chart/color-palettes.ts
@@ -4835,6 +5178,191 @@ function drawingLineXml(line2) {
4835
5178
  return buildXml(doc);
4836
5179
  }
4837
5180
 
5181
+ // chart/marker-shape.ts
5182
+ var CHART_PX_PER_PT = 4 / 3;
5183
+ var DEFAULT_MARKER_OUTLINE_PT = 0.75;
5184
+ var AUTOMATIC_MARKER_CYCLE = [
5185
+ "diamond",
5186
+ "square",
5187
+ "triangle",
5188
+ "x",
5189
+ "star",
5190
+ "circle",
5191
+ "plus",
5192
+ "dot",
5193
+ "dash"
5194
+ ];
5195
+ function automaticMarkerSymbol(seriesIdx) {
5196
+ const length = AUTOMATIC_MARKER_CYCLE.length;
5197
+ const normalized = (Math.trunc(seriesIdx) % length + length) % length;
5198
+ return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
5199
+ }
5200
+ function markerRadius(size, defaultRadius) {
5201
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
5202
+ return defaultRadius;
5203
+ }
5204
+ return size / 2;
5205
+ }
5206
+ function polygonPoints(vertices) {
5207
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
5208
+ }
5209
+ function starVertices(cx, cy, r) {
5210
+ const inner = r * 0.5;
5211
+ const out = [];
5212
+ for (let i = 0; i < 10; i++) {
5213
+ const radius = i % 2 === 0 ? r : inner;
5214
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
5215
+ out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
5216
+ }
5217
+ return out;
5218
+ }
5219
+ function rectPolygon(x, y, w, h) {
5220
+ return polygonPoints([
5221
+ [x, y],
5222
+ [x + w, y],
5223
+ [x + w, y + h],
5224
+ [x, y + h]
5225
+ ]);
5226
+ }
5227
+ function buildMarkerPrimitive(input) {
5228
+ const { symbol, cx, cy, fill } = input;
5229
+ const part = input.part === void 0 ? {} : { part: input.part };
5230
+ if (symbol === "none") {
5231
+ return null;
5232
+ }
5233
+ const r = markerRadius(input.size, input.defaultRadius);
5234
+ const outline2 = input.stroke ? {
5235
+ stroke: input.stroke,
5236
+ strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
5237
+ } : void 0;
5238
+ const polygonStroke = outline2 ?? { stroke: fill, strokeWidth: 0 };
5239
+ const lineStroke = input.stroke ?? fill;
5240
+ switch (symbol) {
5241
+ case "square":
5242
+ case "dash": {
5243
+ const h = symbol === "dash" ? r * 0.64 : r * 2;
5244
+ const y = cy - h / 2;
5245
+ if (outline2) {
5246
+ return {
5247
+ kind: "polygon",
5248
+ points: rectPolygon(cx - r, y, r * 2, h),
5249
+ fill,
5250
+ ...outline2,
5251
+ ...part
5252
+ };
5253
+ }
5254
+ return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
5255
+ }
5256
+ case "diamond":
5257
+ return {
5258
+ kind: "polygon",
5259
+ points: polygonPoints([
5260
+ [cx, cy - r],
5261
+ [cx + r, cy],
5262
+ [cx, cy + r],
5263
+ [cx - r, cy]
5264
+ ]),
5265
+ fill,
5266
+ ...polygonStroke,
5267
+ ...part
5268
+ };
5269
+ case "triangle":
5270
+ return {
5271
+ kind: "polygon",
5272
+ points: polygonPoints([
5273
+ [cx, cy - r],
5274
+ [cx + r * 0.9, cy + r * 0.75],
5275
+ [cx - r * 0.9, cy + r * 0.75]
5276
+ ]),
5277
+ fill,
5278
+ ...polygonStroke,
5279
+ ...part
5280
+ };
5281
+ case "star":
5282
+ return {
5283
+ kind: "polygon",
5284
+ points: polygonPoints(starVertices(cx, cy, r)),
5285
+ fill,
5286
+ ...polygonStroke,
5287
+ ...part
5288
+ };
5289
+ case "plus":
5290
+ return {
5291
+ kind: "path",
5292
+ 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)}`,
5293
+ fill: "none",
5294
+ stroke: lineStroke,
5295
+ strokeWidth: Math.max(1, r * 0.4),
5296
+ ...part
5297
+ };
5298
+ case "x":
5299
+ return {
5300
+ kind: "path",
5301
+ 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)}`,
5302
+ fill: "none",
5303
+ stroke: lineStroke,
5304
+ strokeWidth: Math.max(1, r * 0.4),
5305
+ ...part
5306
+ };
5307
+ case "dot":
5308
+ return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline2 };
5309
+ default:
5310
+ return { kind: "circle", cx, cy, r, fill, ...part, ...outline2 };
5311
+ }
5312
+ }
5313
+
5314
+ // chart/render/chart-view-markers.ts
5315
+ function summaryMarkers(source, group2, seriesPosition) {
5316
+ if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
5317
+ const enabled2 = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
5318
+ const symbol = source.marker?.symbol;
5319
+ const marker = {
5320
+ ...source.marker,
5321
+ symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled2 ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
5322
+ };
5323
+ const pointMarkers = {};
5324
+ for (const point of source.dataPoints) {
5325
+ if (point.index === void 0 || !point.marker) continue;
5326
+ const override = point.marker;
5327
+ pointMarkers[point.index] = {
5328
+ ...marker,
5329
+ ...override,
5330
+ ...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
5331
+ ...marker.spPr || override.spPr ? {
5332
+ spPr: {
5333
+ ...marker.spPr,
5334
+ ...override.spPr,
5335
+ ...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
5336
+ }
5337
+ } : {}
5338
+ };
5339
+ }
5340
+ return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
5341
+ }
5342
+ function seriesMarkerViews(source, drawingColor) {
5343
+ const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
5344
+ const resolve = (marker) => {
5345
+ const fill = fillColor(marker.spPr?.fill);
5346
+ const stroke = fillColor(marker.spPr?.line?.fill);
5347
+ const width = marker.spPr?.line?.widthEmu;
5348
+ return {
5349
+ ...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
5350
+ ...marker.size !== void 0 ? { size: marker.size } : {},
5351
+ ...fill !== void 0 ? { fill } : {},
5352
+ ...stroke !== void 0 ? { stroke } : {},
5353
+ ...width !== void 0 ? { strokeWidth: width / 9525 } : {}
5354
+ };
5355
+ };
5356
+ return {
5357
+ ...source.marker ? { marker: resolve(source.marker) } : {},
5358
+ ...source.pointMarkers ? {
5359
+ pointMarkers: Object.fromEntries(
5360
+ Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
5361
+ )
5362
+ } : {}
5363
+ };
5364
+ }
5365
+
4838
5366
  // chart/render/summary-analysis.ts
4839
5367
  function summaryTrendline(source) {
4840
5368
  const kind = chartTrendlineKind(source.trendlineType);
@@ -4875,6 +5403,41 @@ function summaryAnalysis(series) {
4875
5403
  };
4876
5404
  }
4877
5405
 
5406
+ // chart/render/summary-labels.ts
5407
+ function level(options2, custom) {
5408
+ const out = {};
5409
+ if (options2.deleted !== void 0) out.deleted = options2.deleted;
5410
+ if (options2.showValue !== void 0) out.showValue = options2.showValue;
5411
+ if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
5412
+ if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
5413
+ if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
5414
+ if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
5415
+ if (options2.separator !== void 0) out.separator = options2.separator;
5416
+ if (options2.position) out.position = options2.position;
5417
+ if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
5418
+ if (custom?.text !== void 0) out.text = custom.text;
5419
+ return out;
5420
+ }
5421
+ function shows(levels, point) {
5422
+ const flags = resolveDataLabelFlags({ ...levels, ...point ? { point } : {} });
5423
+ return point?.text !== void 0 || Object.values(flags).some((value) => value === true);
5424
+ }
5425
+ function summaryDataLabels(series, group2) {
5426
+ const own2 = series.dataLabels;
5427
+ if (!own2 && !group2) return void 0;
5428
+ const out = {};
5429
+ if (group2) out.chart = level(group2);
5430
+ if (own2) out.series = level(own2);
5431
+ const points = {};
5432
+ for (const labels of [group2, own2])
5433
+ for (const label of labels?.labels ?? [])
5434
+ if (label.index !== void 0)
5435
+ points[label.index] = { ...points[label.index], ...level(label, label.tx) };
5436
+ if (Object.keys(points).length) out.points = points;
5437
+ if (!shows(out) && !Object.values(points).some((point) => shows(out, point))) return void 0;
5438
+ return out;
5439
+ }
5440
+
4878
5441
  // chart/render/summary-from-space.ts
4879
5442
  var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
4880
5443
  var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
@@ -4892,7 +5455,7 @@ var GROUP_TYPES = {
4892
5455
  surface: "surface"
4893
5456
  };
4894
5457
  var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked", "standard"]);
4895
- function chartSummarySeries(source, chartType) {
5458
+ function chartSummarySeries(source, chartType, groupLabels) {
4896
5459
  const categories = source.categories ?? source.xValues;
4897
5460
  const values = source.values ?? source.yValues;
4898
5461
  const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
@@ -4900,6 +5463,7 @@ function chartSummarySeries(source, chartType) {
4900
5463
  categories: chartSourceValues(categories),
4901
5464
  values: chartSourceValues(values).map(numeric)
4902
5465
  };
5466
+ if (values?.cache?.formatCode !== void 0) out.numberFormat = values.cache.formatCode;
4903
5467
  if (source.bubbleSizes) {
4904
5468
  out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
4905
5469
  if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
@@ -4928,6 +5492,8 @@ function chartSummarySeries(source, chartType) {
4928
5492
  }
4929
5493
  if (Object.keys(points).length) out.pointColors = points;
4930
5494
  if (Object.keys(pointFills).length) out.pointFills = pointFills;
5495
+ const dataLabels = summaryDataLabels(source, groupLabels);
5496
+ if (dataLabels) out.dataLabels = dataLabels;
4931
5497
  Object.assign(out, summaryAnalysis(source));
4932
5498
  return out;
4933
5499
  }
@@ -4936,12 +5502,12 @@ function valueAxisId(chartSpace, axisIds) {
4936
5502
  (id) => chartSpace.plotArea.axes.some((a) => a.id === id && a.kind === "val")
4937
5503
  );
4938
5504
  }
4939
- function stockStyle(group) {
5505
+ function stockStyle(group2) {
4940
5506
  return {
4941
- ...group.hiLowLinesSpPr ? { hiLowLines: group.hiLowLinesSpPr } : {},
4942
- ...group.upBars?.spPr ? { upBars: group.upBars.spPr } : {},
4943
- ...group.downBars?.spPr ? { downBars: group.downBars.spPr } : {},
4944
- ...group.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group.upDownBarsGapWidth }
5507
+ ...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
5508
+ ...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
5509
+ ...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
5510
+ ...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
4945
5511
  };
4946
5512
  }
4947
5513
  function extraGroups(chartSpace, firstType) {
@@ -4949,54 +5515,62 @@ function extraGroups(chartSpace, firstType) {
4949
5515
  if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
4950
5516
  const primary = valueAxisId(chartSpace, first3.axisIds);
4951
5517
  const out = [];
4952
- for (const group of rest) {
4953
- const stockOverColumns = group.kind === "stock" && firstType === "column";
4954
- if (group.is3D || !(["bar", "line", "area"].includes(group.kind) || stockOverColumns)) continue;
4955
- const type = group.kind === "bar" ? "column" : group.kind;
5518
+ for (const group2 of rest) {
5519
+ const stockOverColumns = group2.kind === "stock" && firstType === "column";
5520
+ if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
5521
+ const type = group2.kind === "bar" ? "column" : group2.kind;
4956
5522
  const entry = {
4957
5523
  chartType: type,
4958
- series: group.series.map((source) => chartSummarySeries(source, type)),
4959
- secondary: valueAxisId(chartSpace, group.axisIds) !== primary
5524
+ series: group2.series.map((source, index) => ({
5525
+ ...chartSummarySeries(source, type, group2.dataLabels),
5526
+ ...summaryMarkers(source, group2, index)
5527
+ })),
5528
+ secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
4960
5529
  };
4961
- if (group.grouping && GROUPINGS.has(group.grouping))
4962
- entry.grouping = group.grouping;
4963
- if (type === "stock") entry.stock = stockStyle(group);
5530
+ if (group2.grouping && GROUPINGS.has(group2.grouping))
5531
+ entry.grouping = group2.grouping;
5532
+ if (type === "stock") entry.stock = stockStyle(group2);
4964
5533
  if (type === "column") {
4965
- if (group.gapWidth !== void 0) entry.barGapWidth = group.gapWidth;
4966
- if (group.overlap !== void 0) entry.barOverlap = group.overlap;
5534
+ if (group2.gapWidth !== void 0) entry.barGapWidth = group2.gapWidth;
5535
+ if (group2.overlap !== void 0) entry.barOverlap = group2.overlap;
4967
5536
  }
4968
5537
  if (entry.series.length) out.push(entry);
4969
5538
  }
4970
5539
  return out;
4971
5540
  }
4972
5541
  function chartSummaryFromSpace(chartSpace, extras = {}) {
4973
- const group = chartSpace.plotArea.groups[0];
4974
- let chartType = group ? GROUP_TYPES[group.kind] : "column";
4975
- if (chartType === "bar" && group?.barDirection !== "bar") chartType = "column";
4976
- const series = (group?.series ?? []).map((source) => chartSummarySeries(source, chartType));
5542
+ const group2 = chartSpace.plotArea.groups[0];
5543
+ let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
5544
+ if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
5545
+ const series = (group2?.series ?? []).map((source, index) => ({
5546
+ ...chartSummarySeries(source, chartType, group2?.dataLabels),
5547
+ ...group2 ? summaryMarkers(source, group2, index) : {}
5548
+ }));
4977
5549
  const summary = {
4978
5550
  chartType,
4979
5551
  series,
4980
- showLegend: chartSpace.legend !== void 0
5552
+ showLegend: chartSpace.legend !== void 0,
5553
+ axes: chartSpace.plotArea.axes,
5554
+ axisIds: group2?.axisIds ?? []
4981
5555
  };
4982
5556
  const combined = extraGroups(chartSpace, chartType);
4983
5557
  if (combined.length) summary.extraGroups = combined;
4984
- if (chartType === "stock" && group) summary.stock = stockStyle(group);
4985
- if (chartType === "bubble" && group) {
4986
- const sizeRepresents = group.sizeRepresents === "w" ? "w" : "area";
5558
+ if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
5559
+ if (chartType === "bubble" && group2) {
5560
+ const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
4987
5561
  summary.bubble = {
4988
5562
  sizeRepresents,
4989
- ...group.bubbleScale === void 0 ? {} : { bubbleScale: group.bubbleScale },
4990
- showNegativeBubbles: group.showNegativeBubbles === true
5563
+ ...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
5564
+ showNegativeBubbles: group2.showNegativeBubbles === true
4991
5565
  };
4992
5566
  }
4993
- const grouping = group?.grouping;
5567
+ const grouping = group2?.grouping;
4994
5568
  if (grouping && GROUPINGS.has(grouping))
4995
5569
  summary.grouping = grouping;
4996
5570
  if (chartType === "bar" || chartType === "column") {
4997
5571
  for (const [value, field, fallback, min, max] of [
4998
- [group?.gapWidth, "barGapWidth", 150, 0, 500],
4999
- [group?.overlap, "barOverlap", 0, -100, 100]
5572
+ [group2?.gapWidth, "barGapWidth", 150, 0, 500],
5573
+ [group2?.overlap, "barOverlap", 0, -100, 100]
5000
5574
  ]) {
5001
5575
  const resolved = value ?? fallback;
5002
5576
  if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
@@ -5058,72 +5632,438 @@ function chartBarSpacing(chart) {
5058
5632
  };
5059
5633
  }
5060
5634
 
5061
- // chart/render/chart-svg-bars.ts
5062
- function barLayout(model, frame) {
5063
- const count = Math.max(1, model.series.length);
5064
- const geometry2 = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
5065
- const barSize = geometry2.singleBarWidth;
5066
- const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
5067
- return { barSize, offset };
5068
- }
5069
- function bars(model, frame, out, values) {
5070
- const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
5071
- const { barSize, offset: barOffset } = barLayout(model, frame);
5072
- const base = frame.value(0);
5073
- const pos = new Array(model.categories.length).fill(0);
5074
- const neg = new Array(model.categories.length).fill(0);
5075
- model.series.forEach((s, si) => {
5076
- values[si]?.forEach((v, i) => {
5077
- if (v === null || i >= model.categories.length) return;
5078
- let from = 0;
5079
- let to = v;
5080
- if (stacked) {
5081
- const acc = v >= 0 ? pos : neg;
5082
- from = acc[i] ?? 0;
5083
- to = from + v;
5084
- acc[i] = to;
5085
- }
5086
- const a = stacked ? frame.value(from) : base;
5087
- const b = frame.value(to);
5088
- const offset = barOffset(si);
5089
- const center = frame.band(i);
5090
- const width = model.horizontal ? Math.abs(b - a) : barSize;
5091
- const height = model.horizontal ? barSize : Math.abs(b - a);
5092
- let color = s.pointColors?.[i] ?? s.color;
5093
- const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
5094
- if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
5095
- const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
5096
- if (baseId) {
5097
- const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
5098
- const def = buildChartGradientDef(id, gradient, {
5099
- width: Number(n(width)),
5100
- height: Number(n(height)),
5101
- shape: "rect"
5102
- });
5103
- out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
5104
- color = `url(#${id})`;
5105
- }
5106
- }
5107
- out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
5108
- if (model.horizontal)
5109
- out.push(
5110
- rect(Math.min(a, b), center + offset, Math.abs(b - a), barSize, color, s.shadowFilter)
5111
- );
5112
- else
5113
- out.push(
5114
- rect(center + offset, Math.min(a, b), barSize, Math.abs(b - a), color, s.shadowFilter)
5115
- );
5116
- out.push("</g>");
5117
- });
5118
- });
5635
+ // chart/render/theme-palette.ts
5636
+ var THEME_SLOTS = [
5637
+ "lt1",
5638
+ "dk1",
5639
+ "lt2",
5640
+ "dk2",
5641
+ "accent1",
5642
+ "accent2",
5643
+ "accent3",
5644
+ "accent4",
5645
+ "accent5",
5646
+ "accent6",
5647
+ "hlink",
5648
+ "folHlink"
5649
+ ];
5650
+ var DEFAULT_THEME_COLORS = [
5651
+ "FFFFFF",
5652
+ "000000",
5653
+ "E7E6E6",
5654
+ "44546A",
5655
+ "4472C4",
5656
+ "ED7D31",
5657
+ "A5A5A5",
5658
+ "FFC000",
5659
+ "5B9BD5",
5660
+ "70AD47",
5661
+ "0563C1",
5662
+ "954F72"
5663
+ ];
5664
+ function themeColor(theme, index) {
5665
+ const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
5666
+ return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
5119
5667
  }
5120
5668
 
5121
- // chart/render/chart-svg-analysis.ts
5122
- var DASHES = {
5123
- dot: [1, 3],
5124
- dash: [4, 3],
5125
- lgDash: [8, 3],
5126
- dashDot: [4, 3, 1, 3],
5669
+ // chart/render/chart-colors.ts
5670
+ function chartColorScheme(theme) {
5671
+ const slots = Object.fromEntries(
5672
+ THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
5673
+ );
5674
+ return {
5675
+ ...slots,
5676
+ bg1: slots.lt1,
5677
+ tx1: slots.dk1,
5678
+ bg2: slots.lt2,
5679
+ tx2: slots.dk2
5680
+ };
5681
+ }
5682
+ function autoSeriesColor(theme, index) {
5683
+ const i = Math.max(0, Math.floor(index));
5684
+ return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
5685
+ }
5686
+
5687
+ // chart/text-inheritance.ts
5688
+ var TEXT_KEYS = [
5689
+ "fontSize",
5690
+ "bold",
5691
+ "italic",
5692
+ "underline",
5693
+ "typeface",
5694
+ "textColor",
5695
+ "fontRef"
5696
+ ];
5697
+ var TEXT_PARTS = [
5698
+ "title",
5699
+ "axisTitle",
5700
+ "categoryAxis",
5701
+ "valueAxis",
5702
+ "legend",
5703
+ "dataLabel"
5704
+ ];
5705
+ function inheritChartText(part, entry, builtIn, root) {
5706
+ if (!root || !TEXT_PARTS.includes(part)) return entry;
5707
+ const out = { ...entry };
5708
+ for (const key of TEXT_KEYS) {
5709
+ delete out[key];
5710
+ const value = root[key] ?? builtIn?.[key];
5711
+ if (value !== void 0) Object.assign(out, { [key]: value });
5712
+ }
5713
+ if (part === "title" && root.fontSize !== void 0) out.fontSize = root.fontSize * 1.2;
5714
+ if (root.textEffectsXml !== void 0) out.textEffectsXml = root.textEffectsXml;
5715
+ return out;
5716
+ }
5717
+
5718
+ // chart/render/chart-appearance.ts
5719
+ var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
5720
+ function typeface(entry, theme) {
5721
+ const name = entry.typeface;
5722
+ if (name?.startsWith("+mj-")) return theme.majorFont;
5723
+ if (name?.startsWith("+mn-")) return theme.minorFont;
5724
+ return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
5725
+ }
5726
+ function chartAppearance(chart, theme) {
5727
+ const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
5728
+ const entries = {};
5729
+ for (const part of CHART_STYLE_PARTS) {
5730
+ const base = chart.styleDefinition?.entries[part];
5731
+ const direct = chart.formatting?.entries[part];
5732
+ if (!defaults[part] && !base && !direct) continue;
5733
+ const entry = {
5734
+ ...inheritChartText(
5735
+ part,
5736
+ { ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
5737
+ defaults[part],
5738
+ chart.formatting?.textDefaults
5739
+ ),
5740
+ ...direct,
5741
+ sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
5742
+ };
5743
+ if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
5744
+ entries[part] = entry;
5745
+ }
5746
+ const scheme = chartColorScheme(theme);
5747
+ const resolve = (color) => resolveDrawingColor(
5748
+ color,
5749
+ { scheme: (name) => scheme[name] },
5750
+ { hslRounding: "halfDown", transformOrder: "document" }
5751
+ );
5752
+ const out = resolveChartStyleDefinition(
5753
+ { entries},
5754
+ (color) => drawingColorCss(resolve(color))
5755
+ ) ?? {};
5756
+ for (const part of CHART_STYLE_PARTS) {
5757
+ const entry = entries[part];
5758
+ if (!entry) continue;
5759
+ const family = typeface(entry, theme);
5760
+ const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
5761
+ scheme: (name) => scheme[name]
5762
+ });
5763
+ if (shadow) (out[part] ??= {}).textShadow = shadow;
5764
+ if (family) (out[part] ??= {}).typeface = family;
5765
+ if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
5766
+ if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
5767
+ if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
5768
+ if (entry.fill?.kind === "gradient") {
5769
+ (out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
5770
+ }
5771
+ }
5772
+ return out;
5773
+ }
5774
+
5775
+ // text/css-font-family.ts
5776
+ var FALLBACKS = {
5777
+ calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5778
+ "calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5779
+ cambria: '"Cambria", "Caladea", Georgia, serif',
5780
+ arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
5781
+ "times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
5782
+ "courier new": '"Courier New", "Liberation Mono", monospace',
5783
+ aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
5784
+ };
5785
+ function cssFontFamily(name) {
5786
+ const known = FALLBACKS[name.toLowerCase()];
5787
+ if (known) return known;
5788
+ const quoted = `"${name.replace(/["\\]/g, "")}"`;
5789
+ return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
5790
+ }
5791
+
5792
+ // chart/render/chart-svg-appearance.ts
5793
+ var nextPaintId = 0;
5794
+ function chartGradientPaint(model, width = 1024, height = 768) {
5795
+ const prefix = `xlsx-chart-${++nextPaintId}`;
5796
+ const appearance = { ...model.appearance };
5797
+ const defs = [];
5798
+ const shadowPaint = (shadow, suffix) => {
5799
+ const id = `${prefix}-${suffix}`;
5800
+ const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
5801
+ defs.push(
5802
+ `<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>`
5803
+ );
5804
+ return `url(#${id})`;
5805
+ };
5806
+ for (const [part, entry] of Object.entries(appearance)) {
5807
+ if (entry?.textShadow)
5808
+ appearance[part] = {
5809
+ ...entry,
5810
+ textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
5811
+ };
5812
+ }
5813
+ const paint2 = (gradient, suffix, bounds) => {
5814
+ const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
5815
+ defs.push(chartGradientMarkup(def));
5816
+ return `url(#${def.id})`;
5817
+ };
5818
+ for (const part of ["chartArea", "plotArea"]) {
5819
+ const entry = appearance[part];
5820
+ if (!entry?.gradient) continue;
5821
+ if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
5822
+ appearance[part] = {
5823
+ ...entry,
5824
+ fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
5825
+ };
5826
+ }
5827
+ const series = model.series.map((source, index) => {
5828
+ const view = { ...source };
5829
+ if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
5830
+ const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
5831
+ if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
5832
+ if (source.pointGradients) {
5833
+ view.pointColors = [...source.pointColors ?? []];
5834
+ for (const [key, gradient] of Object.entries(source.pointGradients))
5835
+ view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
5836
+ }
5837
+ return view;
5838
+ });
5839
+ return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
5840
+ }
5841
+ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
5842
+ const entry = model.appearance?.[part];
5843
+ return {
5844
+ size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
5845
+ ...entry?.color === void 0 ? {} : { fill: entry.color },
5846
+ ...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
5847
+ ...entry?.italic === void 0 ? {} : { italic: entry.italic },
5848
+ ...entry?.underline === void 0 ? {} : { underline: entry.underline },
5849
+ ...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
5850
+ ...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
5851
+ };
5852
+ }
5853
+ function chartStroke(model, part) {
5854
+ const entry = model.appearance?.[part];
5855
+ return {
5856
+ color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
5857
+ width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
5858
+ };
5859
+ }
5860
+ function chartAreaRect(model, part, area) {
5861
+ if (area.w <= 0 || area.h <= 0) return "";
5862
+ const entry = model.appearance?.[part];
5863
+ let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
5864
+ let defs = "";
5865
+ if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
5866
+ const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
5867
+ width: area.w,
5868
+ height: area.h,
5869
+ shape: "rect"
5870
+ });
5871
+ defs = `<defs>${chartGradientMarkup(def)}</defs>`;
5872
+ fill = `url(#${def.id})`;
5873
+ }
5874
+ const stroke = entry?.lineColor ?? "none";
5875
+ if (fill === "none" && stroke === "none") return "";
5876
+ const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
5877
+ 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}"/>`;
5878
+ }
5879
+
5880
+ // chart/render/chart-svg-labels.ts
5881
+ var GAP = 3;
5882
+ var LINE = 1.2;
5883
+ var NAMED_COLORS = /^(black|blue|cyan|green|magenta|red|white|yellow)$/iu;
5884
+ function measure(model, label) {
5885
+ const attrs2 = chartTextAttributes(model, "dataLabel", 10);
5886
+ const size = attrs2.size ?? 10;
5887
+ const lines = label.text.split("\n");
5888
+ return {
5889
+ lines,
5890
+ size,
5891
+ w: Math.max(...lines.map((l) => textWidth(l, size))),
5892
+ h: lines.length * size * LINE,
5893
+ attrs: attrs2
5894
+ };
5895
+ }
5896
+ function draw(m, label, x, y, anchor, out) {
5897
+ const fill = label.color && NAMED_COLORS.test(label.color) ? label.color.toLowerCase() : void 0;
5898
+ m.lines.forEach((line2, k) => {
5899
+ const lineY = y - m.h / 2 + (k + 0.5) * m.size * LINE + m.size * 0.35;
5900
+ out.push(text(x, lineY, line2, { ...m.attrs, ...fill ? { fill } : {}, anchor }));
5901
+ });
5902
+ }
5903
+ function barLabels(model, marks, out) {
5904
+ const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
5905
+ for (const mark of marks) {
5906
+ const label = mark.series.labels?.[mark.index];
5907
+ if (!label) continue;
5908
+ const m = measure(model, label);
5909
+ let position2 = label.position ?? (stacked ? "ctr" : "outEnd");
5910
+ if (stacked && position2 === "outEnd") position2 = "ctr";
5911
+ const cx = mark.x + mark.w / 2;
5912
+ const cy = mark.y + mark.h / 2;
5913
+ if (model.horizontal) {
5914
+ const end = mark.negative ? mark.x : mark.x + mark.w;
5915
+ const base = mark.negative ? mark.x + mark.w : mark.x;
5916
+ const dir2 = mark.negative ? -1 : 1;
5917
+ const side = (at, outward) => [
5918
+ at + (outward ? dir2 : -dir2) * GAP,
5919
+ (outward ? dir2 : -dir2) > 0 ? "start" : "end"
5920
+ ];
5921
+ const [x, anchor] = position2 === "ctr" ? [cx, "middle"] : position2 === "inEnd" ? side(end, false) : position2 === "inBase" ? side(base, true) : side(end, true);
5922
+ draw(m, label, x, cy, anchor, out);
5923
+ continue;
5924
+ }
5925
+ const top = mark.negative ? mark.y + mark.h : mark.y;
5926
+ const bottom = mark.negative ? mark.y : mark.y + mark.h;
5927
+ const dir = mark.negative ? 1 : -1;
5928
+ const y = position2 === "ctr" ? cy : position2 === "inEnd" ? top - dir * (GAP + m.h / 2) : position2 === "inBase" ? bottom + dir * (GAP + m.h / 2) : top + dir * (GAP + m.h / 2);
5929
+ draw(m, label, cx, y, "middle", out);
5930
+ }
5931
+ }
5932
+ function pointLabels(model, marks, out) {
5933
+ for (const mark of marks) {
5934
+ const label = mark.series.labels?.[mark.index];
5935
+ if (!label) continue;
5936
+ const m = measure(model, label);
5937
+ const reach = mark.radius + GAP;
5938
+ switch (model.type === "area" ? "ctr" : label.position ?? "r") {
5939
+ case "ctr":
5940
+ draw(m, label, mark.x, mark.y, "middle", out);
5941
+ break;
5942
+ case "t":
5943
+ draw(m, label, mark.x, mark.y - reach - m.h / 2, "middle", out);
5944
+ break;
5945
+ case "b":
5946
+ draw(m, label, mark.x, mark.y + reach + m.h / 2, "middle", out);
5947
+ break;
5948
+ case "l":
5949
+ draw(m, label, mark.x - reach, mark.y, "end", out);
5950
+ break;
5951
+ default:
5952
+ draw(m, label, mark.x + reach, mark.y, "start", out);
5953
+ }
5954
+ }
5955
+ }
5956
+ function sliceLabels(model, marks, out) {
5957
+ for (const mark of marks) {
5958
+ const label = mark.series.labels?.[mark.index];
5959
+ if (!label) continue;
5960
+ const m = measure(model, label);
5961
+ const mid = (mark.start + mark.end) / 2;
5962
+ const ux = Math.sin(mid);
5963
+ const uy = -Math.cos(mid);
5964
+ const place2 = (radius) => [
5965
+ mark.cx + radius * ux,
5966
+ mark.cy + radius * uy
5967
+ ];
5968
+ const position2 = model.type === "doughnut" ? "ctr" : label.position ?? "bestFit";
5969
+ let x;
5970
+ let y;
5971
+ if (position2 === "ctr") [x, y] = place2(mark.inner + (mark.outer - mark.inner) / 2);
5972
+ else if (position2 === "inEnd") {
5973
+ const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
5974
+ [x, y] = place2(Math.max(0, mark.outer - GAP - extent));
5975
+ } else if (position2 === "outEnd") {
5976
+ const extent = Math.abs(ux) * m.w / 2 + Math.abs(uy) * m.h / 2;
5977
+ [x, y] = place2(mark.outer + GAP + extent);
5978
+ } else {
5979
+ const placed = placeBestFitLabel(
5980
+ {
5981
+ cx: mark.cx,
5982
+ cy: mark.cy,
5983
+ outerR: mark.outer,
5984
+ startAngle: mark.start - Math.PI / 2,
5985
+ endAngle: mark.end - Math.PI / 2
5986
+ },
5987
+ m.w,
5988
+ m.h
5989
+ );
5990
+ x = placed.x;
5991
+ y = placed.y;
5992
+ }
5993
+ draw(m, label, x, y, "middle", out);
5994
+ }
5995
+ }
5996
+ function hasOutsideLabels(model) {
5997
+ return model.series.some(
5998
+ (s) => s.labels?.some(
5999
+ (l) => l !== void 0 && ["bestFit", "outEnd"].includes(l.position ?? "bestFit")
6000
+ )
6001
+ );
6002
+ }
6003
+
6004
+ // chart/render/chart-svg-bars.ts
6005
+ function barLayout(model, frame) {
6006
+ const count = Math.max(1, model.series.length);
6007
+ const geometry2 = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
6008
+ const barSize = geometry2.singleBarWidth;
6009
+ const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
6010
+ return { barSize, offset };
6011
+ }
6012
+ function bars(model, frame, out, values) {
6013
+ const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
6014
+ const { barSize, offset: barOffset } = barLayout(model, frame);
6015
+ const base = frame.value(0);
6016
+ const pos = new Array(model.categories.length).fill(0);
6017
+ const neg = new Array(model.categories.length).fill(0);
6018
+ const marks = [];
6019
+ model.series.forEach((s, si) => {
6020
+ values[si]?.forEach((v, i) => {
6021
+ if (v === null || i >= model.categories.length) return;
6022
+ let from = 0;
6023
+ let to = v;
6024
+ if (stacked) {
6025
+ const acc = v >= 0 ? pos : neg;
6026
+ from = acc[i] ?? 0;
6027
+ to = from + v;
6028
+ acc[i] = to;
6029
+ }
6030
+ const a = stacked ? frame.value(from) : base;
6031
+ const b = frame.value(to);
6032
+ const offset = barOffset(si);
6033
+ const center = frame.band(i);
6034
+ const width = model.horizontal ? Math.abs(b - a) : barSize;
6035
+ const height = model.horizontal ? barSize : Math.abs(b - a);
6036
+ let color = s.pointColors?.[i] ?? s.color;
6037
+ const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
6038
+ if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
6039
+ const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
6040
+ if (baseId) {
6041
+ const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
6042
+ const def = buildChartGradientDef(id, gradient, {
6043
+ width: Number(n(width)),
6044
+ height: Number(n(height)),
6045
+ shape: "rect"
6046
+ });
6047
+ out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
6048
+ color = `url(#${id})`;
6049
+ }
6050
+ }
6051
+ out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
6052
+ 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) };
6053
+ out.push(rect(box.x, box.y, box.w, box.h, color, s.shadowFilter));
6054
+ out.push("</g>");
6055
+ marks.push({ series: s, index: i, ...box, negative: v < 0 });
6056
+ });
6057
+ });
6058
+ barLabels(model, marks, out);
6059
+ }
6060
+
6061
+ // chart/render/chart-svg-analysis.ts
6062
+ var DASHES = {
6063
+ dot: [1, 3],
6064
+ dash: [4, 3],
6065
+ lgDash: [8, 3],
6066
+ dashDot: [4, 3, 1, 3],
5127
6067
  lgDashDot: [8, 3, 1, 3],
5128
6068
  lgDashDotDot: [8, 3, 1, 3, 1, 3],
5129
6069
  sysDash: [3, 1],
@@ -5204,6 +6144,60 @@ function scatterAnalysis(model, px, py, out) {
5204
6144
  });
5205
6145
  }
5206
6146
 
6147
+ // chart/render/chart-svg-markers.ts
6148
+ function chartMarkerRadius(series, index, defaultRadius = 3) {
6149
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
6150
+ if (marker.symbol === "none") return 0;
6151
+ const radius = markerRadius(marker.size, defaultRadius);
6152
+ return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
6153
+ }
6154
+ function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
6155
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
6156
+ const primitive = buildMarkerPrimitive({
6157
+ ...marker,
6158
+ symbol: marker.symbol,
6159
+ size: marker.size,
6160
+ cx,
6161
+ cy,
6162
+ fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
6163
+ defaultRadius
6164
+ });
6165
+ if (!primitive) return "";
6166
+ let geometry2;
6167
+ switch (primitive.kind) {
6168
+ case "circle":
6169
+ geometry2 = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
6170
+ break;
6171
+ case "rect":
6172
+ geometry2 = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
6173
+ break;
6174
+ case "path":
6175
+ geometry2 = `d="${esc(primitive.d)}"`;
6176
+ break;
6177
+ case "polygon":
6178
+ geometry2 = `points="${esc(primitive.points)}"`;
6179
+ break;
6180
+ }
6181
+ const outline2 = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
6182
+ const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
6183
+ return `<${primitive.kind} ${geometry2} fill="${esc(primitive.fill)}"${outline2}${filter}/>`;
6184
+ }
6185
+
6186
+ // chart/line-dash.ts
6187
+ function chartLineDashArray(style, width) {
6188
+ if (!style || style === "solid") {
6189
+ return void 0;
6190
+ }
6191
+ const unit = Math.max(width, 1);
6192
+ if (style === "dot" || style === "sysDot") {
6193
+ return `${unit} ${unit * 2}`;
6194
+ }
6195
+ if (style === "lgDash") {
6196
+ return `${unit * 6} ${unit * 3}`;
6197
+ }
6198
+ return `${unit * 3} ${unit * 2}`;
6199
+ }
6200
+
5207
6201
  // chart/render/chart-scale.ts
5208
6202
  var clean = (n2) => Number(n2.toPrecision(12));
5209
6203
  function* units(raw) {
@@ -5214,14 +6208,14 @@ function* units(raw) {
5214
6208
  exp++;
5215
6209
  }
5216
6210
  }
5217
- function niceScale(dataMin, dataMax, options = {}) {
5218
- const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
6211
+ function niceScale(dataMin, dataMax, options2 = {}) {
6212
+ const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
5219
6213
  let lo = Number.isFinite(dataMin) ? dataMin : 0;
5220
6214
  let hi = Number.isFinite(dataMax) ? dataMax : 0;
5221
6215
  if (lo > hi) [lo, hi] = [hi, lo];
5222
6216
  if (lo === hi) {
5223
6217
  if (lo === 0) hi = 1;
5224
- else if (options.noZero) {
6218
+ else if (options2.noZero) {
5225
6219
  const pad = Math.abs(lo) * 0.1 || 1;
5226
6220
  lo -= pad;
5227
6221
  hi += pad;
@@ -5230,7 +6224,7 @@ function niceScale(dataMin, dataMax, options = {}) {
5230
6224
  }
5231
6225
  let fixedLo = false;
5232
6226
  let fixedHi = false;
5233
- if (!options.noZero) {
6227
+ if (!options2.noZero) {
5234
6228
  if (lo >= 0 && hi - lo >= hi / 6) {
5235
6229
  lo = 0;
5236
6230
  fixedLo = true;
@@ -5263,151 +6257,238 @@ var PERCENT_SCALE = {
5263
6257
  function formatAxisValue(value, percent = false) {
5264
6258
  if (percent) return `${clean(value * 100)}%`;
5265
6259
  const v = clean(value);
5266
- if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
5267
- return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
5268
- const [int = "0", frac] = String(Math.abs(v)).split(".");
5269
- const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
5270
- return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
5271
- }
5272
-
5273
- // chart/render/theme-palette.ts
5274
- var THEME_SLOTS = [
5275
- "lt1",
5276
- "dk1",
5277
- "lt2",
5278
- "dk2",
5279
- "accent1",
5280
- "accent2",
5281
- "accent3",
5282
- "accent4",
5283
- "accent5",
5284
- "accent6",
5285
- "hlink",
5286
- "folHlink"
5287
- ];
5288
- var DEFAULT_THEME_COLORS = [
5289
- "FFFFFF",
5290
- "000000",
5291
- "E7E6E6",
5292
- "44546A",
5293
- "4472C4",
5294
- "ED7D31",
5295
- "A5A5A5",
5296
- "FFC000",
5297
- "5B9BD5",
5298
- "70AD47",
5299
- "0563C1",
5300
- "954F72"
5301
- ];
5302
- function themeColor(theme, index) {
5303
- const hex = theme.colors[index] ?? DEFAULT_THEME_COLORS[index];
5304
- return hex && parseArgbHex(hex) ? hex.replace(/^#/, "") : void 0;
5305
- }
5306
-
5307
- // chart/render/chart-colors.ts
5308
- function chartColorScheme(theme) {
5309
- const slots = Object.fromEntries(
5310
- THEME_SLOTS.map((slot, index) => [slot, `#${themeColor(theme, index) ?? "000000"}`])
5311
- );
5312
- return {
5313
- ...slots,
5314
- bg1: slots.lt1,
5315
- tx1: slots.dk1,
5316
- bg2: slots.lt2,
5317
- tx2: slots.dk2
5318
- };
5319
- }
5320
- function autoSeriesColor(theme, index) {
5321
- const i = Math.max(0, Math.floor(index));
5322
- return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
5323
- }
5324
-
5325
- // chart/text-inheritance.ts
5326
- var TEXT_KEYS = [
5327
- "fontSize",
5328
- "bold",
5329
- "italic",
5330
- "underline",
5331
- "typeface",
5332
- "textColor",
5333
- "fontRef"
5334
- ];
5335
- var TEXT_PARTS = [
5336
- "title",
5337
- "axisTitle",
5338
- "categoryAxis",
5339
- "valueAxis",
5340
- "legend",
5341
- "dataLabel"
5342
- ];
5343
- function inheritChartText(part, entry, builtIn, root) {
5344
- if (!root || !TEXT_PARTS.includes(part)) return entry;
5345
- const out = { ...entry };
5346
- for (const key of TEXT_KEYS) {
5347
- delete out[key];
5348
- const value = root[key] ?? builtIn?.[key];
5349
- if (value !== void 0) Object.assign(out, { [key]: value });
6260
+ if (Math.abs(v) >= 1e15 || v !== 0 && Math.abs(v) < 1e-6)
6261
+ return v.toExponential(2).replace("e+", "E+").replace("e-", "E-");
6262
+ const [int = "0", frac] = String(Math.abs(v)).split(".");
6263
+ const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
6264
+ return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
6265
+ }
6266
+
6267
+ // chart/render/chart-svg-axes.ts
6268
+ function axisTickText(value, axis, percent = false) {
6269
+ return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
6270
+ }
6271
+ function axisLine(model, axis, part, x1, y1, x2, y2) {
6272
+ if (axis?.source.deleted) return "";
6273
+ return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
6274
+ }
6275
+ function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
6276
+ const color = paint2?.color ?? fallback.color;
6277
+ const width = paint2?.width ?? fallback.width;
6278
+ if (color === "none" || width === 0) return "";
6279
+ const dash = chartLineDashArray(paint2?.dash, width);
6280
+ return line(x1, y1, x2, y2, esc(color), width).replace(
6281
+ "/>",
6282
+ dash ? ` stroke-dasharray="${dash}"/>` : "/>"
6283
+ );
6284
+ }
6285
+ function axisGridlines(model, axis, ticks, position2, plot, vertical) {
6286
+ const draw2 = (values, paint2, minor2) => {
6287
+ const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
6288
+ return values.map((value) => {
6289
+ const p = position2(value);
6290
+ return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
6291
+ }).join("");
6292
+ };
6293
+ const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
6294
+ const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
6295
+ return major + minor;
6296
+ }
6297
+
6298
+ // chart/axis-range.ts
6299
+ function computeLogValueRange(series, logBase) {
6300
+ const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
6301
+ if (allValues.length === 0) {
6302
+ return { min: 1, max: logBase, span: 1, logScale: true, logBase };
6303
+ }
6304
+ const dataMin = Math.min(...allValues);
6305
+ const dataMax = Math.max(...allValues);
6306
+ const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
6307
+ const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
6308
+ const min = logBase ** logMin;
6309
+ const max = logBase ** Math.max(logMax, logMin + 1);
6310
+ return {
6311
+ min,
6312
+ max,
6313
+ span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
6314
+ logScale: true,
6315
+ logBase
6316
+ };
6317
+ }
6318
+ function withAxisBounds(automatic, axis, logBase) {
6319
+ const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
6320
+ const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
6321
+ const min = validMin ?? automatic.min;
6322
+ let max = validMax ?? automatic.max;
6323
+ const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
6324
+ if (max <= min) {
6325
+ max = logBase ? min * logBase : min + 1;
5350
6326
  }
5351
- if (part === "title" && root.fontSize !== void 0) out.fontSize = root.fontSize * 1.2;
5352
- if (root.textEffectsXml !== void 0) out.textEffectsXml = root.textEffectsXml;
5353
- return out;
6327
+ const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
6328
+ return {
6329
+ min,
6330
+ max,
6331
+ span: Math.max(span, Number.EPSILON),
6332
+ ...majorUnit !== void 0 ? { majorUnit } : {},
6333
+ ...logBase ? { logScale: true, logBase } : {},
6334
+ ...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
6335
+ };
5354
6336
  }
5355
6337
 
5356
- // chart/render/chart-appearance.ts
5357
- var chartPointsToPixels = (points) => points * EMU_PER_POINT / EMU_PER_PIXEL;
5358
- function typeface(entry, theme) {
5359
- const name = entry.typeface;
5360
- if (name?.startsWith("+mj-")) return theme.majorFont;
5361
- if (name?.startsWith("+mn-")) return theme.minorFont;
5362
- return name ?? (entry.fontRef?.index === "major" ? theme.majorFont : entry.fontRef?.index === "minor" ? theme.minorFont : void 0);
6338
+ // chart/axis-ticks.ts
6339
+ var LOG_EXPONENT_TOLERANCE = 1e-12;
6340
+ function generateLogTicks(range) {
6341
+ if (!range.logScale || !range.logBase) {
6342
+ return [];
6343
+ }
6344
+ const base = range.logBase;
6345
+ const logMin = Math.log(range.min) / Math.log(base);
6346
+ const logMax = Math.log(range.max) / Math.log(base);
6347
+ const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
6348
+ const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
6349
+ if (lastExponent < firstExponent) {
6350
+ return range.min === range.max ? [range.min] : [range.min, range.max];
6351
+ }
6352
+ return Array.from(
6353
+ { length: lastExponent - firstExponent + 1 },
6354
+ (_unused, index) => base ** (firstExponent + index)
6355
+ );
5363
6356
  }
5364
- function chartAppearance(chart, theme) {
5365
- const defaults = builtInChartTextStyle(effectiveBuiltInChartStyle(chart.formatting));
5366
- const entries = {};
5367
- for (const part of CHART_STYLE_PARTS) {
5368
- const base = chart.styleDefinition?.entries[part];
5369
- const direct = chart.formatting?.entries[part];
5370
- if (!defaults[part] && !base && !direct) continue;
5371
- const entry = {
5372
- ...inheritChartText(
5373
- part,
5374
- { ...defaults[part], ...base, sourceXml: base?.sourceXml ?? "" },
5375
- defaults[part],
5376
- chart.formatting?.textDefaults
5377
- ),
5378
- ...direct,
5379
- sourceXml: direct?.sourceXml ?? base?.sourceXml ?? ""
5380
- };
5381
- if (base?.line || direct?.line) entry.line = { ...base?.line, ...direct?.line };
5382
- entries[part] = entry;
6357
+ function generateIntervalTicks(range, unit) {
6358
+ if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
6359
+ return [];
5383
6360
  }
5384
- const scheme = chartColorScheme(theme);
5385
- const resolve = (color) => resolveDrawingColor(
5386
- color,
5387
- { scheme: (name) => scheme[name] },
5388
- { hslRounding: "halfDown", transformOrder: "document" }
6361
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
6362
+ const first3 = Math.ceil((range.min - tolerance) / unit);
6363
+ const last = Math.floor((range.max + tolerance) / unit);
6364
+ const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
6365
+ return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
6366
+ }
6367
+ function generateAxisTicks(range, axis, defaultIntervals) {
6368
+ if (range.logScale && range.logBase) {
6369
+ return generateLogTicks(range);
6370
+ }
6371
+ const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
6372
+ if (explicit.length > 0) {
6373
+ return explicit;
6374
+ }
6375
+ const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
6376
+ if (automatic.length > 0) {
6377
+ return automatic;
6378
+ }
6379
+ return Array.from(
6380
+ { length: defaultIntervals + 1 },
6381
+ (_, index) => range.min + range.span / defaultIntervals * index
5389
6382
  );
5390
- const out = resolveChartStyleDefinition(
5391
- { entries},
5392
- (color) => drawingColorCss(resolve(color))
5393
- ) ?? {};
5394
- for (const part of CHART_STYLE_PARTS) {
5395
- const entry = entries[part];
5396
- if (!entry) continue;
5397
- const family = typeface(entry, theme);
5398
- const shadow = resolveDrawingShadowXml(entry.textEffectsXml, {
5399
- scheme: (name) => scheme[name]
5400
- });
5401
- if (shadow) (out[part] ??= {}).textShadow = shadow;
5402
- if (family) (out[part] ??= {}).typeface = family;
5403
- if (entry.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry.axisVisible;
5404
- if (entry.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry.labelsVisible;
5405
- if (entry.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
5406
- if (entry.fill?.kind === "gradient") {
5407
- (out[part] ??= {}).gradient = resolveChartGradient(entry.fill, resolve);
5408
- }
6383
+ }
6384
+ function generateMinorAxisTicks(range, axis) {
6385
+ const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
6386
+ if (minor.length === 0) {
6387
+ return [];
5409
6388
  }
5410
- return out;
6389
+ const majorUnit = axis?.majorUnit;
6390
+ if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
6391
+ return minor;
6392
+ }
6393
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
6394
+ return minor.filter(
6395
+ (value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
6396
+ );
6397
+ }
6398
+
6399
+ // chart/render/chart-view-axes.ts
6400
+ function chartAxisRatio(value, scale, axis) {
6401
+ const range = axis?.range;
6402
+ 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);
6403
+ return range?.reverseOrder ? 1 - ratio : ratio;
6404
+ }
6405
+ function chartAxisLabels(axis) {
6406
+ return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
6407
+ }
6408
+ function options(axis) {
6409
+ return {
6410
+ ...axis.scaling,
6411
+ ...axis.scaling.logBase === void 0 ? {} : { logScale: true },
6412
+ ...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
6413
+ ...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
6414
+ };
6415
+ }
6416
+ function applyChartAxes(model, chart, color) {
6417
+ if (!chart.axes?.length) return;
6418
+ const axes = chart.axes;
6419
+ const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
6420
+ const candidates = linked.length ? linked : axes;
6421
+ const xy = model.type === "scatter" || model.type === "bubble";
6422
+ const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
6423
+ const category = candidates.find(
6424
+ (axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
6425
+ );
6426
+ const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
6427
+ const paint2 = (shape) => {
6428
+ const ln = shape?.line;
6429
+ const fill = ln?.fill;
6430
+ const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
6431
+ return {
6432
+ ...resolved === void 0 ? {} : { color: resolved },
6433
+ ...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
6434
+ ...ln?.dash === void 0 ? {} : { dash: ln.dash }
6435
+ };
6436
+ };
6437
+ const bind = (axis, scale, values) => {
6438
+ const opts = options(axis);
6439
+ const automatic = opts.logScale ? computeLogValueRange(
6440
+ [{ values: values ?? [] }],
6441
+ opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
6442
+ ) : {
6443
+ min: scale?.min ?? 0,
6444
+ max: scale?.max ?? 1,
6445
+ span: (scale?.max ?? 1) - (scale?.min ?? 0),
6446
+ ...scale ? { majorUnit: scale.majorUnit } : {}
6447
+ };
6448
+ const logBase = automatic.logBase;
6449
+ const range = withAxisBounds(automatic, opts, logBase);
6450
+ if (scale) {
6451
+ scale.min = range.min;
6452
+ scale.max = range.max;
6453
+ scale.ticks = generateAxisTicks(range, opts, 5);
6454
+ }
6455
+ return {
6456
+ source: axis,
6457
+ range,
6458
+ minorTicks: generateMinorAxisTicks(range, opts),
6459
+ line: paint2(axis.spPr),
6460
+ majorGrid: paint2(axis.majorGridlinesSpPr),
6461
+ minorGrid: paint2(axis.minorGridlinesSpPr)
6462
+ };
6463
+ };
6464
+ const out = {};
6465
+ if (value)
6466
+ out.value = bind(
6467
+ value,
6468
+ model.valueAxis,
6469
+ [
6470
+ ...model.series,
6471
+ ...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
6472
+ ].flatMap((s) => s.values)
6473
+ );
6474
+ if (category)
6475
+ out.category = bind(
6476
+ category,
6477
+ model.xAxis ?? {
6478
+ min: 0,
6479
+ max: Math.max(1, model.categories.length - 1),
6480
+ majorUnit: 1,
6481
+ ticks: []
6482
+ },
6483
+ model.series.flatMap((s) => s.xValues ?? [])
6484
+ );
6485
+ if (secondary)
6486
+ out.secondary = bind(
6487
+ secondary,
6488
+ model.secondaryAxis,
6489
+ model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
6490
+ );
6491
+ model.axes = out;
5411
6492
  }
5412
6493
 
5413
6494
  // chart/render/chart-view-analysis.ts
@@ -5459,15 +6540,15 @@ function seriesName(series, index, evaluateRef) {
5459
6540
  const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
5460
6541
  return fromRef || series.name || `Series${index + 1}`;
5461
6542
  }
5462
- function seriesContext(chart, theme, options) {
6543
+ function seriesContext(chart, theme, options2) {
5463
6544
  const scheme = chartColorScheme(theme);
5464
6545
  const resolver = { scheme: (name) => scheme[name] };
5465
6546
  return {
5466
6547
  theme,
5467
6548
  scheme,
5468
6549
  palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
5469
- evaluateRef: options.evaluateRef ?? (() => []),
5470
- seriesColor: options.seriesColor,
6550
+ evaluateRef: options2.evaluateRef ?? (() => []),
6551
+ seriesColor: options2.seriesColor,
5471
6552
  drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
5472
6553
  gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
5473
6554
  fill,
@@ -5493,7 +6574,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
5493
6574
  })
5494
6575
  );
5495
6576
  if (Object.keys(points).length) view.pointGradients = points;
5496
- Object.assign(view, analysisView(s, color, ctx.drawingColor));
6577
+ Object.assign(
6578
+ view,
6579
+ analysisView(s, color, ctx.drawingColor),
6580
+ seriesMarkerViews(s, ctx.drawingColor)
6581
+ );
5497
6582
  return view;
5498
6583
  }
5499
6584
 
@@ -5666,12 +6751,70 @@ function chartTitleText(chart, theme) {
5666
6751
  };
5667
6752
  }
5668
6753
 
6754
+ // chart/render/chart-view-labels.ts
6755
+ function labelsOf(source, view, categories, numberFormat) {
6756
+ const { chart, series, points } = source;
6757
+ if ((series?.deleted ?? chart?.deleted) === true) return void 0;
6758
+ const percentBase = view.values.reduce(
6759
+ (sum, v) => sum + (v === null ? 0 : Math.abs(v)),
6760
+ 0
6761
+ );
6762
+ const out = [];
6763
+ let any = false;
6764
+ view.values.forEach((value, i) => {
6765
+ const point = points?.[i];
6766
+ if (value === null || point?.deleted === true) return;
6767
+ const position2 = point?.position ?? series?.position ?? chart?.position;
6768
+ const x = view.xValues?.[i];
6769
+ const category = x === void 0 || x === null ? categories[i] : formatAxisValue(x);
6770
+ let built;
6771
+ if (point?.text !== void 0) built = { text: point.text };
6772
+ else {
6773
+ const flags = resolveDataLabelFlags({
6774
+ ...point ? { point } : {},
6775
+ ...series ? { series } : {},
6776
+ ...chart ? { chart } : {}
6777
+ });
6778
+ built = composeDataLabelText({
6779
+ flags,
6780
+ seriesName: view.name,
6781
+ category,
6782
+ value,
6783
+ numberFormat: point?.numberFormat ?? series?.numberFormat ?? chart?.numberFormat ?? numberFormat,
6784
+ percentBase,
6785
+ bubbleSize: view.sizes?.[i] ?? void 0,
6786
+ formatValue: (v) => formatAxisValue(v),
6787
+ formatBubbleSize: (size) => formatAxisValue(size)
6788
+ });
6789
+ }
6790
+ if (!built) return;
6791
+ any = true;
6792
+ out[i] = {
6793
+ text: built.text,
6794
+ ...position2 ? { position: position2 } : {},
6795
+ ...built.color ? { color: built.color } : {}
6796
+ };
6797
+ });
6798
+ return any ? out : void 0;
6799
+ }
6800
+ function applyDataLabels(model, sources, extra) {
6801
+ const apply = (source, view) => {
6802
+ if (!source?.dataLabels) return;
6803
+ const labels = labelsOf(source.dataLabels, view, model.categories, source.numberFormat);
6804
+ if (labels) view.labels = labels;
6805
+ };
6806
+ model.series.forEach((view, i) => apply(sources[i], view));
6807
+ model.extraGroups?.forEach(
6808
+ (group2, g) => group2.series.forEach((view, i) => apply(extra[g]?.series[i], view))
6809
+ );
6810
+ }
6811
+
5669
6812
  // chart/render/chart-view-ex.ts
5670
6813
  function groupsAxis(groups, categories) {
5671
6814
  let min = Infinity;
5672
6815
  let max = -Infinity;
5673
- for (const group of groups) {
5674
- const extent = valueExtent(group.type, group.grouping, group.series, categories);
6816
+ for (const group2 of groups) {
6817
+ const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
5675
6818
  min = Math.min(min, extent.min);
5676
6819
  max = Math.max(max, extent.max);
5677
6820
  }
@@ -5680,17 +6823,17 @@ function groupsAxis(groups, categories) {
5680
6823
  function chartExtraView(chart, model, ctx, total, categoriesOf) {
5681
6824
  let index = chart.series.length;
5682
6825
  const groups = [];
5683
- for (const group of chart.extraGroups ?? []) {
5684
- const series = group.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
6826
+ for (const group2 of chart.extraGroups ?? []) {
6827
+ const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
5685
6828
  const view = {
5686
- type: group.chartType,
5687
- grouping: group.grouping ?? (group.chartType === "column" ? "clustered" : "standard"),
6829
+ type: group2.chartType,
6830
+ grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
5688
6831
  series,
5689
- secondary: group.secondary
6832
+ secondary: group2.secondary
5690
6833
  };
5691
- if (group.chartType === "stock") view.stock = stockView(group.stock, ctx);
5692
- if (group.barGapWidth !== void 0) view.barGapWidth = group.barGapWidth;
5693
- if (group.barOverlap !== void 0) view.barOverlap = group.barOverlap;
6834
+ if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
6835
+ if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
6836
+ if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
5694
6837
  groups.push(view);
5695
6838
  }
5696
6839
  if (!groups.length) return;
@@ -5707,8 +6850,8 @@ function chartExtraAxes(model) {
5707
6850
  const own2 = valueExtent(model.type, model.grouping, model.series, count);
5708
6851
  let min = own2.min;
5709
6852
  let max = own2.max;
5710
- for (const group of shared) {
5711
- const extent = valueExtent(group.type, group.grouping, group.series, count);
6853
+ for (const group2 of shared) {
6854
+ const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
5712
6855
  min = Math.min(min, extent.min);
5713
6856
  max = Math.max(max, extent.max);
5714
6857
  }
@@ -5735,11 +6878,11 @@ function histogramView(chart, model) {
5735
6878
  const first3 = model.series[0];
5736
6879
  if (!first3) return;
5737
6880
  const raw = first3.values.map((v) => v ?? Number.NaN);
5738
- const options = chart.histogram ?? {};
5739
- const bins = options.aggregateByCategory ? aggregateByCategory(
6881
+ const options2 = chart.histogram ?? {};
6882
+ const bins = options2.aggregateByCategory ? aggregateByCategory(
5740
6883
  first3.values.map((v) => v ?? 0),
5741
6884
  model.categories
5742
- ) : computeHistogramBins(raw, options, formatAxisValue);
6885
+ ) : computeHistogramBins(raw, options2, formatAxisValue);
5743
6886
  model.categories = bins.map((bin) => bin.label);
5744
6887
  first3.values = bins.map((bin) => bin.value);
5745
6888
  model.barGapWidth = 0;
@@ -5763,11 +6906,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
5763
6906
  "treemap",
5764
6907
  "sunburst"
5765
6908
  ]);
5766
- function chartSummaryView(chart, theme, options = {}) {
6909
+ function chartSummaryView(chart, theme, options2 = {}) {
5767
6910
  const type = chart.chartType;
5768
6911
  const radial = type === "pie" || type === "doughnut";
5769
6912
  const byPoint = radial || type === "treemap" || type === "sunburst";
5770
- const ctx = seriesContext(chart, theme, options);
6913
+ const ctx = seriesContext(chart, theme, options2);
5771
6914
  const { palette, scheme, drawingColor } = ctx;
5772
6915
  const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
5773
6916
  const rawCategories = [];
@@ -5851,128 +6994,23 @@ function chartSummaryView(chart, theme, options = {}) {
5851
6994
  chartExtraView(chart, model, ctx, total, collect);
5852
6995
  if (type === "waterfall") waterfallView(chart, model, ctx);
5853
6996
  else if (!byPoint) model.valueAxis = valueAxis(model);
6997
+ applyDataLabels(model, chart.series, extra);
5854
6998
  chartExtraAxes(model);
6999
+ applyChartAxes(model, chart, ctx.drawingColor);
5855
7000
  return model;
5856
7001
  }
5857
7002
 
5858
- // text/css-font-family.ts
5859
- var FALLBACKS = {
5860
- calibri: '"Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5861
- "calibri light": '"Calibri Light", "Calibri", "Carlito", "Segoe UI", Arial, sans-serif',
5862
- cambria: '"Cambria", "Caladea", Georgia, serif',
5863
- arial: 'Arial, "Liberation Sans", Helvetica, sans-serif',
5864
- "times new roman": '"Times New Roman", "Liberation Serif", Times, serif',
5865
- "courier new": '"Courier New", "Liberation Mono", monospace',
5866
- aptos: '"Aptos", "Calibri", "Carlito", "Segoe UI", sans-serif'
5867
- };
5868
- function cssFontFamily(name) {
5869
- const known = FALLBACKS[name.toLowerCase()];
5870
- if (known) return known;
5871
- const quoted = `"${name.replace(/["\\]/g, "")}"`;
5872
- return `${quoted}, "Calibri", "Carlito", "Segoe UI", sans-serif`;
5873
- }
5874
-
5875
- // chart/render/chart-svg-appearance.ts
5876
- var nextPaintId = 0;
5877
- function chartGradientPaint(model, width = 1024, height = 768) {
5878
- const prefix = `xlsx-chart-${++nextPaintId}`;
5879
- const appearance = { ...model.appearance };
5880
- const defs = [];
5881
- const shadowPaint = (shadow, suffix) => {
5882
- const id = `${prefix}-${suffix}`;
5883
- const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
5884
- defs.push(
5885
- `<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>`
5886
- );
5887
- return `url(#${id})`;
5888
- };
5889
- for (const [part, entry] of Object.entries(appearance)) {
5890
- if (entry?.textShadow)
5891
- appearance[part] = {
5892
- ...entry,
5893
- textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
5894
- };
5895
- }
5896
- const paint2 = (gradient, suffix, bounds) => {
5897
- const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
5898
- defs.push(chartGradientMarkup(def));
5899
- return `url(#${def.id})`;
5900
- };
5901
- for (const part of ["chartArea", "plotArea"]) {
5902
- const entry = appearance[part];
5903
- if (!entry?.gradient) continue;
5904
- if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
5905
- appearance[part] = {
5906
- ...entry,
5907
- fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
5908
- };
5909
- }
5910
- const series = model.series.map((source, index) => {
5911
- const view = { ...source };
5912
- if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
5913
- const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
5914
- if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
5915
- if (source.pointGradients) {
5916
- view.pointColors = [...source.pointColors ?? []];
5917
- for (const [key, gradient] of Object.entries(source.pointGradients))
5918
- view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
5919
- }
5920
- return view;
5921
- });
5922
- return defs.length ? { model: { ...model, appearance, series }, defs: `<defs>${defs.join("")}</defs>` } : { model, defs: "" };
5923
- }
5924
- function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
5925
- const entry = model.appearance?.[part];
5926
- return {
5927
- size: entry?.fontSize === void 0 ? fallbackSize : chartPointsToPixels(entry.fontSize),
5928
- ...entry?.color === void 0 ? {} : { fill: entry.color },
5929
- ...entry?.bold === void 0 ? {} : { weight: entry.bold ? "bold" : "normal" },
5930
- ...entry?.italic === void 0 ? {} : { italic: entry.italic },
5931
- ...entry?.underline === void 0 ? {} : { underline: entry.underline },
5932
- ...entry?.typeface === void 0 ? {} : { family: cssFontFamily(entry.typeface) },
5933
- ...entry?.textShadowFilter === void 0 ? {} : { filter: entry.textShadowFilter }
5934
- };
5935
- }
5936
- function chartStroke(model, part) {
5937
- const entry = model.appearance?.[part];
5938
- return {
5939
- color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
5940
- width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
5941
- };
5942
- }
5943
- function chartAreaRect(model, part, area) {
5944
- if (area.w <= 0 || area.h <= 0) return "";
5945
- const entry = model.appearance?.[part];
5946
- let fill = entry?.fillColor ?? (part === "chartArea" ? "#FFFFFF" : "none");
5947
- let defs = "";
5948
- if (part !== "chartArea" && entry?.gradient && (part !== "plotArea" || ["circle", "shape"].includes(entry.gradient.path ?? ""))) {
5949
- const def = buildChartGradientDef(`xlsx-chart-${++nextPaintId}-${part}`, entry.gradient, {
5950
- width: area.w,
5951
- height: area.h,
5952
- shape: "rect"
5953
- });
5954
- defs = `<defs>${chartGradientMarkup(def)}</defs>`;
5955
- fill = `url(#${def.id})`;
5956
- }
5957
- const stroke = entry?.lineColor ?? "none";
5958
- if (fill === "none" && stroke === "none") return "";
5959
- const width = entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth);
5960
- 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}"/>`;
5961
- }
5962
-
5963
7003
  // chart/render/chart-svg-cartesian.ts
5964
7004
  function cartesianAxes(model, area, out) {
5965
7005
  const scale = model.valueAxis;
5966
7006
  if (!scale) return void 0;
5967
- const labels = scale.ticks.map((t) => formatAxisValue(t, scale.percent));
7007
+ const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
5968
7008
  const valueAttrs = chartTextAttributes(model, "valueAxis");
5969
7009
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
5970
7010
  const valueSize = valueAttrs.size ?? 10;
5971
7011
  const categorySize = categoryAttrs.size ?? 10;
5972
- const grid = chartStroke(model, "gridlineMajor");
5973
- const axis = chartStroke(model, "categoryAxis");
5974
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
5975
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
7012
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
7013
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
5976
7014
  const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
5977
7015
  const horizontal = model.horizontal;
5978
7016
  const cats = Math.max(1, model.categories.length);
@@ -5981,7 +7019,7 @@ function cartesianAxes(model, area, out) {
5981
7019
  Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
5982
7020
  );
5983
7021
  const second = horizontal ? void 0 : model.secondaryAxis;
5984
- const secondLabels = second?.ticks.map((t) => formatAxisValue(t, second.percent)) ?? [];
7022
+ const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
5985
7023
  const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
5986
7024
  const plot = horizontal ? {
5987
7025
  x: area.x + catW,
@@ -5994,29 +7032,47 @@ function cartesianAxes(model, area, out) {
5994
7032
  w: Math.max(1, area.w - labelW - 4 - secondW),
5995
7033
  h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
5996
7034
  };
5997
- const span = scale.max - scale.min || 1;
5998
- const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
7035
+ 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;
5999
7036
  const bandSize = (horizontal ? plot.h : plot.w) / cats;
6000
- const band = horizontal ? (i) => plot.y + plot.h - bandSize * (i + 0.5) : (i) => plot.x + bandSize * (i + 0.5);
7037
+ const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
7038
+ const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
6001
7039
  out.push(chartAreaRect(model, "plotArea", plot));
7040
+ out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
7041
+ if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
7042
+ out.push(
7043
+ axisGridlines(
7044
+ model,
7045
+ model.axes.category,
7046
+ model.categories.map((_, i) => i),
7047
+ band,
7048
+ plot,
7049
+ !horizontal
7050
+ )
7051
+ );
6002
7052
  scale.ticks.forEach((t, i) => {
6003
7053
  const p = value(t);
6004
7054
  const label = labels[i] ?? "";
6005
7055
  if (horizontal) {
6006
- out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
6007
7056
  if (valueLabels)
6008
7057
  out.push(
6009
7058
  text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
6010
7059
  );
6011
7060
  } else {
6012
- out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
6013
7061
  if (valueLabels)
6014
7062
  out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
6015
7063
  }
6016
7064
  });
6017
- const zero = value(Math.min(Math.max(0, scale.min), scale.max));
6018
- if (horizontal) out.push(line(zero, plot.y, zero, plot.y + plot.h, axis.color, axis.width));
6019
- else out.push(line(plot.x, zero, plot.x + plot.w, zero, axis.color, axis.width));
7065
+ const source = model.axes?.value?.source;
7066
+ const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
7067
+ const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
7068
+ if (horizontal)
7069
+ out.push(
7070
+ axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
7071
+ );
7072
+ else
7073
+ out.push(
7074
+ axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
7075
+ );
6020
7076
  const step = Math.max(
6021
7077
  1,
6022
7078
  Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
@@ -6041,20 +7097,23 @@ function cartesianAxes(model, area, out) {
6041
7097
  });
6042
7098
  const frame = { plot, value, band, bandSize };
6043
7099
  if (second) {
6044
- const secondSpan = second.max - second.min || 1;
6045
- frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
6046
- const secondAxis = chartStroke(model, "valueAxis");
7100
+ frame.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
6047
7101
  out.push(
6048
- line(
7102
+ axisLine(
7103
+ model,
7104
+ model.axes?.secondary,
7105
+ "valueAxis",
6049
7106
  plot.x + plot.w,
6050
7107
  plot.y,
6051
7108
  plot.x + plot.w,
6052
- plot.y + plot.h,
6053
- secondAxis.color,
6054
- secondAxis.width
7109
+ plot.y + plot.h
6055
7110
  )
6056
7111
  );
6057
- if (valueLabels)
7112
+ if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
7113
+ out.push(
7114
+ axisGridlines(model, model.axes.secondary, second.ticks, frame.secondary, plot, false)
7115
+ );
7116
+ if (chartAxisLabels(model.axes?.secondary))
6058
7117
  second.ticks.forEach(
6059
7118
  (t, i) => out.push(
6060
7119
  text(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
@@ -6078,6 +7137,7 @@ function linesAndAreas(model, frame, out) {
6078
7137
  const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
6079
7138
  const acc = new Array(model.categories.length).fill(0);
6080
7139
  const area = model.type === "area";
7140
+ const marks = [];
6081
7141
  const layers = [];
6082
7142
  model.series.forEach((s, si) => {
6083
7143
  const points = [];
@@ -6092,16 +7152,24 @@ function linesAndAreas(model, frame, out) {
6092
7152
  const top = below + (v ?? 0);
6093
7153
  if (stacked) acc[i] = top;
6094
7154
  points.push([frame.band(i), frame.value(top)]);
7155
+ marks.push({
7156
+ series: s,
7157
+ index: i,
7158
+ x: frame.band(i),
7159
+ y: frame.value(top),
7160
+ radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
7161
+ });
6095
7162
  lower.push([frame.band(i), frame.value(below)]);
6096
7163
  });
6097
7164
  layers.push({
7165
+ series: s,
6098
7166
  points,
6099
7167
  lower,
6100
7168
  color: s.color,
6101
7169
  filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
6102
7170
  });
6103
7171
  });
6104
- for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
7172
+ for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
6105
7173
  if (area) {
6106
7174
  const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6107
7175
  out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
@@ -6120,10 +7188,11 @@ function linesAndAreas(model, frame, out) {
6120
7188
  else segment2.push(`${n(x)},${n(y)}`);
6121
7189
  }
6122
7190
  flush();
6123
- for (const [x, y] of points)
6124
- if (!Number.isNaN(x))
6125
- out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
7191
+ points.forEach(([x, y], index) => {
7192
+ if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
7193
+ });
6126
7194
  }
7195
+ pointLabels(model, marks, out);
6127
7196
  }
6128
7197
 
6129
7198
  // chart/render/chart-svg-xy.ts
@@ -6131,16 +7200,14 @@ function scatter(model, area, out) {
6131
7200
  const ys = model.valueAxis;
6132
7201
  const xs = model.xAxis;
6133
7202
  if (!ys || !xs) return;
6134
- const yLabels = ys.ticks.map((t) => formatAxisValue(t));
7203
+ const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
6135
7204
  const valueAttrs = chartTextAttributes(model, "valueAxis");
6136
7205
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
6137
7206
  const valueSize = valueAttrs.size ?? 10;
6138
7207
  const categorySize = categoryAttrs.size ?? 10;
6139
- const grid = chartStroke(model, "gridlineMajor");
6140
7208
  const xAxis = chartStroke(model, "categoryAxis");
6141
- const yAxis = chartStroke(model, "valueAxis");
6142
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
6143
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
7209
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
7210
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
6144
7211
  const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
6145
7212
  const plot = {
6146
7213
  x: area.x + labelW,
@@ -6160,17 +7227,24 @@ function scatter(model, area, out) {
6160
7227
  s.values.forEach((_, i) => {
6161
7228
  reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
6162
7229
  });
6163
- const widen = (s, length) => {
7230
+ const widen = (s, length, axis) => {
7231
+ if (axis?.range.logScale) return s;
6164
7232
  const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
6165
- return { ...s, min: s.min - pad, max: s.max + pad };
7233
+ return {
7234
+ ...s,
7235
+ min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
7236
+ max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
7237
+ };
6166
7238
  };
6167
- const xView = widen(xs, plot.w);
6168
- const yView = widen(ys, plot.h);
6169
- const px = (v) => plot.x + (v - xView.min) / (xView.max - xView.min || 1) * plot.w;
6170
- const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
7239
+ const xView = widen(xs, plot.w, model.axes?.category);
7240
+ const yView = widen(ys, plot.h, model.axes?.value);
7241
+ const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
7242
+ const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
6171
7243
  out.push(chartAreaRect(model, "plotArea", plot));
7244
+ out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
7245
+ if (model.axes?.category)
7246
+ out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
6172
7247
  ys.ticks.forEach((t, i) => {
6173
- out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
6174
7248
  if (valueLabels)
6175
7249
  out.push(
6176
7250
  text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
@@ -6180,19 +7254,31 @@ function scatter(model, area, out) {
6180
7254
  );
6181
7255
  });
6182
7256
  for (const t of xs.ticks) {
6183
- out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
7257
+ if (!model.axes?.category?.source.deleted)
7258
+ out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
6184
7259
  if (categoryLabels)
6185
7260
  out.push(
6186
- text(px(t), plot.y + plot.h + categorySize + 3, formatAxisValue(t), {
7261
+ text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
6187
7262
  anchor: "middle",
6188
7263
  ...categoryAttrs
6189
7264
  })
6190
7265
  );
6191
7266
  }
6192
7267
  out.push(
6193
- line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
7268
+ axisLine(
7269
+ model,
7270
+ model.axes?.category,
7271
+ "categoryAxis",
7272
+ plot.x,
7273
+ plot.y + plot.h,
7274
+ plot.x + plot.w,
7275
+ plot.y + plot.h
7276
+ )
7277
+ );
7278
+ out.push(
7279
+ axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
6194
7280
  );
6195
- out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
7281
+ const marks = [];
6196
7282
  for (const [si, s] of model.series.entries())
6197
7283
  s.values.forEach((v, i) => {
6198
7284
  const x = s.xValues?.[i] ?? null;
@@ -6200,15 +7286,18 @@ function scatter(model, area, out) {
6200
7286
  const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
6201
7287
  const fill = s.pointColors?.[i] ?? s.color;
6202
7288
  if (!bubble) {
6203
- out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
7289
+ out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
7290
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
6204
7291
  return;
6205
7292
  }
6206
7293
  const r = radiusOf(s.sizes?.[i] ?? void 0);
6207
7294
  if (r === void 0) return;
7295
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: r });
6208
7296
  out.push(
6209
7297
  `<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}/>`
6210
7298
  );
6211
7299
  });
7300
+ pointLabels(model, marks, out);
6212
7301
  scatterAnalysis(model, px, py, out);
6213
7302
  }
6214
7303
 
@@ -6325,21 +7414,21 @@ function cartesianSvg(model, area) {
6325
7414
  return out.join("");
6326
7415
  }
6327
7416
  const layers = [{ model, frame }];
6328
- for (const group of model.extraGroups ?? []) {
7417
+ for (const group2 of model.extraGroups ?? []) {
6329
7418
  const grouped = {
6330
7419
  ...model,
6331
- type: group.type,
6332
- grouping: group.grouping,
6333
- series: group.series,
7420
+ type: group2.type,
7421
+ grouping: group2.grouping,
7422
+ series: group2.series,
6334
7423
  horizontal: false
6335
7424
  };
6336
- if (group.stock) grouped.stock = group.stock;
7425
+ if (group2.stock) grouped.stock = group2.stock;
6337
7426
  else delete grouped.stock;
6338
- if (group.barGapWidth !== void 0) grouped.barGapWidth = group.barGapWidth;
7427
+ if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
6339
7428
  else delete grouped.barGapWidth;
6340
- if (group.barOverlap !== void 0) grouped.barOverlap = group.barOverlap;
7429
+ if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
6341
7430
  else delete grouped.barOverlap;
6342
- const value = group.secondary && frame.secondary ? frame.secondary : frame.value;
7431
+ const value = group2.secondary && frame.secondary ? frame.secondary : frame.value;
6343
7432
  layers.push({ model: grouped, frame: { ...frame, value } });
6344
7433
  }
6345
7434
  layers.map((layer, order) => ({ layer, order })).sort(
@@ -6373,7 +7462,9 @@ function pieSvg(model, area) {
6373
7462
  const out = [chartAreaRect(model, "plotArea", area)];
6374
7463
  const cx = area.x + area.w / 2;
6375
7464
  const cy = area.y + area.h / 2;
6376
- const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4);
7465
+ const margin = hasOutsideLabels(model) ? Math.min(area.w, area.h) * 0.12 : 0;
7466
+ const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4 - margin);
7467
+ const slices = [];
6377
7468
  const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
6378
7469
  const hole = model.type === "doughnut" ? radius * 0.5 : 0;
6379
7470
  const ringSize = (radius - hole) / Math.max(1, rings.length);
@@ -6390,9 +7481,20 @@ function pieSvg(model, area) {
6390
7481
  out.push(
6391
7482
  `<path d="${slicePath(cx, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
6392
7483
  );
7484
+ slices.push({
7485
+ series: s,
7486
+ index: i,
7487
+ cx,
7488
+ cy,
7489
+ outer,
7490
+ inner,
7491
+ start: angle,
7492
+ end: angle + sweep
7493
+ });
6393
7494
  angle += sweep;
6394
7495
  });
6395
7496
  });
7497
+ sliceLabels(model, slices, out);
6396
7498
  return out.join("");
6397
7499
  }
6398
7500
  function radarSvg(model, area) {
@@ -6405,32 +7507,37 @@ function radarSvg(model, area) {
6405
7507
  const valueSize = valueAttrs.size ?? 9;
6406
7508
  const categorySize = categoryAttrs.size ?? 10;
6407
7509
  const grid = chartStroke(model, "gridlineMajor");
6408
- const axis = chartStroke(model, "categoryAxis");
6409
7510
  const cx = area.x + area.w / 2;
6410
7511
  const cy = area.y + area.h / 2 + 4;
6411
7512
  const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
6412
7513
  const angle = (i) => i / count * Math.PI * 2;
6413
- const r = (v) => (v - scale.min) / (scale.max - scale.min || 1) * radius;
7514
+ const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
6414
7515
  const labelEvery = Math.max(
6415
7516
  1,
6416
7517
  Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
6417
7518
  );
6418
7519
  for (const [k, t] of scale.ticks.entries()) {
6419
7520
  const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6420
- out.push(
6421
- `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
6422
- );
6423
- if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
7521
+ if (!model.axes?.value || model.axes.value.source.majorGridlines)
7522
+ out.push(
7523
+ `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
7524
+ );
7525
+ if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
6424
7526
  out.push(
6425
- text(cx + 3, cy - r(t) + valueSize * 0.3, formatAxisValue(t, scale.percent), valueAttrs)
7527
+ text(
7528
+ cx + 3,
7529
+ cy - r(t) + valueSize * 0.3,
7530
+ axisTickText(t, model.axes?.value, scale.percent),
7531
+ valueAttrs
7532
+ )
6426
7533
  );
6427
7534
  }
6428
7535
  model.categories.forEach((c, i) => {
6429
7536
  const [x, y] = polar(cx, cy, radius, angle(i));
6430
- out.push(line(cx, cy, x, y, axis.color, axis.width));
7537
+ out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
6431
7538
  const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
6432
7539
  const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
6433
- if (model.appearance?.categoryAxis?.labelsVisible !== false)
7540
+ if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
6434
7541
  out.push(
6435
7542
  text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
6436
7543
  anchor,
@@ -6438,12 +7545,22 @@ function radarSvg(model, area) {
6438
7545
  })
6439
7546
  );
6440
7547
  });
7548
+ const marks = [];
6441
7549
  for (const s of model.series) {
6442
- 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(" ");
7550
+ const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
7551
+ vertices.forEach(([x, y], i) => {
7552
+ if (s.values[i] === null) return;
7553
+ const markerSeries = s;
7554
+ if (markerSeries.marker || markerSeries.pointMarkers)
7555
+ out.push(chartSeriesMarkerSvg(s, i, x, y));
7556
+ marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
7557
+ });
7558
+ const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6443
7559
  out.push(
6444
7560
  `<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
6445
7561
  );
6446
7562
  }
7563
+ pointLabels(model, marks, out);
6447
7564
  return out.join("");
6448
7565
  }
6449
7566
 
@@ -6534,33 +7651,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
6534
7651
  function cssFont(attrs2) {
6535
7652
  return `${attrs2.italic ? "italic" : "normal"} ${attrs2.weight ?? "normal"} ${attrs2.size ?? 10}px ${attrs2.family ?? CHART_FONT_FAMILY}`;
6536
7653
  }
6537
- function chartFontMetrics(attrs2, options) {
6538
- const metrics = options.measureFont?.(cssFont(attrs2));
7654
+ function chartFontMetrics(attrs2, options2) {
7655
+ const metrics = options2.measureFont?.(cssFont(attrs2));
6539
7656
  return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
6540
7657
  }
6541
- function chartTextWidth(content, attrs2, options) {
6542
- const width = options.measureText?.(content, cssFont(attrs2));
7658
+ function chartTextWidth(content, attrs2, options2) {
7659
+ const width = options2.measureText?.(content, cssFont(attrs2));
6543
7660
  return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs2.size);
6544
7661
  }
6545
- function fitChartText(content, maxWidth, attrs2, options) {
6546
- if (!options.measureText) return fit(content, maxWidth, attrs2.size);
6547
- if (chartTextWidth(content, attrs2, options) <= maxWidth) return content;
7662
+ function fitChartText(content, maxWidth, attrs2, options2) {
7663
+ if (!options2.measureText) return fit(content, maxWidth, attrs2.size);
7664
+ if (chartTextWidth(content, attrs2, options2) <= maxWidth) return content;
6548
7665
  const points = [...content];
6549
7666
  let low = 0;
6550
7667
  let high = points.length;
6551
7668
  while (low < high) {
6552
7669
  const mid = Math.ceil((low + high) / 2);
6553
- if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options) <= maxWidth) low = mid;
7670
+ if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options2) <= maxWidth) low = mid;
6554
7671
  else high = mid - 1;
6555
7672
  }
6556
7673
  return `${points.slice(0, low).join("")}\u2026`;
6557
7674
  }
6558
7675
 
6559
7676
  // chart/render/chart-svg-legend.ts
6560
- function chartLegendSvg(model, area, frame, options) {
7677
+ function chartLegendSvg(model, area, frame, options2) {
6561
7678
  const automatic = [];
6562
7679
  const bounds = {};
6563
- const reserved = automaticLegend(model, area, automatic, options, bounds);
7680
+ const reserved = automaticLegend(model, area, automatic, options2, bounds);
6564
7681
  const plot = model.legendOverlay ? area : reserved;
6565
7682
  const box = bounds.box;
6566
7683
  if (!box) return { plot, markup: "", foreground: false };
@@ -6574,11 +7691,11 @@ function chartLegendSvg(model, area, frame, options) {
6574
7691
  const entries = legendEntries(model);
6575
7692
  const attrs2 = chartTextAttributes(model, "legend");
6576
7693
  const size = attrs2.size ?? 10;
6577
- const font = chartFontMetrics(attrs2, options);
7694
+ const font = chartFontMetrics(attrs2, options2);
6578
7695
  const keySize = size / 2;
6579
7696
  const keyGap = size / 4;
6580
7697
  const widths = entries.map(
6581
- (entry) => chartTextWidth(entry.label, attrs2, options) + keySize + keyGap
7698
+ (entry) => chartTextWidth(entry.label, attrs2, options2) + keySize + keyGap
6582
7699
  );
6583
7700
  const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
6584
7701
  const rowWidth = horizontal ? manual.width / entries.length : manual.width;
@@ -6593,8 +7710,8 @@ function chartLegendSvg(model, area, frame, options) {
6593
7710
  ];
6594
7711
  const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
6595
7712
  entries.forEach((entry, i) => {
6596
- const available = horizontal ? chartTextWidth(entry.label, attrs2, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
6597
- const label = fitChartText(entry.label, available, attrs2, options);
7713
+ const available = horizontal ? chartTextWidth(entry.label, attrs2, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
7714
+ const label = fitChartText(entry.label, available, attrs2, options2);
6598
7715
  const contentWidth = Math.min(
6599
7716
  horizontal ? widths[i] ?? 0 : Math.max(...widths),
6600
7717
  rowWidth - size / 2
@@ -6637,7 +7754,7 @@ function legendEntries(model) {
6637
7754
  color: s.color
6638
7755
  }));
6639
7756
  }
6640
- function automaticLegend(model, area, out, options, bounds) {
7757
+ function automaticLegend(model, area, out, options2, bounds) {
6641
7758
  const entries = legendEntries(model);
6642
7759
  if (!model.showLegend || entries.length === 0) return area;
6643
7760
  const pos = model.legendPosition;
@@ -6646,7 +7763,7 @@ function automaticLegend(model, area, out, options, bounds) {
6646
7763
  const rowH = Math.max(16, size * 1.4);
6647
7764
  if (pos === "t" || pos === "b") {
6648
7765
  const widths = entries.map(
6649
- (e) => Math.min(chartTextWidth(e.label, attrs2, options) + 20, area.w / 2)
7766
+ (e) => Math.min(chartTextWidth(e.label, attrs2, options2) + 20, area.w / 2)
6650
7767
  );
6651
7768
  const total = widths.reduce((a, b) => a + b, 0);
6652
7769
  let x2 = area.x + Math.max(0, (area.w - total) / 2);
@@ -6663,14 +7780,14 @@ function automaticLegend(model, area, out, options, bounds) {
6663
7780
  entries.forEach((e, i) => {
6664
7781
  const w = widths[i] ?? 0;
6665
7782
  out.push(rect(x2, y, 8, 8, e.color));
6666
- out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options), attrs2));
7783
+ out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options2), attrs2));
6667
7784
  x2 += w;
6668
7785
  });
6669
7786
  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 };
6670
7787
  }
6671
7788
  const width = Math.min(
6672
7789
  area.w * 0.35,
6673
- Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options))) + 22
7790
+ Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options2))) + 22
6674
7791
  );
6675
7792
  const height = entries.length * rowH;
6676
7793
  const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
@@ -6688,24 +7805,24 @@ function automaticLegend(model, area, out, options, bounds) {
6688
7805
  const y = y0 + i * rowH;
6689
7806
  if (y + rowH > area.y + area.h + 2) return;
6690
7807
  out.push(rect(x, y + 3, 8, 8, e.color));
6691
- out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options), attrs2));
7808
+ out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options2), attrs2));
6692
7809
  });
6693
7810
  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 };
6694
7811
  }
6695
7812
 
6696
7813
  // text/wrap-styled-runs.ts
6697
7814
  var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
6698
- function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
7815
+ function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
6699
7816
  const groups = [];
6700
7817
  for (const [source, run] of runs.entries()) {
6701
7818
  for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
6702
7819
  const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
6703
- let group = groups.at(-1);
6704
- if (!group || group.kind !== kind || kind === "break") {
6705
- group = { kind, pieces: [] };
6706
- groups.push(group);
7820
+ let group2 = groups.at(-1);
7821
+ if (!group2 || group2.kind !== kind || kind === "break") {
7822
+ group2 = { kind, pieces: [] };
7823
+ groups.push(group2);
6707
7824
  }
6708
- if (kind !== "break") group.pieces.push({ run, source, text: token });
7825
+ if (kind !== "break") group2.pieces.push({ run, source, text: token });
6709
7826
  }
6710
7827
  }
6711
7828
  const merged = (left, right) => {
@@ -6718,7 +7835,7 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
6718
7835
  return result2;
6719
7836
  };
6720
7837
  const width = (pieces) => pieces.reduce((sum, piece) => {
6721
- const advance = measure(piece.text, piece.run);
7838
+ const advance = measure2(piece.text, piece.run);
6722
7839
  return sum + (Number.isFinite(advance) && advance >= 0 ? advance : 0);
6723
7840
  }, 0);
6724
7841
  const result = [];
@@ -6729,29 +7846,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
6729
7846
  line2 = [];
6730
7847
  spaces = [];
6731
7848
  };
6732
- for (const group of groups) {
6733
- if (group.kind === "break") {
7849
+ for (const group2 of groups) {
7850
+ if (group2.kind === "break") {
6734
7851
  flush();
6735
7852
  continue;
6736
7853
  }
6737
- if (group.kind === "space") {
6738
- spaces = group.pieces;
7854
+ if (group2.kind === "space") {
7855
+ spaces = group2.pieces;
6739
7856
  continue;
6740
7857
  }
6741
7858
  const separator = line2.length ? spaces : [];
6742
- const wordWidth = width(group.pieces);
6743
- if (line2.length && width(merged(line2, [...separator, ...group.pieces])) > maxWidth) flush();
7859
+ const wordWidth = width(group2.pieces);
7860
+ if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
6744
7861
  else line2 = merged(line2, separator);
6745
7862
  spaces = [];
6746
- if (options.breakWords && wordWidth > maxWidth) {
6747
- for (const piece of group.pieces) {
7863
+ if (options2.breakWords && wordWidth > maxWidth) {
7864
+ for (const piece of group2.pieces) {
6748
7865
  for (const { segment: segment2 } of graphemes.segment(piece.text)) {
6749
7866
  const next = { ...piece, text: segment2 };
6750
7867
  if (line2.length && width(merged(line2, [next])) > maxWidth) flush();
6751
7868
  line2 = merged(line2, [next]);
6752
7869
  }
6753
7870
  }
6754
- } else line2 = merged(line2, group.pieces);
7871
+ } else line2 = merged(line2, group2.pieces);
6755
7872
  }
6756
7873
  flush();
6757
7874
  return result;
@@ -6761,11 +7878,11 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
6761
7878
  function spacing(value, naturalHeight, fallback) {
6762
7879
  return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
6763
7880
  }
6764
- function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7881
+ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
6765
7882
  if (!model.title) return void 0;
6766
7883
  const base = chartTextAttributes(model, "title", 14);
6767
7884
  const capacity = Math.max(1, width * 0.8 - 8);
6768
- if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options) <= capacity)
7885
+ if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
6769
7886
  return void 0;
6770
7887
  const paragraphs = model.titleText?.paragraphs ?? [
6771
7888
  {
@@ -6801,7 +7918,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
6801
7918
  "title",
6802
7919
  base.size
6803
7920
  ),
6804
- options
7921
+ options2
6805
7922
  ),
6806
7923
  { breakWords: true }
6807
7924
  );
@@ -6825,10 +7942,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
6825
7942
  return {
6826
7943
  ...line2,
6827
7944
  runs,
6828
- width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options), 0),
7945
+ width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
6829
7946
  size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
6830
7947
  fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
6831
- (attrs2) => chartFontMetrics(attrs2, options)
7948
+ (attrs2) => chartFontMetrics(attrs2, options2)
6832
7949
  )
6833
7950
  };
6834
7951
  });
@@ -6866,7 +7983,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
6866
7983
  anchor: "start"
6867
7984
  }).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
6868
7985
  );
6869
- x += chartTextWidth(run.text, run.attrs, options);
7986
+ x += chartTextWidth(run.text, run.attrs, options2);
6870
7987
  }
6871
7988
  }
6872
7989
  const parent = text(0, 0, "", { ...base, underline: false }).replace(
@@ -6892,7 +8009,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
6892
8009
  }
6893
8010
 
6894
8011
  // chart/render/chart-svg.ts
6895
- function renderChartSvg(model, width, height, options = {}) {
8012
+ function renderChartSvg(model, width, height, options2 = {}) {
6896
8013
  const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
6897
8014
  model = paint2.model;
6898
8015
  const w = Math.max(1, width);
@@ -6906,7 +8023,7 @@ function renderChartSvg(model, width, height, options = {}) {
6906
8023
  if (paint2.defs) out.push(paint2.defs);
6907
8024
  out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
6908
8025
  let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
6909
- const richTitle = chartRichTitleSvg(model, w, options, h);
8026
+ const richTitle = chartRichTitleSvg(model, w, options2, h);
6910
8027
  if (richTitle) {
6911
8028
  if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
6912
8029
  else out.push(richTitle.markup);
@@ -6915,9 +8032,9 @@ function renderChartSvg(model, width, height, options = {}) {
6915
8032
  } else if (model.title) {
6916
8033
  const attrs2 = chartTextAttributes(model, "title", 14);
6917
8034
  const size = attrs2.size ?? 14;
6918
- const label = fitChartText(model.title, w - 16, attrs2, options);
6919
- const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options) + 8);
6920
- const font = chartFontMetrics(attrs2, options);
8035
+ const label = fitChartText(model.title, w - 16, attrs2, options2);
8036
+ const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options2) + 8);
8037
+ const font = chartFontMetrics(attrs2, options2);
6921
8038
  const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
6922
8039
  out.push(
6923
8040
  chartAreaRect(model, "title", {
@@ -6945,7 +8062,7 @@ function renderChartSvg(model, width, height, options = {}) {
6945
8062
  out.push("</svg>");
6946
8063
  return out.join("");
6947
8064
  }
6948
- const legend = chartLegendSvg(model, area, { width: w, height: h }, options);
8065
+ const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
6949
8066
  area = legend.plot;
6950
8067
  if (!legend.foreground) out.push(legend.markup);
6951
8068
  if (area.w > 4 && area.h > 4) {
@@ -6992,8 +8109,8 @@ function chartSpaceKind(space) {
6992
8109
  const type = chartSummaryFromSpace(space).chartType;
6993
8110
  return { type, drawn: DRAWN_CHART_TYPES.has(type) };
6994
8111
  }
6995
- function renderChartSpaceSvg(space, options) {
6996
- const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options;
8112
+ function renderChartSpaceSvg(space, options2) {
8113
+ const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
6997
8114
  const summary = chartSummaryFromSpace(space, {
6998
8115
  ...formatting ? { formatting } : {},
6999
8116
  ...colorPalette !== void 0 ? { colorPalette } : {},
@@ -7002,8 +8119,8 @@ function renderChartSpaceSvg(space, options) {
7002
8119
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
7003
8120
  return renderChartSvg(view, width, height, svg);
7004
8121
  }
7005
- function renderChartSummarySvg(summary, options) {
7006
- const { width, height, theme, fonts, ...svg } = options;
8122
+ function renderChartSummarySvg(summary, options2) {
8123
+ const { width, height, theme, fonts, ...svg } = options2;
7007
8124
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
7008
8125
  return renderChartSvg(view, width, height, svg);
7009
8126
  }
@@ -7931,30 +9048,30 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
7931
9048
  const output = [];
7932
9049
  let index = 0;
7933
9050
  while (index < runs.length) {
7934
- const group = containerGroup(runAt(index));
7935
- if (!group) {
9051
+ const group2 = containerGroup(runAt(index));
9052
+ if (!group2) {
7936
9053
  output.push(...nodesFor(index));
7937
9054
  index++;
7938
9055
  continue;
7939
9056
  }
7940
9057
  const start = index;
7941
- while (index < runs.length && sameGroup(containerGroup(runAt(index)), group)) index++;
9058
+ while (index < runs.length && sameGroup(containerGroup(runAt(index)), group2)) index++;
7942
9059
  const oldContainers = new Set(slots.slice(start, index).map((slot) => slot?.container));
7943
9060
  const [onlyContainer] = oldContainers;
7944
- oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (group.kind === "link" ? "hyperlink" : group.kind === "control" ? "sdt" : "fldSimple") && base?.slice(start, index).every((run) => sameGroup(run && containerGroup(run), group)) === true;
9061
+ oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (group2.kind === "link" ? "hyperlink" : group2.kind === "control" ? "sdt" : "fldSimple") && base?.slice(start, index).every((run) => sameGroup(run && containerGroup(run), group2)) === true;
7945
9062
  let container;
7946
9063
  let target;
7947
- if (group.kind === "control") {
7948
- const created = createContentControl(doc, group.control);
9064
+ if (group2.kind === "control") {
9065
+ const created = createContentControl(doc, group2.control);
7949
9066
  container = created.sdt;
7950
9067
  target = created.content;
7951
- } else if (group.kind === "link") container = newHyperlink(doc, group.link);
9068
+ } else if (group2.kind === "link") container = newHyperlink(doc, group2.link);
7952
9069
  else {
7953
9070
  container = makeW(doc, "fldSimple");
7954
- setW2(container, "instr", ` ${group.instr} `);
9071
+ setW2(container, "instr", ` ${group2.instr} `);
7955
9072
  }
7956
- if (group.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
7957
- const edges = group.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
9073
+ if (group2.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
9074
+ const edges = group2.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
7958
9075
  for (let item = start; item < index; item++)
7959
9076
  for (const node of nodesFor(item)) (target ?? container).appendChild(node);
7960
9077
  output.push(...edges.before, container, ...edges.after);
@@ -8152,11 +9269,11 @@ function createParagraph(doc, paragraph, allocator, spans) {
8152
9269
 
8153
9270
  // docx/numbering-parse.ts
8154
9271
  var own = (map, key) => Object.prototype.hasOwnProperty.call(map, key) ? map[key] : void 0;
8155
- function resolveNumberingLevel(catalog, numId, level) {
9272
+ function resolveNumberingLevel(catalog, numId, level2) {
8156
9273
  const num = own(catalog.nums, numId);
8157
9274
  if (!num) return void 0;
8158
- const override = num.levelOverrides?.[level];
8159
- const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level];
9275
+ const override = num.levelOverrides?.[level2];
9276
+ const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level2];
8160
9277
  const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
8161
9278
  let base = override?.lvl ?? abstract;
8162
9279
  if (!base) return void 0;
@@ -8264,10 +9381,10 @@ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
8264
9381
  const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
8265
9382
  if (!inherited || inherited.numId <= 0) return void 0;
8266
9383
  if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
8267
- for (let level = 0; level < 9; level++) {
8268
- const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level);
9384
+ for (let level2 = 0; level2 < 9; level2++) {
9385
+ const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level2);
8269
9386
  if (definition?.paragraphStyleId === paragraph.style)
8270
- return { numId: inherited.numId, level };
9387
+ return { numId: inherited.numId, level: level2 };
8271
9388
  }
8272
9389
  }
8273
9390
  return inherited;
@@ -8492,7 +9609,7 @@ var rejectAllRevisions = (model) => applyAll(model, rejectRevision);
8492
9609
  // docx/field-date.ts
8493
9610
  var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
8494
9611
  function formatWordDate(date, picture, locale = "en-US") {
8495
- const name = (options) => new Intl.DateTimeFormat(locale, options).format(date);
9612
+ const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
8496
9613
  const pad = (value) => String(value).padStart(2, "0");
8497
9614
  const hours12 = date.getHours() % 12 || 12;
8498
9615
  return picture.replace(TOKENS, (token) => {
@@ -8572,9 +9689,9 @@ function resolveCellVisuals(table, cell, placement, styles) {
8572
9689
  }
8573
9690
 
8574
9691
  // docx/section-layout.ts
8575
- function sectionLayoutJson(sections) {
9692
+ function sectionLayoutJson(sections2) {
8576
9693
  return JSON.stringify(
8577
- sections.map(({ headers: _headers, footers: _footers, ...layout }) => layout)
9694
+ sections2.map(({ headers: _headers, footers: _footers, ...layout }) => layout)
8578
9695
  );
8579
9696
  }
8580
9697
  function sectionsFromLayout(json, prior, blocks) {
@@ -10145,11 +11262,11 @@ function wordYjsDocumentAttributes(attrs2, canWrite) {
10145
11262
  }
10146
11263
  var wordYjsPluginKey = new PluginKey("docx-yjs");
10147
11264
  var WordYjsCollaboration = class {
10148
- constructor(session, initial, options) {
11265
+ constructor(session, initial, options2) {
10149
11266
  this.session = session;
10150
11267
  if (!session.synced)
10151
11268
  throw new Error("Wait for initial provider synchronization before joining Word.");
10152
- if (!options.documentId.trim()) throw new Error("A matching source documentId is required.");
11269
+ if (!options2.documentId.trim()) throw new Error("A matching source documentId is required.");
10153
11270
  this.fragment = session.doc.getXmlFragment("docx:body");
10154
11271
  this.media = new WordYjsMedia(session);
10155
11272
  this.attributes = session.doc.getMap("docx:attributes");
@@ -10165,17 +11282,17 @@ var WordYjsCollaboration = class {
10165
11282
  () => this.sharedInlineComments
10166
11283
  );
10167
11284
  if (!identity.has("documentId")) {
10168
- if (!options.initializeIfEmpty || !session.canWrite() || this.fragment.length)
11285
+ if (!options2.initializeIfEmpty || !session.canWrite() || this.fragment.length)
10169
11286
  throw new Error("The Word room has not been initialized by its designated creator.");
10170
11287
  session.doc.transact(() => {
10171
- for (const [name, part] of options.initialMedia ?? []) this.media.publish(name, part);
10172
- identity.set("documentId", options.documentId);
11288
+ for (const [name, part] of options2.initialMedia ?? []) this.media.publish(name, part);
11289
+ identity.set("documentId", options2.documentId);
10173
11290
  identity.set("format", format);
10174
11291
  identity.set(
10175
11292
  "comments",
10176
11293
  format === "word-yjs-v3" ? "inline-relative-v1" : "independent-v1"
10177
11294
  );
10178
- for (const comment of options.initialComments ?? []) {
11295
+ for (const comment of options2.initialComments ?? []) {
10179
11296
  this.comments.records.set(comment.id, { ...comment });
10180
11297
  if (comment.resolved !== void 0)
10181
11298
  this.comments.resolved.set(comment.id, comment.resolved);
@@ -10189,7 +11306,7 @@ var WordYjsCollaboration = class {
10189
11306
  this.comments.inlineAnchors.seed(doc, mapping);
10190
11307
  }
10191
11308
  }, this);
10192
- } else if (identity.get("documentId") !== options.documentId) {
11309
+ } else if (identity.get("documentId") !== options2.documentId) {
10193
11310
  throw new Error("Load the matching source package before joining this Word room.");
10194
11311
  } else if (identity.get("format") !== format) {
10195
11312
  throw new Error("Unsupported Word collaboration room format.");
@@ -10232,7 +11349,7 @@ var WordYjsCollaboration = class {
10232
11349
  this.session.doc.transact(() => seedEmptyParagraphText(this.fragment), this);
10233
11350
  };
10234
11351
  /** Fresh plugins per live view; the Y.Doc and local undo history survive view teardown. */
10235
- state(schema, options = {}) {
11352
+ state(schema, options2 = {}) {
10236
11353
  if (this.destroyed) throw new Error("The Word Yjs binding has been destroyed.");
10237
11354
  if (wordInlinePropertyCodec(schema) !== this.roomFormat)
10238
11355
  throw new Error("Unsupported Word collaboration schema for this room format.");
@@ -10262,8 +11379,8 @@ var WordYjsCollaboration = class {
10262
11379
  const unguard = binding ? guardDeletedNodeSelection(this.session.doc, view, binding) : () => {
10263
11380
  };
10264
11381
  const originalVisibility = binding?._isDomSelectionInView;
10265
- if (binding && options.selectionVisible)
10266
- binding._isDomSelectionInView = () => options.selectionVisible(view);
11382
+ if (binding && options2.selectionVisible)
11383
+ binding._isDomSelectionInView = () => options2.selectionVisible(view);
10267
11384
  const added = ({ stackItem }) => {
10268
11385
  const binding2 = ySyncPluginKey.getState(view.state)?.binding;
10269
11386
  if (binding2) stackItem.meta.set(this.selectionKey, this.previousSelection);
@@ -10336,8 +11453,8 @@ function isWordYjsRemoteTransaction(transaction) {
10336
11453
  transaction.getMeta("dve-remote") || transaction.getMeta(ySyncPluginKey)?.isChangeOrigin
10337
11454
  );
10338
11455
  }
10339
- function wordYjsPresencePlugin(session, options) {
10340
- return yCursorPlugin(session.awareness, options);
11456
+ function wordYjsPresencePlugin(session, options2) {
11457
+ return yCursorPlugin(session.awareness, options2);
10341
11458
  }
10342
11459
  function refreshWordYjsPresence(state) {
10343
11460
  return state.tr.setMeta(yCursorPluginKey, { awarenessUpdated: true });
@@ -10421,9 +11538,9 @@ var SectionPartsStep = class _SectionPartsStep extends DocAttrStep {
10421
11538
  return new _SectionPartsStep(doc.attrs.sectionParts);
10422
11539
  }
10423
11540
  };
10424
- function sectionPartsJson(sections) {
11541
+ function sectionPartsJson(sections2) {
10425
11542
  return JSON.stringify(
10426
- (sections ?? []).map(({ endsAtBlockId, headers, footers }) => ({
11543
+ (sections2 ?? []).map(({ endsAtBlockId, headers, footers }) => ({
10427
11544
  endsAtBlockId,
10428
11545
  ...headers ? { headers } : {},
10429
11546
  ...footers ? { footers } : {}
@@ -11428,9 +12545,9 @@ function safeParagraph(node, allowInsertion = false) {
11428
12545
  function endsSection(state, node) {
11429
12546
  if (typeof state.doc.attrs.sections !== "string") return false;
11430
12547
  try {
11431
- const sections = JSON.parse(state.doc.attrs.sections);
11432
- return sections.some(
11433
- (section, index) => section.endsAtBlockId === node.attrs.id && (index < sections.length - 1 || state.doc.lastChild !== node)
12548
+ const sections2 = JSON.parse(state.doc.attrs.sections);
12549
+ return sections2.some(
12550
+ (section, index) => section.endsAtBlockId === node.attrs.id && (index < sections2.length - 1 || state.doc.lastChild !== node)
11434
12551
  );
11435
12552
  } catch {
11436
12553
  return true;
@@ -11727,8 +12844,8 @@ function resolveParagraphMarkRange(tr, pos, mode) {
11727
12844
  const $next = tr.doc.resolve(nextPos);
11728
12845
  const following = $next.nodeAfter;
11729
12846
  if (!keepBreak && typeof tr.doc.attrs.sections === "string") {
11730
- const sections = JSON.parse(tr.doc.attrs.sections);
11731
- if (sections.some((section) => section.endsAtBlockId === current.id))
12847
+ const sections2 = JSON.parse(tr.doc.attrs.sections);
12848
+ if (sections2.some((section) => section.endsAtBlockId === current.id))
11732
12849
  throw new Error("Cannot resolve a paragraph mark across a section boundary.");
11733
12850
  }
11734
12851
  const blocks = [current];
@@ -12438,7 +13555,7 @@ function normalizeRibbonActions(input) {
12438
13555
  }
12439
13556
 
12440
13557
  // docx/ui/ribbon-colors.ts
12441
- var NAMED_COLORS = {
13558
+ var NAMED_COLORS2 = {
12442
13559
  yellow: "#ffff00",
12443
13560
  green: "#00ff00",
12444
13561
  cyan: "#00ffff",
@@ -12457,7 +13574,7 @@ var NAMED_COLORS = {
12457
13574
  white: "#ffffff"
12458
13575
  };
12459
13576
  function swatchColor(value) {
12460
- return value === "none" ? "transparent" : NAMED_COLORS[value] ?? value;
13577
+ return value === "none" ? "transparent" : NAMED_COLORS2[value] ?? value;
12461
13578
  }
12462
13579
 
12463
13580
  // docx/ui/run-compare.ts
@@ -13157,7 +14274,7 @@ var newControlId = (doc) => {
13157
14274
  while (used.has(id));
13158
14275
  return id;
13159
14276
  };
13160
- function insertContentControl(state, kind, options = {}) {
14277
+ function insertContentControl(state, kind, options2 = {}) {
13161
14278
  const type = state.schema.marks.contentControl;
13162
14279
  if (!type) return void 0;
13163
14280
  const { selection } = state;
@@ -13165,10 +14282,10 @@ function insertContentControl(state, kind, options = {}) {
13165
14282
  id: newControlId(state.doc),
13166
14283
  level: "inline",
13167
14284
  kind,
13168
- ...options.alias ? { alias: options.alias } : {},
13169
- ...options.tag ? { tag: options.tag } : {},
13170
- ...options.items ? { items: options.items } : {},
13171
- ...kind === "date" ? { dateFormat: options.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
14285
+ ...options2.alias ? { alias: options2.alias } : {},
14286
+ ...options2.tag ? { tag: options2.tag } : {},
14287
+ ...options2.items ? { items: options2.items } : {},
14288
+ ...kind === "date" ? { dateFormat: options2.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
13172
14289
  };
13173
14290
  const wrapsText = !selection.empty && (kind === "richText" || kind === "text");
13174
14291
  if (wrapsText) {