ooxml-core 1.18.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 (82) hide show
  1. package/dist/{PptxHandler-X6AO6LKJ.mjs → PptxHandler-5GBBVJCR.mjs} +2 -2
  2. package/dist/{PptxHandler-5X4VOWAO.mjs → PptxHandler-H43MAMTO.mjs} +1 -1
  3. package/dist/{PptxHandler-4AHDZDA5.cjs → PptxHandler-ZHPGBSAF.cjs} +2 -2
  4. package/dist/{PresentationBuilder-UY3S4YE2.mjs → PresentationBuilder-7ZSUKCX5.mjs} +1 -1
  5. package/dist/{PresentationBuilder-LRX55PXA.mjs → PresentationBuilder-IJW42L3R.mjs} +2 -2
  6. package/dist/{PresentationBuilder-MJB4LIFS.cjs → PresentationBuilder-O4H4MMWB.cjs} +4 -4
  7. package/dist/automation/index.cjs +535 -266
  8. package/dist/automation/index.mjs +535 -266
  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/index.cjs +815 -165
  18. package/dist/chart/index.d.ts +6 -0
  19. package/dist/chart/index.d.ts.map +1 -1
  20. package/dist/chart/index.mjs +795 -166
  21. package/dist/chart/line-dash.d.ts +2 -0
  22. package/dist/chart/line-dash.d.ts.map +1 -0
  23. package/dist/chart/marker-shape.d.ts +70 -0
  24. package/dist/chart/marker-shape.d.ts.map +1 -0
  25. package/dist/chart/render/chart-svg-axes.d.ts +9 -0
  26. package/dist/chart/render/chart-svg-axes.d.ts.map +1 -0
  27. package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
  28. package/dist/chart/render/chart-svg-markers.d.ts +6 -0
  29. package/dist/chart/render/chart-svg-markers.d.ts.map +1 -0
  30. package/dist/chart/render/chart-svg-radial.d.ts.map +1 -1
  31. package/dist/chart/render/chart-svg-xy.d.ts.map +1 -1
  32. package/dist/chart/render/chart-view-axes.d.ts +30 -0
  33. package/dist/chart/render/chart-view-axes.d.ts.map +1 -0
  34. package/dist/chart/render/chart-view-markers.d.ts +27 -0
  35. package/dist/chart/render/chart-view-markers.d.ts.map +1 -0
  36. package/dist/chart/render/chart-view-series.d.ts.map +1 -1
  37. package/dist/chart/render/chart-view.d.ts +4 -1
  38. package/dist/chart/render/chart-view.d.ts.map +1 -1
  39. package/dist/chart/render/index.d.ts +2 -0
  40. package/dist/chart/render/index.d.ts.map +1 -1
  41. package/dist/chart/render/summary-from-space.d.ts.map +1 -1
  42. package/dist/chart/render/summary.d.ts +6 -1
  43. package/dist/chart/render/summary.d.ts.map +1 -1
  44. package/dist/{chunk-7NWQUCGX.mjs → chunk-3XFPCZKB.mjs} +1 -1
  45. package/dist/{chunk-Z5Y53IZD.mjs → chunk-75GLSRZE.mjs} +4 -4
  46. package/dist/{chunk-LT7RCEHY.mjs → chunk-BIVNVDAH.mjs} +1 -1
  47. package/dist/{chunk-I5ZE3VLI.mjs → chunk-QBJRB6WW.mjs} +1 -1
  48. package/dist/{chunk-U7IDT6VT.mjs → chunk-RUZEMWDI.mjs} +1 -1
  49. package/dist/docx/index.cjs +695 -168
  50. package/dist/docx/index.mjs +695 -168
  51. package/dist/docx/layout/index.cjs +697 -170
  52. package/dist/docx/layout/index.mjs +697 -170
  53. package/dist/docx/ui/index.cjs +704 -177
  54. package/dist/docx/ui/index.mjs +704 -177
  55. package/dist/index.cjs +912 -262
  56. package/dist/index.mjs +912 -262
  57. package/dist/pptx/automation/index.cjs +54 -0
  58. package/dist/pptx/automation/index.mjs +5 -5
  59. package/dist/pptx/cli/index.cjs +54 -0
  60. package/dist/pptx/cli/index.mjs +4 -4
  61. package/dist/pptx/converter/index.mjs +2 -2
  62. package/dist/pptx/editor/render/slide-operations.cjs +1 -1
  63. package/dist/pptx/editor/render/slide-operations.mjs +1 -1
  64. package/dist/pptx/index.cjs +54 -0
  65. package/dist/pptx/index.mjs +5 -5
  66. package/dist/teams/index.cjs +71 -5
  67. package/dist/teams/index.mjs +71 -5
  68. package/dist/visio/index.cjs +483 -214
  69. package/dist/visio/index.mjs +483 -214
  70. package/dist/visio/ui/index.cjs +504 -235
  71. package/dist/visio/ui/index.mjs +504 -235
  72. package/dist/xlsx/edit/chart-colors.d.ts.map +1 -1
  73. package/dist/xlsx/index.cjs +818 -281
  74. package/dist/xlsx/index.mjs +818 -281
  75. package/dist/xlsx/load/index.cjs +58 -5
  76. package/dist/xlsx/load/index.mjs +58 -5
  77. package/dist/xlsx/read/chart.d.ts.map +1 -1
  78. package/dist/xlsx/ui/index.cjs +835 -298
  79. package/dist/xlsx/ui/index.mjs +835 -298
  80. package/package.json +1 -1
  81. /package/dist/{chunk-C363NN2C.mjs → chunk-H6TNNXJK.mjs} +0 -0
  82. /package/dist/{chunk-R4BCOQHB.cjs → chunk-MHMVD23Y.cjs} +0 -0
@@ -826,11 +826,11 @@ function checkXmlLimits(xml, label, limits = {}) {
826
826
  throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
827
827
  }
828
828
  }
829
- function parseXml(xml, options = {}) {
830
- const label = options.label ?? "OOXML";
829
+ function parseXml(xml, options2 = {}) {
830
+ const label = options2.label ?? "OOXML";
831
831
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
832
832
  throw new Error(`${label} XML with DTD or entity declarations is not supported`);
833
- checkXmlLimits(xml, label, options.limits);
833
+ checkXmlLimits(xml, label, options2.limits);
834
834
  let parseError = "";
835
835
  let parsed;
836
836
  try {
@@ -1752,8 +1752,8 @@ function rgbToHsl(r, g, b) {
1752
1752
  }
1753
1753
  return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
1754
1754
  }
1755
- function hslToRgb(h, s, l, roundChannel = Math.round, options) {
1756
- const sC = options?.clampSaturation === false ? s : clampUnitInterval(s);
1755
+ function hslToRgb(h, s, l, roundChannel = Math.round, options2) {
1756
+ const sC = options2?.clampSaturation === false ? s : clampUnitInterval(s);
1757
1757
  const lC = clampUnitInterval(l);
1758
1758
  const hN = (h % 360 + 360) % 360;
1759
1759
  const c = (1 - Math.abs(2 * lC - 1)) * sC;
@@ -2242,13 +2242,13 @@ var APPLIED = /* @__PURE__ */ new Set([
2242
2242
  "lumMod",
2243
2243
  "lumOff"
2244
2244
  ]);
2245
- function resolveDrawingColor(color, theme, options) {
2245
+ function resolveDrawingColor(color, theme, options2) {
2246
2246
  const base = baseHex(color, theme);
2247
2247
  const rgb = base ? hexToRgbChannels(base) : null;
2248
2248
  if (!rgb) return void 0;
2249
- if (options?.transformOrder === "document") {
2249
+ if (options2?.transformOrder === "document") {
2250
2250
  const value = orderedColorTransforms(rgb, color.transforms);
2251
- const round = options.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
2251
+ const round = options2.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
2252
2252
  return {
2253
2253
  hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
2254
2254
  alpha: value.alpha,
@@ -2299,7 +2299,7 @@ function resolveDrawingColor(color, theme, options) {
2299
2299
  if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
2300
2300
  const lumOff = parseDrawingFraction(find("lumOff"));
2301
2301
  if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
2302
- const round = options?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
2302
+ const round = options2?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
2303
2303
  ({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
2304
2304
  }
2305
2305
  let alpha = parseDrawingPercent(find("alpha")) ?? 1;
@@ -3760,7 +3760,7 @@ function resolveInnerRect(fillToRect, focalPoint) {
3760
3760
  function lerpEdge(inner, outer, t) {
3761
3761
  return inner + (outer - inner) * t;
3762
3762
  }
3763
- function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
3763
+ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options2) {
3764
3764
  if (stops.length === 0) {
3765
3765
  return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
3766
3766
  }
@@ -3769,7 +3769,7 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
3769
3769
  const rects = [];
3770
3770
  const alphaRects = [];
3771
3771
  const masked = sorted.some((stop) => (stop.opacity ?? 1) < 1);
3772
- const bands = options?.bands;
3772
+ const bands = options2?.bands;
3773
3773
  if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
3774
3774
  for (let i = bands; i >= 0; i -= 1) {
3775
3775
  const t = i / bands;
@@ -4137,6 +4137,9 @@ function formatChartNumberWithColor(value, formatCode) {
4137
4137
  return void 0;
4138
4138
  }
4139
4139
  }
4140
+ function formatChartNumber(value, formatCode) {
4141
+ return formatChartNumberWithColor(value, formatCode)?.text;
4142
+ }
4140
4143
 
4141
4144
  // chart/data-label-text.ts
4142
4145
  var DATA_LABEL_SEPARATOR = ", ";
@@ -4185,12 +4188,12 @@ function composeDataLabelText(input) {
4185
4188
  }
4186
4189
 
4187
4190
  // chart/bubble-radius.ts
4188
- function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
4189
- const scale = (options?.bubbleScale ?? 100) / 100;
4191
+ function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options2) {
4192
+ const scale = (options2?.bubbleScale ?? 100) / 100;
4190
4193
  if (sizeVal === void 0) return medianRadius * scale;
4191
4194
  const denom = maxBubble > 0 ? maxBubble : 1;
4192
4195
  const magnitude = Math.abs(sizeVal);
4193
- const ratio = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
4196
+ const ratio = (options2?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
4194
4197
  return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
4195
4198
  }
4196
4199
  function maxBubbleSize(sizes) {
@@ -4518,14 +4521,14 @@ function scottBinCount(values, min, max) {
4518
4521
  const width = 3.49 * sd * values.length ** (-1 / 3);
4519
4522
  return Math.max(1, Math.ceil((max - min) / width));
4520
4523
  }
4521
- function computeHistogramBins(values, options, format = String) {
4522
- const closed = options.intervalClosed ?? "l";
4524
+ function computeHistogramBins(values, options2, format = String) {
4525
+ const closed = options2.intervalClosed ?? "l";
4523
4526
  const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
4524
4527
  if (finite2.length === 0) {
4525
4528
  return [];
4526
4529
  }
4527
- const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
4528
- const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
4530
+ const underflow = typeof options2.underflow === "number" ? options2.underflow : void 0;
4531
+ const overflow = typeof options2.overflow === "number" ? options2.overflow : void 0;
4529
4532
  const under = underflow === void 0 ? [] : finite2.filter(
4530
4533
  (item) => closed === "r" ? item.value <= underflow : item.value < underflow
4531
4534
  );
@@ -4542,8 +4545,8 @@ function computeHistogramBins(values, options, format = String) {
4542
4545
  if (regular.length > 0) {
4543
4546
  const min = Math.min(...regular.map((item) => item.value));
4544
4547
  const max = Math.max(...regular.map((item) => item.value));
4545
- const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
4546
- const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
4548
+ const requestedSize = options2.binSize && options2.binSize > 0 ? options2.binSize : void 0;
4549
+ const requestedCount = options2.binCount && options2.binCount > 0 ? options2.binCount : void 0;
4547
4550
  const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
4548
4551
  const count = requestedSize ? Math.max(
4549
4552
  closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
@@ -4594,9 +4597,9 @@ function aggregateByCategory(values, rawCategories) {
4594
4597
  }
4595
4598
 
4596
4599
  // chart/waterfall.ts
4597
- function buildWaterfallSteps(values, options) {
4600
+ function buildWaterfallSteps(values, options2) {
4598
4601
  const subtotalIndices = new Set(
4599
- options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
4602
+ options2?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
4600
4603
  );
4601
4604
  const steps = [];
4602
4605
  let runningTotal = 0;
@@ -4656,13 +4659,13 @@ var noFit = () => ({
4656
4659
  rSquared: 0,
4657
4660
  coefficients: []
4658
4661
  });
4659
- function fitModel(options, xVals, yVals) {
4662
+ function fitModel(options2, xVals, yVals) {
4660
4663
  const xs = [...xVals];
4661
4664
  const ys = [...yVals];
4662
- switch (options.kind) {
4665
+ switch (options2.kind) {
4663
4666
  case "linear": {
4664
4667
  const reg = computeLinearRegression(xs, ys);
4665
- const fixed = options.intercept;
4668
+ const fixed = options2.intercept;
4666
4669
  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;
4667
4670
  const b = fixed ?? reg.intercept;
4668
4671
  return {
@@ -4712,7 +4715,7 @@ function fitModel(options, xVals, yVals) {
4712
4715
  };
4713
4716
  }
4714
4717
  case "polynomial": {
4715
- const order = Math.min(options.order ?? 2, 6);
4718
+ const order = Math.min(options2.order ?? 2, 6);
4716
4719
  const coeffs = fitPolynomial(xs, ys, order);
4717
4720
  const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
4718
4721
  return {
@@ -4726,11 +4729,11 @@ function fitModel(options, xVals, yVals) {
4726
4729
  return void 0;
4727
4730
  }
4728
4731
  }
4729
- function fitChartTrendline(options, xVals, yVals) {
4732
+ function fitChartTrendline(options2, xVals, yVals) {
4730
4733
  const count = yVals.length;
4731
4734
  if (count < 2) return noFit();
4732
- if (options.kind === "movingAvg") {
4733
- const period = options.period ?? 2;
4735
+ if (options2.kind === "movingAvg") {
4736
+ const period = options2.period ?? 2;
4734
4737
  const points2 = [];
4735
4738
  for (let i = period - 1; i < count; i++) {
4736
4739
  let sum = 0;
@@ -4739,10 +4742,10 @@ function fitChartTrendline(options, xVals, yVals) {
4739
4742
  }
4740
4743
  return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
4741
4744
  }
4742
- const model = fitModel(options, xVals, yVals);
4745
+ const model = fitModel(options2, xVals, yVals);
4743
4746
  if (!model) return noFit();
4744
- const startX = Math.min(...xVals) - (options.backward ?? 0);
4745
- const endX = Math.max(...xVals) + (options.forward ?? 0);
4747
+ const startX = Math.min(...xVals) - (options2.backward ?? 0);
4748
+ const endX = Math.max(...xVals) + (options2.forward ?? 0);
4746
4749
  const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
4747
4750
  const points = [];
4748
4751
  for (let step = 0; step <= steps; step++) {
@@ -4765,18 +4768,18 @@ function chartSampleVariance(values) {
4765
4768
  const mean = values.reduce((sum, value) => sum + value, 0) / count;
4766
4769
  return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
4767
4770
  }
4768
- function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
4769
- switch (options.valueType) {
4771
+ function chartErrorBarAmount(options2, values, displayIndex, sourceIndex, side) {
4772
+ switch (options2.valueType) {
4770
4773
  case "fixedVal":
4771
- return options.value ?? 0;
4774
+ return options2.value ?? 0;
4772
4775
  case "percentage":
4773
- return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
4776
+ return Math.abs(values[displayIndex] ?? 0) * ((options2.value ?? 0) / 100);
4774
4777
  case "stdDev":
4775
- return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
4778
+ return Math.sqrt(chartSampleVariance(values)) * (options2.value ?? 1);
4776
4779
  case "stdErr":
4777
4780
  return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
4778
4781
  case "cust":
4779
- return side === "plus" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
4782
+ return side === "plus" ? options2.customPlus?.[sourceIndex] ?? 0 : options2.customMinus?.[sourceIndex] ?? 0;
4780
4783
  }
4781
4784
  }
4782
4785
 
@@ -5197,6 +5200,191 @@ function drawingLineXml(line2) {
5197
5200
  return buildXml(doc);
5198
5201
  }
5199
5202
 
5203
+ // chart/marker-shape.ts
5204
+ var CHART_PX_PER_PT = 4 / 3;
5205
+ var DEFAULT_MARKER_OUTLINE_PT = 0.75;
5206
+ var AUTOMATIC_MARKER_CYCLE = [
5207
+ "diamond",
5208
+ "square",
5209
+ "triangle",
5210
+ "x",
5211
+ "star",
5212
+ "circle",
5213
+ "plus",
5214
+ "dot",
5215
+ "dash"
5216
+ ];
5217
+ function automaticMarkerSymbol(seriesIdx) {
5218
+ const length = AUTOMATIC_MARKER_CYCLE.length;
5219
+ const normalized = (Math.trunc(seriesIdx) % length + length) % length;
5220
+ return AUTOMATIC_MARKER_CYCLE[Number.isFinite(normalized) ? normalized : 0];
5221
+ }
5222
+ function markerRadius(size, defaultRadius) {
5223
+ if (size === void 0 || !Number.isFinite(size) || size <= 0) {
5224
+ return defaultRadius;
5225
+ }
5226
+ return size / 2;
5227
+ }
5228
+ function polygonPoints(vertices) {
5229
+ return vertices.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
5230
+ }
5231
+ function starVertices(cx, cy, r) {
5232
+ const inner = r * 0.5;
5233
+ const out = [];
5234
+ for (let i = 0; i < 10; i++) {
5235
+ const radius = i % 2 === 0 ? r : inner;
5236
+ const angle = -Math.PI / 2 + Math.PI * i / 5;
5237
+ out.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
5238
+ }
5239
+ return out;
5240
+ }
5241
+ function rectPolygon(x, y, w, h) {
5242
+ return polygonPoints([
5243
+ [x, y],
5244
+ [x + w, y],
5245
+ [x + w, y + h],
5246
+ [x, y + h]
5247
+ ]);
5248
+ }
5249
+ function buildMarkerPrimitive(input) {
5250
+ const { symbol, cx, cy, fill } = input;
5251
+ const part = input.part === void 0 ? {} : { part: input.part };
5252
+ if (symbol === "none") {
5253
+ return null;
5254
+ }
5255
+ const r = markerRadius(input.size, input.defaultRadius);
5256
+ const outline2 = input.stroke ? {
5257
+ stroke: input.stroke,
5258
+ strokeWidth: input.strokeWidth ?? DEFAULT_MARKER_OUTLINE_PT * CHART_PX_PER_PT
5259
+ } : void 0;
5260
+ const polygonStroke = outline2 ?? { stroke: fill, strokeWidth: 0 };
5261
+ const lineStroke = input.stroke ?? fill;
5262
+ switch (symbol) {
5263
+ case "square":
5264
+ case "dash": {
5265
+ const h = symbol === "dash" ? r * 0.64 : r * 2;
5266
+ const y = cy - h / 2;
5267
+ if (outline2) {
5268
+ return {
5269
+ kind: "polygon",
5270
+ points: rectPolygon(cx - r, y, r * 2, h),
5271
+ fill,
5272
+ ...outline2,
5273
+ ...part
5274
+ };
5275
+ }
5276
+ return { kind: "rect", x: cx - r, y, w: r * 2, h, fill, ...part };
5277
+ }
5278
+ case "diamond":
5279
+ return {
5280
+ kind: "polygon",
5281
+ points: polygonPoints([
5282
+ [cx, cy - r],
5283
+ [cx + r, cy],
5284
+ [cx, cy + r],
5285
+ [cx - r, cy]
5286
+ ]),
5287
+ fill,
5288
+ ...polygonStroke,
5289
+ ...part
5290
+ };
5291
+ case "triangle":
5292
+ return {
5293
+ kind: "polygon",
5294
+ points: polygonPoints([
5295
+ [cx, cy - r],
5296
+ [cx + r * 0.9, cy + r * 0.75],
5297
+ [cx - r * 0.9, cy + r * 0.75]
5298
+ ]),
5299
+ fill,
5300
+ ...polygonStroke,
5301
+ ...part
5302
+ };
5303
+ case "star":
5304
+ return {
5305
+ kind: "polygon",
5306
+ points: polygonPoints(starVertices(cx, cy, r)),
5307
+ fill,
5308
+ ...polygonStroke,
5309
+ ...part
5310
+ };
5311
+ case "plus":
5312
+ return {
5313
+ kind: "path",
5314
+ 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)}`,
5315
+ fill: "none",
5316
+ stroke: lineStroke,
5317
+ strokeWidth: Math.max(1, r * 0.4),
5318
+ ...part
5319
+ };
5320
+ case "x":
5321
+ return {
5322
+ kind: "path",
5323
+ 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)}`,
5324
+ fill: "none",
5325
+ stroke: lineStroke,
5326
+ strokeWidth: Math.max(1, r * 0.4),
5327
+ ...part
5328
+ };
5329
+ case "dot":
5330
+ return { kind: "circle", cx, cy, r: Math.max(r * 0.6, 1), fill, ...part, ...outline2 };
5331
+ default:
5332
+ return { kind: "circle", cx, cy, r, fill, ...part, ...outline2 };
5333
+ }
5334
+ }
5335
+
5336
+ // chart/render/chart-view-markers.ts
5337
+ function summaryMarkers(source, group2, seriesPosition) {
5338
+ if (!["line", "scatter", "radar"].includes(group2.kind)) return {};
5339
+ const enabled2 = group2.kind === "line" ? group2.marker === true : group2.kind === "radar" ? group2.radarStyle === "marker" : !["line", "smooth", "none"].includes(group2.scatterStyle ?? "marker");
5340
+ const symbol = source.marker?.symbol;
5341
+ const marker = {
5342
+ ...source.marker,
5343
+ symbol: symbol && symbol !== "auto" ? symbol : source.marker || enabled2 ? automaticMarkerSymbol(source.index ?? seriesPosition) : "none"
5344
+ };
5345
+ const pointMarkers = {};
5346
+ for (const point of source.dataPoints) {
5347
+ if (point.index === void 0 || !point.marker) continue;
5348
+ const override = point.marker;
5349
+ pointMarkers[point.index] = {
5350
+ ...marker,
5351
+ ...override,
5352
+ ...override.symbol === "auto" || !source.marker && override.symbol === void 0 ? { symbol: automaticMarkerSymbol(source.index ?? seriesPosition) } : {},
5353
+ ...marker.spPr || override.spPr ? {
5354
+ spPr: {
5355
+ ...marker.spPr,
5356
+ ...override.spPr,
5357
+ ...marker.spPr?.line || override.spPr?.line ? { line: { ...marker.spPr?.line, ...override.spPr?.line } } : {}
5358
+ }
5359
+ } : {}
5360
+ };
5361
+ }
5362
+ return { marker, ...Object.keys(pointMarkers).length ? { pointMarkers } : {} };
5363
+ }
5364
+ function seriesMarkerViews(source, drawingColor) {
5365
+ const fillColor = (fill) => fill?.kind === "none" ? "none" : fill?.kind === "solid" ? drawingColor(fill.color) : void 0;
5366
+ const resolve = (marker) => {
5367
+ const fill = fillColor(marker.spPr?.fill);
5368
+ const stroke = fillColor(marker.spPr?.line?.fill);
5369
+ const width = marker.spPr?.line?.widthEmu;
5370
+ return {
5371
+ ...marker.symbol !== void 0 ? { symbol: marker.symbol } : {},
5372
+ ...marker.size !== void 0 ? { size: marker.size } : {},
5373
+ ...fill !== void 0 ? { fill } : {},
5374
+ ...stroke !== void 0 ? { stroke } : {},
5375
+ ...width !== void 0 ? { strokeWidth: width / 9525 } : {}
5376
+ };
5377
+ };
5378
+ return {
5379
+ ...source.marker ? { marker: resolve(source.marker) } : {},
5380
+ ...source.pointMarkers ? {
5381
+ pointMarkers: Object.fromEntries(
5382
+ Object.entries(source.pointMarkers).map(([i, marker]) => [i, resolve(marker)])
5383
+ )
5384
+ } : {}
5385
+ };
5386
+ }
5387
+
5200
5388
  // chart/render/summary-analysis.ts
5201
5389
  function summaryTrendline(source) {
5202
5390
  const kind = chartTrendlineKind(source.trendlineType);
@@ -5238,17 +5426,17 @@ function summaryAnalysis(series) {
5238
5426
  }
5239
5427
 
5240
5428
  // chart/render/summary-labels.ts
5241
- function level(options, custom) {
5429
+ function level(options2, custom) {
5242
5430
  const out = {};
5243
- if (options.deleted !== void 0) out.deleted = options.deleted;
5244
- if (options.showValue !== void 0) out.showValue = options.showValue;
5245
- if (options.showCategoryName !== void 0) out.showCategory = options.showCategoryName;
5246
- if (options.showSeriesName !== void 0) out.showSeriesName = options.showSeriesName;
5247
- if (options.showPercent !== void 0) out.showPercent = options.showPercent;
5248
- if (options.showBubbleSize !== void 0) out.showBubbleSize = options.showBubbleSize;
5249
- if (options.separator !== void 0) out.separator = options.separator;
5250
- if (options.position) out.position = options.position;
5251
- if (options.numberFormat?.formatCode) out.numberFormat = options.numberFormat.formatCode;
5431
+ if (options2.deleted !== void 0) out.deleted = options2.deleted;
5432
+ if (options2.showValue !== void 0) out.showValue = options2.showValue;
5433
+ if (options2.showCategoryName !== void 0) out.showCategory = options2.showCategoryName;
5434
+ if (options2.showSeriesName !== void 0) out.showSeriesName = options2.showSeriesName;
5435
+ if (options2.showPercent !== void 0) out.showPercent = options2.showPercent;
5436
+ if (options2.showBubbleSize !== void 0) out.showBubbleSize = options2.showBubbleSize;
5437
+ if (options2.separator !== void 0) out.separator = options2.separator;
5438
+ if (options2.position) out.position = options2.position;
5439
+ if (options2.numberFormat?.formatCode) out.numberFormat = options2.numberFormat.formatCode;
5252
5440
  if (custom?.text !== void 0) out.text = custom.text;
5253
5441
  return out;
5254
5442
  }
@@ -5355,7 +5543,10 @@ function extraGroups(chartSpace, firstType) {
5355
5543
  const type = group2.kind === "bar" ? "column" : group2.kind;
5356
5544
  const entry = {
5357
5545
  chartType: type,
5358
- series: group2.series.map((source) => chartSummarySeries(source, type, group2.dataLabels)),
5546
+ series: group2.series.map((source, index) => ({
5547
+ ...chartSummarySeries(source, type, group2.dataLabels),
5548
+ ...summaryMarkers(source, group2, index)
5549
+ })),
5359
5550
  secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
5360
5551
  };
5361
5552
  if (group2.grouping && GROUPINGS.has(group2.grouping))
@@ -5373,13 +5564,16 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
5373
5564
  const group2 = chartSpace.plotArea.groups[0];
5374
5565
  let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
5375
5566
  if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
5376
- const series = (group2?.series ?? []).map(
5377
- (source) => chartSummarySeries(source, chartType, group2?.dataLabels)
5378
- );
5567
+ const series = (group2?.series ?? []).map((source, index) => ({
5568
+ ...chartSummarySeries(source, chartType, group2?.dataLabels),
5569
+ ...group2 ? summaryMarkers(source, group2, index) : {}
5570
+ }));
5379
5571
  const summary = {
5380
5572
  chartType,
5381
5573
  series,
5382
- showLegend: chartSpace.legend !== void 0
5574
+ showLegend: chartSpace.legend !== void 0,
5575
+ axes: chartSpace.plotArea.axes,
5576
+ axisIds: group2?.axisIds ?? []
5383
5577
  };
5384
5578
  const combined = extraGroups(chartSpace, chartType);
5385
5579
  if (combined.length) summary.extraGroups = combined;
@@ -5681,7 +5875,7 @@ function chartTextAttributes(model, part, fallbackSize = FONT_SIZE) {
5681
5875
  function chartStroke(model, part) {
5682
5876
  const entry = model.appearance?.[part];
5683
5877
  return {
5684
- color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part === "gridlineMajor" ? GRID_COLOR : AXIS_COLOR),
5878
+ color: entry?.axisVisible === false ? "none" : entry?.lineColor ?? (part.startsWith("gridline") ? GRID_COLOR : AXIS_COLOR),
5685
5879
  width: entry?.lineWidth === void 0 ? 1 : chartPointsToPixels(entry.lineWidth)
5686
5880
  };
5687
5881
  }
@@ -5972,6 +6166,60 @@ function scatterAnalysis(model, px, py, out) {
5972
6166
  });
5973
6167
  }
5974
6168
 
6169
+ // chart/render/chart-svg-markers.ts
6170
+ function chartMarkerRadius(series, index, defaultRadius = 3) {
6171
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
6172
+ if (marker.symbol === "none") return 0;
6173
+ const radius = markerRadius(marker.size, defaultRadius);
6174
+ return marker.symbol === "dot" ? Math.max(radius * 0.6, 1) : radius;
6175
+ }
6176
+ function chartSeriesMarkerSvg(series, index, cx, cy, defaultRadius = 3) {
6177
+ const marker = { ...series.marker, ...series.pointMarkers?.[index] };
6178
+ const primitive = buildMarkerPrimitive({
6179
+ ...marker,
6180
+ symbol: marker.symbol,
6181
+ size: marker.size,
6182
+ cx,
6183
+ cy,
6184
+ fill: marker.fill ?? series.pointColors?.[index] ?? series.color,
6185
+ defaultRadius
6186
+ });
6187
+ if (!primitive) return "";
6188
+ let geometry2;
6189
+ switch (primitive.kind) {
6190
+ case "circle":
6191
+ geometry2 = `cx="${n(primitive.cx)}" cy="${n(primitive.cy)}" r="${n(primitive.r)}"`;
6192
+ break;
6193
+ case "rect":
6194
+ geometry2 = `x="${n(primitive.x)}" y="${n(primitive.y)}" width="${n(primitive.w)}" height="${n(primitive.h)}"`;
6195
+ break;
6196
+ case "path":
6197
+ geometry2 = `d="${esc(primitive.d)}"`;
6198
+ break;
6199
+ case "polygon":
6200
+ geometry2 = `points="${esc(primitive.points)}"`;
6201
+ break;
6202
+ }
6203
+ const outline2 = primitive.stroke ? ` stroke="${esc(primitive.stroke)}" stroke-width="${n(primitive.strokeWidth ?? 1)}"` : "";
6204
+ const filter = series.shadowFilter ? ` filter="${esc(series.shadowFilter)}"` : "";
6205
+ return `<${primitive.kind} ${geometry2} fill="${esc(primitive.fill)}"${outline2}${filter}/>`;
6206
+ }
6207
+
6208
+ // chart/line-dash.ts
6209
+ function chartLineDashArray(style, width) {
6210
+ if (!style || style === "solid") {
6211
+ return void 0;
6212
+ }
6213
+ const unit = Math.max(width, 1);
6214
+ if (style === "dot" || style === "sysDot") {
6215
+ return `${unit} ${unit * 2}`;
6216
+ }
6217
+ if (style === "lgDash") {
6218
+ return `${unit * 6} ${unit * 3}`;
6219
+ }
6220
+ return `${unit * 3} ${unit * 2}`;
6221
+ }
6222
+
5975
6223
  // chart/render/chart-scale.ts
5976
6224
  var clean = (n2) => Number(n2.toPrecision(12));
5977
6225
  function* units(raw) {
@@ -5982,14 +6230,14 @@ function* units(raw) {
5982
6230
  exp++;
5983
6231
  }
5984
6232
  }
5985
- function niceScale(dataMin, dataMax, options = {}) {
5986
- const maxIntervals = Math.max(1, options.maxIntervals ?? 10);
6233
+ function niceScale(dataMin, dataMax, options2 = {}) {
6234
+ const maxIntervals = Math.max(1, options2.maxIntervals ?? 10);
5987
6235
  let lo = Number.isFinite(dataMin) ? dataMin : 0;
5988
6236
  let hi = Number.isFinite(dataMax) ? dataMax : 0;
5989
6237
  if (lo > hi) [lo, hi] = [hi, lo];
5990
6238
  if (lo === hi) {
5991
6239
  if (lo === 0) hi = 1;
5992
- else if (options.noZero) {
6240
+ else if (options2.noZero) {
5993
6241
  const pad = Math.abs(lo) * 0.1 || 1;
5994
6242
  lo -= pad;
5995
6243
  hi += pad;
@@ -5998,7 +6246,7 @@ function niceScale(dataMin, dataMax, options = {}) {
5998
6246
  }
5999
6247
  let fixedLo = false;
6000
6248
  let fixedHi = false;
6001
- if (!options.noZero) {
6249
+ if (!options2.noZero) {
6002
6250
  if (lo >= 0 && hi - lo >= hi / 6) {
6003
6251
  lo = 0;
6004
6252
  fixedLo = true;
@@ -6038,6 +6286,233 @@ function formatAxisValue(value, percent = false) {
6038
6286
  return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
6039
6287
  }
6040
6288
 
6289
+ // chart/render/chart-svg-axes.ts
6290
+ function axisTickText(value, axis, percent = false) {
6291
+ return formatChartNumber(value, axis?.source.numberFormat?.formatCode) ?? formatAxisValue(value, percent);
6292
+ }
6293
+ function axisLine(model, axis, part, x1, y1, x2, y2) {
6294
+ if (axis?.source.deleted) return "";
6295
+ return styledAxisLine(x1, y1, x2, y2, axis?.line, chartStroke(model, part));
6296
+ }
6297
+ function styledAxisLine(x1, y1, x2, y2, paint2, fallback) {
6298
+ const color = paint2?.color ?? fallback.color;
6299
+ const width = paint2?.width ?? fallback.width;
6300
+ if (color === "none" || width === 0) return "";
6301
+ const dash = chartLineDashArray(paint2?.dash, width);
6302
+ return line(x1, y1, x2, y2, esc(color), width).replace(
6303
+ "/>",
6304
+ dash ? ` stroke-dasharray="${dash}"/>` : "/>"
6305
+ );
6306
+ }
6307
+ function axisGridlines(model, axis, ticks, position2, plot, vertical) {
6308
+ const draw2 = (values, paint2, minor2) => {
6309
+ const fallback = chartStroke(model, minor2 ? "gridlineMinor" : "gridlineMajor");
6310
+ return values.map((value) => {
6311
+ const p = position2(value);
6312
+ return vertical ? styledAxisLine(p, plot.y, p, plot.y + plot.h, paint2, fallback) : styledAxisLine(plot.x, p, plot.x + plot.w, p, paint2, fallback);
6313
+ }).join("");
6314
+ };
6315
+ const major = !axis || axis.source.majorGridlines ? draw2(ticks, axis?.majorGrid, false) : "";
6316
+ const minor = axis?.source.minorGridlines ? draw2(axis.minorTicks, axis.minorGrid, true) : "";
6317
+ return major + minor;
6318
+ }
6319
+
6320
+ // chart/axis-range.ts
6321
+ function computeLogValueRange(series, logBase) {
6322
+ const allValues = series.flatMap((item) => item.values).filter((value) => value !== null && Number.isFinite(value) && value > 0);
6323
+ if (allValues.length === 0) {
6324
+ return { min: 1, max: logBase, span: 1, logScale: true, logBase };
6325
+ }
6326
+ const dataMin = Math.min(...allValues);
6327
+ const dataMax = Math.max(...allValues);
6328
+ const logMin = Math.floor(Math.log(dataMin) / Math.log(logBase));
6329
+ const logMax = Math.ceil(Math.log(dataMax) / Math.log(logBase));
6330
+ const min = logBase ** logMin;
6331
+ const max = logBase ** Math.max(logMax, logMin + 1);
6332
+ return {
6333
+ min,
6334
+ max,
6335
+ span: Math.max(Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase), 1),
6336
+ logScale: true,
6337
+ logBase
6338
+ };
6339
+ }
6340
+ function withAxisBounds(automatic, axis, logBase) {
6341
+ const validMin = typeof axis?.min === "number" && Number.isFinite(axis.min) && (!logBase || axis.min > 0) ? axis.min : void 0;
6342
+ const validMax = typeof axis?.max === "number" && Number.isFinite(axis.max) && (!logBase || axis.max > 0) ? axis.max : void 0;
6343
+ const min = validMin ?? automatic.min;
6344
+ let max = validMax ?? automatic.max;
6345
+ const majorUnit = validMin === void 0 && validMax === void 0 ? automatic.majorUnit : void 0;
6346
+ if (max <= min) {
6347
+ max = logBase ? min * logBase : min + 1;
6348
+ }
6349
+ const span = logBase ? Math.log(max) / Math.log(logBase) - Math.log(min) / Math.log(logBase) : max - min;
6350
+ return {
6351
+ min,
6352
+ max,
6353
+ span: Math.max(span, Number.EPSILON),
6354
+ ...majorUnit !== void 0 ? { majorUnit } : {},
6355
+ ...logBase ? { logScale: true, logBase } : {},
6356
+ ...axis?.orientation === "maxMin" ? { reverseOrder: true } : {}
6357
+ };
6358
+ }
6359
+
6360
+ // chart/axis-ticks.ts
6361
+ var LOG_EXPONENT_TOLERANCE = 1e-12;
6362
+ function generateLogTicks(range) {
6363
+ if (!range.logScale || !range.logBase) {
6364
+ return [];
6365
+ }
6366
+ const base = range.logBase;
6367
+ const logMin = Math.log(range.min) / Math.log(base);
6368
+ const logMax = Math.log(range.max) / Math.log(base);
6369
+ const firstExponent = Math.ceil(logMin - LOG_EXPONENT_TOLERANCE);
6370
+ const lastExponent = Math.floor(logMax + LOG_EXPONENT_TOLERANCE);
6371
+ if (lastExponent < firstExponent) {
6372
+ return range.min === range.max ? [range.min] : [range.min, range.max];
6373
+ }
6374
+ return Array.from(
6375
+ { length: lastExponent - firstExponent + 1 },
6376
+ (_unused, index) => base ** (firstExponent + index)
6377
+ );
6378
+ }
6379
+ function generateIntervalTicks(range, unit) {
6380
+ if (!Number.isFinite(unit) || unit <= 0 || range.logScale) {
6381
+ return [];
6382
+ }
6383
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-12;
6384
+ const first3 = Math.ceil((range.min - tolerance) / unit);
6385
+ const last = Math.floor((range.max + tolerance) / unit);
6386
+ const count = Math.min(Math.max(last - first3 + 1, 0), 2e3);
6387
+ return Array.from({ length: count }, (_, index) => (first3 + index) * unit);
6388
+ }
6389
+ function generateAxisTicks(range, axis, defaultIntervals) {
6390
+ if (range.logScale && range.logBase) {
6391
+ return generateLogTicks(range);
6392
+ }
6393
+ const explicit = generateIntervalTicks(range, axis?.majorUnit ?? 0);
6394
+ if (explicit.length > 0) {
6395
+ return explicit;
6396
+ }
6397
+ const automatic = generateIntervalTicks(range, range.majorUnit ?? 0);
6398
+ if (automatic.length > 0) {
6399
+ return automatic;
6400
+ }
6401
+ return Array.from(
6402
+ { length: defaultIntervals + 1 },
6403
+ (_, index) => range.min + range.span / defaultIntervals * index
6404
+ );
6405
+ }
6406
+ function generateMinorAxisTicks(range, axis) {
6407
+ const minor = generateIntervalTicks(range, axis?.minorUnit ?? 0);
6408
+ if (minor.length === 0) {
6409
+ return [];
6410
+ }
6411
+ const majorUnit = axis?.majorUnit;
6412
+ if (!majorUnit || !Number.isFinite(majorUnit) || majorUnit <= 0) {
6413
+ return minor;
6414
+ }
6415
+ const tolerance = Math.max(1, Math.abs(range.min), Math.abs(range.max)) * 1e-10;
6416
+ return minor.filter(
6417
+ (value) => Math.abs(value / majorUnit - Math.round(value / majorUnit)) > tolerance
6418
+ );
6419
+ }
6420
+
6421
+ // chart/render/chart-view-axes.ts
6422
+ function chartAxisRatio(value, scale, axis) {
6423
+ const range = axis?.range;
6424
+ 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);
6425
+ return range?.reverseOrder ? 1 - ratio : ratio;
6426
+ }
6427
+ function chartAxisLabels(axis) {
6428
+ return axis?.source.deleted !== true && axis?.source.tickLabelPosition !== "none";
6429
+ }
6430
+ function options(axis) {
6431
+ return {
6432
+ ...axis.scaling,
6433
+ ...axis.scaling.logBase === void 0 ? {} : { logScale: true },
6434
+ ...axis.majorUnit === void 0 ? {} : { majorUnit: axis.majorUnit },
6435
+ ...axis.minorUnit === void 0 ? {} : { minorUnit: axis.minorUnit }
6436
+ };
6437
+ }
6438
+ function applyChartAxes(model, chart, color) {
6439
+ if (!chart.axes?.length) return;
6440
+ const axes = chart.axes;
6441
+ const linked = axes.filter((axis) => axis.id !== void 0 && chart.axisIds?.includes(axis.id));
6442
+ const candidates = linked.length ? linked : axes;
6443
+ const xy = model.type === "scatter" || model.type === "bubble";
6444
+ const value = candidates.find((axis) => axis.kind === "val" && !["b", "t"].includes(axis.position ?? "")) ?? candidates.find((axis) => axis.kind === "val");
6445
+ const category = candidates.find(
6446
+ (axis) => xy ? axis.kind === "val" && axis !== value : axis.kind === "cat" || axis.kind === "date"
6447
+ );
6448
+ const secondary = axes.find((axis) => axis.kind === "val" && axis !== value && axis !== category);
6449
+ const paint2 = (shape) => {
6450
+ const ln = shape?.line;
6451
+ const fill = ln?.fill;
6452
+ const resolved = fill?.kind === "none" ? "none" : color(fill?.kind === "solid" ? fill.color : void 0);
6453
+ return {
6454
+ ...resolved === void 0 ? {} : { color: resolved },
6455
+ ...ln?.widthEmu === void 0 ? {} : { width: ln.widthEmu / EMU_PER_PIXEL },
6456
+ ...ln?.dash === void 0 ? {} : { dash: ln.dash }
6457
+ };
6458
+ };
6459
+ const bind = (axis, scale, values) => {
6460
+ const opts = options(axis);
6461
+ const automatic = opts.logScale ? computeLogValueRange(
6462
+ [{ values: values ?? [] }],
6463
+ opts.logBase && Number.isFinite(opts.logBase) && opts.logBase > 1 ? opts.logBase : 10
6464
+ ) : {
6465
+ min: scale?.min ?? 0,
6466
+ max: scale?.max ?? 1,
6467
+ span: (scale?.max ?? 1) - (scale?.min ?? 0),
6468
+ ...scale ? { majorUnit: scale.majorUnit } : {}
6469
+ };
6470
+ const logBase = automatic.logBase;
6471
+ const range = withAxisBounds(automatic, opts, logBase);
6472
+ if (scale) {
6473
+ scale.min = range.min;
6474
+ scale.max = range.max;
6475
+ scale.ticks = generateAxisTicks(range, opts, 5);
6476
+ }
6477
+ return {
6478
+ source: axis,
6479
+ range,
6480
+ minorTicks: generateMinorAxisTicks(range, opts),
6481
+ line: paint2(axis.spPr),
6482
+ majorGrid: paint2(axis.majorGridlinesSpPr),
6483
+ minorGrid: paint2(axis.minorGridlinesSpPr)
6484
+ };
6485
+ };
6486
+ const out = {};
6487
+ if (value)
6488
+ out.value = bind(
6489
+ value,
6490
+ model.valueAxis,
6491
+ [
6492
+ ...model.series,
6493
+ ...model.extraGroups?.filter((g) => !g.secondary).flatMap((g) => g.series) ?? []
6494
+ ].flatMap((s) => s.values)
6495
+ );
6496
+ if (category)
6497
+ out.category = bind(
6498
+ category,
6499
+ model.xAxis ?? {
6500
+ min: 0,
6501
+ max: Math.max(1, model.categories.length - 1),
6502
+ majorUnit: 1,
6503
+ ticks: []
6504
+ },
6505
+ model.series.flatMap((s) => s.xValues ?? [])
6506
+ );
6507
+ if (secondary)
6508
+ out.secondary = bind(
6509
+ secondary,
6510
+ model.secondaryAxis,
6511
+ model.extraGroups?.filter((g) => g.secondary).flatMap((g) => g.series.flatMap((s) => s.values))
6512
+ );
6513
+ model.axes = out;
6514
+ }
6515
+
6041
6516
  // chart/render/chart-view-analysis.ts
6042
6517
  function strokeOf(line2, fallback, resolve) {
6043
6518
  if (line2?.fill?.kind === "none") return void 0;
@@ -6087,15 +6562,15 @@ function seriesName(series, index, evaluateRef) {
6087
6562
  const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
6088
6563
  return fromRef || series.name || `Series${index + 1}`;
6089
6564
  }
6090
- function seriesContext(chart, theme, options) {
6565
+ function seriesContext(chart, theme, options2) {
6091
6566
  const scheme = chartColorScheme(theme);
6092
6567
  const resolver = { scheme: (name) => scheme[name] };
6093
6568
  return {
6094
6569
  theme,
6095
6570
  scheme,
6096
6571
  palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
6097
- evaluateRef: options.evaluateRef ?? (() => []),
6098
- seriesColor: options.seriesColor,
6572
+ evaluateRef: options2.evaluateRef ?? (() => []),
6573
+ seriesColor: options2.seriesColor,
6099
6574
  drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
6100
6575
  gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
6101
6576
  fill,
@@ -6121,7 +6596,11 @@ function seriesView(ctx, s, index, total, categoriesOf) {
6121
6596
  })
6122
6597
  );
6123
6598
  if (Object.keys(points).length) view.pointGradients = points;
6124
- Object.assign(view, analysisView(s, color, ctx.drawingColor));
6599
+ Object.assign(
6600
+ view,
6601
+ analysisView(s, color, ctx.drawingColor),
6602
+ seriesMarkerViews(s, ctx.drawingColor)
6603
+ );
6125
6604
  return view;
6126
6605
  }
6127
6606
 
@@ -6421,11 +6900,11 @@ function histogramView(chart, model) {
6421
6900
  const first3 = model.series[0];
6422
6901
  if (!first3) return;
6423
6902
  const raw = first3.values.map((v) => v ?? Number.NaN);
6424
- const options = chart.histogram ?? {};
6425
- const bins = options.aggregateByCategory ? aggregateByCategory(
6903
+ const options2 = chart.histogram ?? {};
6904
+ const bins = options2.aggregateByCategory ? aggregateByCategory(
6426
6905
  first3.values.map((v) => v ?? 0),
6427
6906
  model.categories
6428
- ) : computeHistogramBins(raw, options, formatAxisValue);
6907
+ ) : computeHistogramBins(raw, options2, formatAxisValue);
6429
6908
  model.categories = bins.map((bin) => bin.label);
6430
6909
  first3.values = bins.map((bin) => bin.value);
6431
6910
  model.barGapWidth = 0;
@@ -6449,11 +6928,11 @@ var SUPPORTED = /* @__PURE__ */ new Set([
6449
6928
  "treemap",
6450
6929
  "sunburst"
6451
6930
  ]);
6452
- function chartSummaryView(chart, theme, options = {}) {
6931
+ function chartSummaryView(chart, theme, options2 = {}) {
6453
6932
  const type = chart.chartType;
6454
6933
  const radial = type === "pie" || type === "doughnut";
6455
6934
  const byPoint = radial || type === "treemap" || type === "sunburst";
6456
- const ctx = seriesContext(chart, theme, options);
6935
+ const ctx = seriesContext(chart, theme, options2);
6457
6936
  const { palette, scheme, drawingColor } = ctx;
6458
6937
  const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
6459
6938
  const rawCategories = [];
@@ -6539,6 +7018,7 @@ function chartSummaryView(chart, theme, options = {}) {
6539
7018
  else if (!byPoint) model.valueAxis = valueAxis(model);
6540
7019
  applyDataLabels(model, chart.series, extra);
6541
7020
  chartExtraAxes(model);
7021
+ applyChartAxes(model, chart, ctx.drawingColor);
6542
7022
  return model;
6543
7023
  }
6544
7024
 
@@ -6546,15 +7026,13 @@ function chartSummaryView(chart, theme, options = {}) {
6546
7026
  function cartesianAxes(model, area, out) {
6547
7027
  const scale = model.valueAxis;
6548
7028
  if (!scale) return void 0;
6549
- const labels = scale.ticks.map((t) => formatAxisValue(t, scale.percent));
7029
+ const labels = scale.ticks.map((t) => axisTickText(t, model.axes?.value, scale.percent));
6550
7030
  const valueAttrs = chartTextAttributes(model, "valueAxis");
6551
7031
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
6552
7032
  const valueSize = valueAttrs.size ?? 10;
6553
7033
  const categorySize = categoryAttrs.size ?? 10;
6554
- const grid = chartStroke(model, "gridlineMajor");
6555
- const axis = chartStroke(model, "categoryAxis");
6556
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
6557
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
7034
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
7035
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
6558
7036
  const labelW = valueLabels ? Math.max(...labels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
6559
7037
  const horizontal = model.horizontal;
6560
7038
  const cats = Math.max(1, model.categories.length);
@@ -6563,7 +7041,7 @@ function cartesianAxes(model, area, out) {
6563
7041
  Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
6564
7042
  );
6565
7043
  const second = horizontal ? void 0 : model.secondaryAxis;
6566
- const secondLabels = second?.ticks.map((t) => formatAxisValue(t, second.percent)) ?? [];
7044
+ const secondLabels = second?.ticks.map((t) => axisTickText(t, model.axes?.secondary, second.percent)) ?? [];
6567
7045
  const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
6568
7046
  const plot = horizontal ? {
6569
7047
  x: area.x + catW,
@@ -6576,29 +7054,47 @@ function cartesianAxes(model, area, out) {
6576
7054
  w: Math.max(1, area.w - labelW - 4 - secondW),
6577
7055
  h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
6578
7056
  };
6579
- const span = scale.max - scale.min || 1;
6580
- const value = horizontal ? (v) => plot.x + (v - scale.min) / span * plot.w : (v) => plot.y + plot.h - (v - scale.min) / span * plot.h;
7057
+ 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;
6581
7058
  const bandSize = (horizontal ? plot.h : plot.w) / cats;
6582
- const band = horizontal ? (i) => plot.y + plot.h - bandSize * (i + 0.5) : (i) => plot.x + bandSize * (i + 0.5);
7059
+ const index = (i) => model.axes?.category?.range.reverseOrder ? cats - 1 - i : i;
7060
+ const band = horizontal ? (i) => plot.y + plot.h - bandSize * (index(i) + 0.5) : (i) => plot.x + bandSize * (index(i) + 0.5);
6583
7061
  out.push(chartAreaRect(model, "plotArea", plot));
7062
+ out.push(axisGridlines(model, model.axes?.value, scale.ticks, value, plot, horizontal));
7063
+ if (model.axes?.category?.source.majorGridlines || model.axes?.category?.source.minorGridlines)
7064
+ out.push(
7065
+ axisGridlines(
7066
+ model,
7067
+ model.axes.category,
7068
+ model.categories.map((_, i) => i),
7069
+ band,
7070
+ plot,
7071
+ !horizontal
7072
+ )
7073
+ );
6584
7074
  scale.ticks.forEach((t, i) => {
6585
7075
  const p = value(t);
6586
7076
  const label = labels[i] ?? "";
6587
7077
  if (horizontal) {
6588
- out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
6589
7078
  if (valueLabels)
6590
7079
  out.push(
6591
7080
  text(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
6592
7081
  );
6593
7082
  } else {
6594
- out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
6595
7083
  if (valueLabels)
6596
7084
  out.push(text(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
6597
7085
  }
6598
7086
  });
6599
- const zero = value(Math.min(Math.max(0, scale.min), scale.max));
6600
- if (horizontal) out.push(line(zero, plot.y, zero, plot.y + plot.h, axis.color, axis.width));
6601
- else out.push(line(plot.x, zero, plot.x + plot.w, zero, axis.color, axis.width));
7087
+ const source = model.axes?.value?.source;
7088
+ const crossing = source?.crosses === "max" ? scale.max : source?.crosses === "min" ? scale.min : source?.crossesAt ?? 0;
7089
+ const zero = value(Math.min(Math.max(crossing, scale.min), scale.max));
7090
+ if (horizontal)
7091
+ out.push(
7092
+ axisLine(model, model.axes?.category, "categoryAxis", zero, plot.y, zero, plot.y + plot.h)
7093
+ );
7094
+ else
7095
+ out.push(
7096
+ axisLine(model, model.axes?.category, "categoryAxis", plot.x, zero, plot.x + plot.w, zero)
7097
+ );
6602
7098
  const step = Math.max(
6603
7099
  1,
6604
7100
  Math.ceil(cats / Math.max(1, Math.floor((horizontal ? plot.h : plot.w) / 14)))
@@ -6623,20 +7119,23 @@ function cartesianAxes(model, area, out) {
6623
7119
  });
6624
7120
  const frame = { plot, value, band, bandSize };
6625
7121
  if (second) {
6626
- const secondSpan = second.max - second.min || 1;
6627
- frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
6628
- const secondAxis = chartStroke(model, "valueAxis");
7122
+ frame.secondary = (v) => plot.y + plot.h - chartAxisRatio(v, second, model.axes?.secondary) * plot.h;
6629
7123
  out.push(
6630
- line(
7124
+ axisLine(
7125
+ model,
7126
+ model.axes?.secondary,
7127
+ "valueAxis",
6631
7128
  plot.x + plot.w,
6632
7129
  plot.y,
6633
7130
  plot.x + plot.w,
6634
- plot.y + plot.h,
6635
- secondAxis.color,
6636
- secondAxis.width
7131
+ plot.y + plot.h
6637
7132
  )
6638
7133
  );
6639
- if (valueLabels)
7134
+ if (model.axes?.secondary?.source.majorGridlines || model.axes?.secondary?.source.minorGridlines)
7135
+ out.push(
7136
+ axisGridlines(model, model.axes.secondary, second.ticks, frame.secondary, plot, false)
7137
+ );
7138
+ if (chartAxisLabels(model.axes?.secondary))
6640
7139
  second.ticks.forEach(
6641
7140
  (t, i) => out.push(
6642
7141
  text(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
@@ -6680,18 +7179,19 @@ function linesAndAreas(model, frame, out) {
6680
7179
  index: i,
6681
7180
  x: frame.band(i),
6682
7181
  y: frame.value(top),
6683
- radius: area ? 0 : 3
7182
+ radius: area ? 0 : chartMarkerRadius(s, i, 2.5)
6684
7183
  });
6685
7184
  lower.push([frame.band(i), frame.value(below)]);
6686
7185
  });
6687
7186
  layers.push({
7187
+ series: s,
6688
7188
  points,
6689
7189
  lower,
6690
7190
  color: s.color,
6691
7191
  filter: s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""
6692
7192
  });
6693
7193
  });
6694
- for (const { points, lower, color, filter } of area ? [...layers].reverse() : layers) {
7194
+ for (const { points, lower, color, filter, series } of area ? [...layers].reverse() : layers) {
6695
7195
  if (area) {
6696
7196
  const poly = [...points, ...[...lower].reverse()].map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
6697
7197
  out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
@@ -6710,9 +7210,9 @@ function linesAndAreas(model, frame, out) {
6710
7210
  else segment2.push(`${n(x)},${n(y)}`);
6711
7211
  }
6712
7212
  flush();
6713
- for (const [x, y] of points)
6714
- if (!Number.isNaN(x))
6715
- out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
7213
+ points.forEach(([x, y], index) => {
7214
+ if (!Number.isNaN(x)) out.push(chartSeriesMarkerSvg(series, index, x, y, 2.5));
7215
+ });
6716
7216
  }
6717
7217
  pointLabels(model, marks, out);
6718
7218
  }
@@ -6722,16 +7222,14 @@ function scatter(model, area, out) {
6722
7222
  const ys = model.valueAxis;
6723
7223
  const xs = model.xAxis;
6724
7224
  if (!ys || !xs) return;
6725
- const yLabels = ys.ticks.map((t) => formatAxisValue(t));
7225
+ const yLabels = ys.ticks.map((t) => axisTickText(t, model.axes?.value));
6726
7226
  const valueAttrs = chartTextAttributes(model, "valueAxis");
6727
7227
  const categoryAttrs = chartTextAttributes(model, "categoryAxis");
6728
7228
  const valueSize = valueAttrs.size ?? 10;
6729
7229
  const categorySize = categoryAttrs.size ?? 10;
6730
- const grid = chartStroke(model, "gridlineMajor");
6731
7230
  const xAxis = chartStroke(model, "categoryAxis");
6732
- const yAxis = chartStroke(model, "valueAxis");
6733
- const valueLabels = model.appearance?.valueAxis?.labelsVisible !== false;
6734
- const categoryLabels = model.appearance?.categoryAxis?.labelsVisible !== false;
7231
+ const valueLabels = chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false;
7232
+ const categoryLabels = chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false;
6735
7233
  const labelW = valueLabels ? Math.max(...yLabels.map((l) => textWidth(l, valueSize)), 8) + 6 : 4;
6736
7234
  const plot = {
6737
7235
  x: area.x + labelW,
@@ -6751,17 +7249,24 @@ function scatter(model, area, out) {
6751
7249
  s.values.forEach((_, i) => {
6752
7250
  reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
6753
7251
  });
6754
- const widen = (s, length) => {
7252
+ const widen = (s, length, axis) => {
7253
+ if (axis?.range.logScale) return s;
6755
7254
  const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
6756
- return { ...s, min: s.min - pad, max: s.max + pad };
7255
+ return {
7256
+ ...s,
7257
+ min: axis?.source.scaling.min === void 0 ? s.min - pad : s.min,
7258
+ max: axis?.source.scaling.max === void 0 ? s.max + pad : s.max
7259
+ };
6757
7260
  };
6758
- const xView = widen(xs, plot.w);
6759
- const yView = widen(ys, plot.h);
6760
- const px = (v) => plot.x + (v - xView.min) / (xView.max - xView.min || 1) * plot.w;
6761
- const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
7261
+ const xView = widen(xs, plot.w, model.axes?.category);
7262
+ const yView = widen(ys, plot.h, model.axes?.value);
7263
+ const px = (v) => plot.x + chartAxisRatio(v, xView, model.axes?.category) * plot.w;
7264
+ const py = (v) => plot.y + plot.h - chartAxisRatio(v, yView, model.axes?.value) * plot.h;
6762
7265
  out.push(chartAreaRect(model, "plotArea", plot));
7266
+ out.push(axisGridlines(model, model.axes?.value, ys.ticks, py, plot, false));
7267
+ if (model.axes?.category)
7268
+ out.push(axisGridlines(model, model.axes.category, xs.ticks, px, plot, true));
6763
7269
  ys.ticks.forEach((t, i) => {
6764
- out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
6765
7270
  if (valueLabels)
6766
7271
  out.push(
6767
7272
  text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
@@ -6771,19 +7276,30 @@ function scatter(model, area, out) {
6771
7276
  );
6772
7277
  });
6773
7278
  for (const t of xs.ticks) {
6774
- out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
7279
+ if (!model.axes?.category?.source.deleted)
7280
+ out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
6775
7281
  if (categoryLabels)
6776
7282
  out.push(
6777
- text(px(t), plot.y + plot.h + categorySize + 3, formatAxisValue(t), {
7283
+ text(px(t), plot.y + plot.h + categorySize + 3, axisTickText(t, model.axes?.category), {
6778
7284
  anchor: "middle",
6779
7285
  ...categoryAttrs
6780
7286
  })
6781
7287
  );
6782
7288
  }
6783
7289
  out.push(
6784
- line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
7290
+ axisLine(
7291
+ model,
7292
+ model.axes?.category,
7293
+ "categoryAxis",
7294
+ plot.x,
7295
+ plot.y + plot.h,
7296
+ plot.x + plot.w,
7297
+ plot.y + plot.h
7298
+ )
7299
+ );
7300
+ out.push(
7301
+ axisLine(model, model.axes?.value, "valueAxis", plot.x, plot.y, plot.x, plot.y + plot.h)
6785
7302
  );
6786
- out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
6787
7303
  const marks = [];
6788
7304
  for (const [si, s] of model.series.entries())
6789
7305
  s.values.forEach((v, i) => {
@@ -6792,8 +7308,8 @@ function scatter(model, area, out) {
6792
7308
  const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
6793
7309
  const fill = s.pointColors?.[i] ?? s.color;
6794
7310
  if (!bubble) {
6795
- out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
6796
- marks.push({ series: s, index: i, x: px(x), y: py(v), radius: 3 });
7311
+ out.push(chartSeriesMarkerSvg(s, i, px(x), py(v)));
7312
+ marks.push({ series: s, index: i, x: px(x), y: py(v), radius: chartMarkerRadius(s, i) });
6797
7313
  return;
6798
7314
  }
6799
7315
  const r = radiusOf(s.sizes?.[i] ?? void 0);
@@ -7013,32 +7529,37 @@ function radarSvg(model, area) {
7013
7529
  const valueSize = valueAttrs.size ?? 9;
7014
7530
  const categorySize = categoryAttrs.size ?? 10;
7015
7531
  const grid = chartStroke(model, "gridlineMajor");
7016
- const axis = chartStroke(model, "categoryAxis");
7017
7532
  const cx = area.x + area.w / 2;
7018
7533
  const cy = area.y + area.h / 2 + 4;
7019
7534
  const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
7020
7535
  const angle = (i) => i / count * Math.PI * 2;
7021
- const r = (v) => (v - scale.min) / (scale.max - scale.min || 1) * radius;
7536
+ const r = (v) => chartAxisRatio(v, scale, model.axes?.value) * radius;
7022
7537
  const labelEvery = Math.max(
7023
7538
  1,
7024
7539
  Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
7025
7540
  );
7026
7541
  for (const [k, t] of scale.ticks.entries()) {
7027
7542
  const ring = Array.from({ length: count }, (_, i) => polar(cx, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
7028
- out.push(
7029
- `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
7030
- );
7031
- if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
7543
+ if (!model.axes?.value || model.axes.value.source.majorGridlines)
7032
7544
  out.push(
7033
- text(cx + 3, cy - r(t) + valueSize * 0.3, formatAxisValue(t, scale.percent), valueAttrs)
7545
+ `<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
7546
+ );
7547
+ if (chartAxisLabels(model.axes?.value) && model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
7548
+ out.push(
7549
+ text(
7550
+ cx + 3,
7551
+ cy - r(t) + valueSize * 0.3,
7552
+ axisTickText(t, model.axes?.value, scale.percent),
7553
+ valueAttrs
7554
+ )
7034
7555
  );
7035
7556
  }
7036
7557
  model.categories.forEach((c, i) => {
7037
7558
  const [x, y] = polar(cx, cy, radius, angle(i));
7038
- out.push(line(cx, cy, x, y, axis.color, axis.width));
7559
+ out.push(axisLine(model, model.axes?.category, "categoryAxis", cx, cy, x, y));
7039
7560
  const [lx, ly] = polar(cx, cy, radius + 10, angle(i));
7040
7561
  const anchor = Math.abs(lx - cx) < 2 ? "middle" : lx > cx ? "start" : "end";
7041
- if (model.appearance?.categoryAxis?.labelsVisible !== false)
7562
+ if (chartAxisLabels(model.axes?.category) && model.appearance?.categoryAxis?.labelsVisible !== false)
7042
7563
  out.push(
7043
7564
  text(lx, ly + categorySize * 0.3, fit(c, area.w / 4, categorySize), {
7044
7565
  anchor,
@@ -7049,7 +7570,13 @@ function radarSvg(model, area) {
7049
7570
  const marks = [];
7050
7571
  for (const s of model.series) {
7051
7572
  const vertices = s.values.slice(0, count).map((v, i) => polar(cx, cy, r(v ?? scale.min), angle(i)));
7052
- vertices.forEach(([x, y], i) => marks.push({ series: s, index: i, x, y, radius: 3 }));
7573
+ vertices.forEach(([x, y], i) => {
7574
+ if (s.values[i] === null) return;
7575
+ const markerSeries = s;
7576
+ if (markerSeries.marker || markerSeries.pointMarkers)
7577
+ out.push(chartSeriesMarkerSvg(s, i, x, y));
7578
+ marks.push({ series: s, index: i, x, y, radius: chartMarkerRadius(s, i) });
7579
+ });
7053
7580
  const points = vertices.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
7054
7581
  out.push(
7055
7582
  `<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
@@ -7146,33 +7673,33 @@ var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
7146
7673
  function cssFont(attrs2) {
7147
7674
  return `${attrs2.italic ? "italic" : "normal"} ${attrs2.weight ?? "normal"} ${attrs2.size ?? 10}px ${attrs2.family ?? CHART_FONT_FAMILY}`;
7148
7675
  }
7149
- function chartFontMetrics(attrs2, options) {
7150
- const metrics = options.measureFont?.(cssFont(attrs2));
7676
+ function chartFontMetrics(attrs2, options2) {
7677
+ const metrics = options2.measureFont?.(cssFont(attrs2));
7151
7678
  return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
7152
7679
  }
7153
- function chartTextWidth(content, attrs2, options) {
7154
- const width = options.measureText?.(content, cssFont(attrs2));
7680
+ function chartTextWidth(content, attrs2, options2) {
7681
+ const width = options2.measureText?.(content, cssFont(attrs2));
7155
7682
  return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs2.size);
7156
7683
  }
7157
- function fitChartText(content, maxWidth, attrs2, options) {
7158
- if (!options.measureText) return fit(content, maxWidth, attrs2.size);
7159
- if (chartTextWidth(content, attrs2, options) <= maxWidth) return content;
7684
+ function fitChartText(content, maxWidth, attrs2, options2) {
7685
+ if (!options2.measureText) return fit(content, maxWidth, attrs2.size);
7686
+ if (chartTextWidth(content, attrs2, options2) <= maxWidth) return content;
7160
7687
  const points = [...content];
7161
7688
  let low = 0;
7162
7689
  let high = points.length;
7163
7690
  while (low < high) {
7164
7691
  const mid = Math.ceil((low + high) / 2);
7165
- if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options) <= maxWidth) low = mid;
7692
+ if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options2) <= maxWidth) low = mid;
7166
7693
  else high = mid - 1;
7167
7694
  }
7168
7695
  return `${points.slice(0, low).join("")}\u2026`;
7169
7696
  }
7170
7697
 
7171
7698
  // chart/render/chart-svg-legend.ts
7172
- function chartLegendSvg(model, area, frame, options) {
7699
+ function chartLegendSvg(model, area, frame, options2) {
7173
7700
  const automatic = [];
7174
7701
  const bounds = {};
7175
- const reserved = automaticLegend(model, area, automatic, options, bounds);
7702
+ const reserved = automaticLegend(model, area, automatic, options2, bounds);
7176
7703
  const plot = model.legendOverlay ? area : reserved;
7177
7704
  const box = bounds.box;
7178
7705
  if (!box) return { plot, markup: "", foreground: false };
@@ -7186,11 +7713,11 @@ function chartLegendSvg(model, area, frame, options) {
7186
7713
  const entries = legendEntries(model);
7187
7714
  const attrs2 = chartTextAttributes(model, "legend");
7188
7715
  const size = attrs2.size ?? 10;
7189
- const font = chartFontMetrics(attrs2, options);
7716
+ const font = chartFontMetrics(attrs2, options2);
7190
7717
  const keySize = size / 2;
7191
7718
  const keyGap = size / 4;
7192
7719
  const widths = entries.map(
7193
- (entry) => chartTextWidth(entry.label, attrs2, options) + keySize + keyGap
7720
+ (entry) => chartTextWidth(entry.label, attrs2, options2) + keySize + keyGap
7194
7721
  );
7195
7722
  const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
7196
7723
  const rowWidth = horizontal ? manual.width / entries.length : manual.width;
@@ -7205,8 +7732,8 @@ function chartLegendSvg(model, area, frame, options) {
7205
7732
  ];
7206
7733
  const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
7207
7734
  entries.forEach((entry, i) => {
7208
- const available = horizontal ? chartTextWidth(entry.label, attrs2, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
7209
- const label = fitChartText(entry.label, available, attrs2, options);
7735
+ const available = horizontal ? chartTextWidth(entry.label, attrs2, options2) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
7736
+ const label = fitChartText(entry.label, available, attrs2, options2);
7210
7737
  const contentWidth = Math.min(
7211
7738
  horizontal ? widths[i] ?? 0 : Math.max(...widths),
7212
7739
  rowWidth - size / 2
@@ -7249,7 +7776,7 @@ function legendEntries(model) {
7249
7776
  color: s.color
7250
7777
  }));
7251
7778
  }
7252
- function automaticLegend(model, area, out, options, bounds) {
7779
+ function automaticLegend(model, area, out, options2, bounds) {
7253
7780
  const entries = legendEntries(model);
7254
7781
  if (!model.showLegend || entries.length === 0) return area;
7255
7782
  const pos = model.legendPosition;
@@ -7258,7 +7785,7 @@ function automaticLegend(model, area, out, options, bounds) {
7258
7785
  const rowH = Math.max(16, size * 1.4);
7259
7786
  if (pos === "t" || pos === "b") {
7260
7787
  const widths = entries.map(
7261
- (e) => Math.min(chartTextWidth(e.label, attrs2, options) + 20, area.w / 2)
7788
+ (e) => Math.min(chartTextWidth(e.label, attrs2, options2) + 20, area.w / 2)
7262
7789
  );
7263
7790
  const total = widths.reduce((a, b) => a + b, 0);
7264
7791
  let x2 = area.x + Math.max(0, (area.w - total) / 2);
@@ -7275,14 +7802,14 @@ function automaticLegend(model, area, out, options, bounds) {
7275
7802
  entries.forEach((e, i) => {
7276
7803
  const w = widths[i] ?? 0;
7277
7804
  out.push(rect(x2, y, 8, 8, e.color));
7278
- out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options), attrs2));
7805
+ out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options2), attrs2));
7279
7806
  x2 += w;
7280
7807
  });
7281
7808
  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 };
7282
7809
  }
7283
7810
  const width = Math.min(
7284
7811
  area.w * 0.35,
7285
- Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options))) + 22
7812
+ Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options2))) + 22
7286
7813
  );
7287
7814
  const height = entries.length * rowH;
7288
7815
  const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
@@ -7300,14 +7827,14 @@ function automaticLegend(model, area, out, options, bounds) {
7300
7827
  const y = y0 + i * rowH;
7301
7828
  if (y + rowH > area.y + area.h + 2) return;
7302
7829
  out.push(rect(x, y + 3, 8, 8, e.color));
7303
- out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options), attrs2));
7830
+ out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options2), attrs2));
7304
7831
  });
7305
7832
  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 };
7306
7833
  }
7307
7834
 
7308
7835
  // text/wrap-styled-runs.ts
7309
7836
  var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
7310
- function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
7837
+ function wrapStyledRuns(runs, maxWidth, measure2, options2 = {}) {
7311
7838
  const groups = [];
7312
7839
  for (const [source, run] of runs.entries()) {
7313
7840
  for (const token of run.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
@@ -7355,7 +7882,7 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
7355
7882
  if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
7356
7883
  else line2 = merged(line2, separator);
7357
7884
  spaces = [];
7358
- if (options.breakWords && wordWidth > maxWidth) {
7885
+ if (options2.breakWords && wordWidth > maxWidth) {
7359
7886
  for (const piece of group2.pieces) {
7360
7887
  for (const { segment: segment2 } of graphemes.segment(piece.text)) {
7361
7888
  const next = { ...piece, text: segment2 };
@@ -7373,11 +7900,11 @@ function wrapStyledRuns(runs, maxWidth, measure2, options = {}) {
7373
7900
  function spacing(value, naturalHeight, fallback) {
7374
7901
  return value ? value.unit === "points" ? chartPointsToPixels(value.value) : naturalHeight * value.value : fallback;
7375
7902
  }
7376
- function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7903
+ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
7377
7904
  if (!model.title) return void 0;
7378
7905
  const base = chartTextAttributes(model, "title", 14);
7379
7906
  const capacity = Math.max(1, width * 0.8 - 8);
7380
- if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options) <= capacity)
7907
+ if (!model.titleText && !hasManualLayoutFields(model.titleLayout) && !model.titleOverlay && !model.title.includes("\n") && chartTextWidth(model.title, base, options2) <= capacity)
7381
7908
  return void 0;
7382
7909
  const paragraphs = model.titleText?.paragraphs ?? [
7383
7910
  {
@@ -7413,7 +7940,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7413
7940
  "title",
7414
7941
  base.size
7415
7942
  ),
7416
- options
7943
+ options2
7417
7944
  ),
7418
7945
  { breakWords: true }
7419
7946
  );
@@ -7437,10 +7964,10 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7437
7964
  return {
7438
7965
  ...line2,
7439
7966
  runs,
7440
- width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options), 0),
7967
+ width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options2), 0),
7441
7968
  size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
7442
7969
  fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
7443
- (attrs2) => chartFontMetrics(attrs2, options)
7970
+ (attrs2) => chartFontMetrics(attrs2, options2)
7444
7971
  )
7445
7972
  };
7446
7973
  });
@@ -7478,7 +8005,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7478
8005
  anchor: "start"
7479
8006
  }).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
7480
8007
  );
7481
- x += chartTextWidth(run.text, run.attrs, options);
8008
+ x += chartTextWidth(run.text, run.attrs, options2);
7482
8009
  }
7483
8010
  }
7484
8011
  const parent = text(0, 0, "", { ...base, underline: false }).replace(
@@ -7504,7 +8031,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
7504
8031
  }
7505
8032
 
7506
8033
  // chart/render/chart-svg.ts
7507
- function renderChartSvg(model, width, height, options = {}) {
8034
+ function renderChartSvg(model, width, height, options2 = {}) {
7508
8035
  const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
7509
8036
  model = paint2.model;
7510
8037
  const w = Math.max(1, width);
@@ -7518,7 +8045,7 @@ function renderChartSvg(model, width, height, options = {}) {
7518
8045
  if (paint2.defs) out.push(paint2.defs);
7519
8046
  out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
7520
8047
  let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
7521
- const richTitle = chartRichTitleSvg(model, w, options, h);
8048
+ const richTitle = chartRichTitleSvg(model, w, options2, h);
7522
8049
  if (richTitle) {
7523
8050
  if (model.titleLayout || model.titleOverlay) foregroundTitle = richTitle.markup;
7524
8051
  else out.push(richTitle.markup);
@@ -7527,9 +8054,9 @@ function renderChartSvg(model, width, height, options = {}) {
7527
8054
  } else if (model.title) {
7528
8055
  const attrs2 = chartTextAttributes(model, "title", 14);
7529
8056
  const size = attrs2.size ?? 14;
7530
- const label = fitChartText(model.title, w - 16, attrs2, options);
7531
- const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options) + 8);
7532
- const font = chartFontMetrics(attrs2, options);
8057
+ const label = fitChartText(model.title, w - 16, attrs2, options2);
8058
+ const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options2) + 8);
8059
+ const font = chartFontMetrics(attrs2, options2);
7533
8060
  const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
7534
8061
  out.push(
7535
8062
  chartAreaRect(model, "title", {
@@ -7557,7 +8084,7 @@ function renderChartSvg(model, width, height, options = {}) {
7557
8084
  out.push("</svg>");
7558
8085
  return out.join("");
7559
8086
  }
7560
- const legend = chartLegendSvg(model, area, { width: w, height: h }, options);
8087
+ const legend = chartLegendSvg(model, area, { width: w, height: h }, options2);
7561
8088
  area = legend.plot;
7562
8089
  if (!legend.foreground) out.push(legend.markup);
7563
8090
  if (area.w > 4 && area.h > 4) {
@@ -7604,8 +8131,8 @@ function chartSpaceKind(space) {
7604
8131
  const type = chartSummaryFromSpace(space).chartType;
7605
8132
  return { type, drawn: DRAWN_CHART_TYPES.has(type) };
7606
8133
  }
7607
- function renderChartSpaceSvg(space, options) {
7608
- const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options;
8134
+ function renderChartSpaceSvg(space, options2) {
8135
+ const { width, height, theme, fonts, formatting, colorPalette, styleDefinition, ...svg } = options2;
7609
8136
  const summary = chartSummaryFromSpace(space, {
7610
8137
  ...formatting ? { formatting } : {},
7611
8138
  ...colorPalette !== void 0 ? { colorPalette } : {},
@@ -7614,8 +8141,8 @@ function renderChartSpaceSvg(space, options) {
7614
8141
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
7615
8142
  return renderChartSvg(view, width, height, svg);
7616
8143
  }
7617
- function renderChartSummarySvg(summary, options) {
7618
- const { width, height, theme, fonts, ...svg } = options;
8144
+ function renderChartSummarySvg(summary, options2) {
8145
+ const { width, height, theme, fonts, ...svg } = options2;
7619
8146
  const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
7620
8147
  return renderChartSvg(view, width, height, svg);
7621
8148
  }
@@ -9104,7 +9631,7 @@ var rejectAllRevisions = (model) => applyAll(model, rejectRevision);
9104
9631
  // docx/field-date.ts
9105
9632
  var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
9106
9633
  function formatWordDate(date, picture, locale = "en-US") {
9107
- const name = (options) => new Intl.DateTimeFormat(locale, options).format(date);
9634
+ const name = (options2) => new Intl.DateTimeFormat(locale, options2).format(date);
9108
9635
  const pad = (value) => String(value).padStart(2, "0");
9109
9636
  const hours12 = date.getHours() % 12 || 12;
9110
9637
  return picture.replace(TOKENS, (token) => {
@@ -10757,11 +11284,11 @@ function wordYjsDocumentAttributes(attrs2, canWrite) {
10757
11284
  }
10758
11285
  var wordYjsPluginKey = new prosemirrorState.PluginKey("docx-yjs");
10759
11286
  var WordYjsCollaboration = class {
10760
- constructor(session, initial, options) {
11287
+ constructor(session, initial, options2) {
10761
11288
  this.session = session;
10762
11289
  if (!session.synced)
10763
11290
  throw new Error("Wait for initial provider synchronization before joining Word.");
10764
- if (!options.documentId.trim()) throw new Error("A matching source documentId is required.");
11291
+ if (!options2.documentId.trim()) throw new Error("A matching source documentId is required.");
10765
11292
  this.fragment = session.doc.getXmlFragment("docx:body");
10766
11293
  this.media = new WordYjsMedia(session);
10767
11294
  this.attributes = session.doc.getMap("docx:attributes");
@@ -10777,17 +11304,17 @@ var WordYjsCollaboration = class {
10777
11304
  () => this.sharedInlineComments
10778
11305
  );
10779
11306
  if (!identity.has("documentId")) {
10780
- if (!options.initializeIfEmpty || !session.canWrite() || this.fragment.length)
11307
+ if (!options2.initializeIfEmpty || !session.canWrite() || this.fragment.length)
10781
11308
  throw new Error("The Word room has not been initialized by its designated creator.");
10782
11309
  session.doc.transact(() => {
10783
- for (const [name, part] of options.initialMedia ?? []) this.media.publish(name, part);
10784
- identity.set("documentId", options.documentId);
11310
+ for (const [name, part] of options2.initialMedia ?? []) this.media.publish(name, part);
11311
+ identity.set("documentId", options2.documentId);
10785
11312
  identity.set("format", format);
10786
11313
  identity.set(
10787
11314
  "comments",
10788
11315
  format === "word-yjs-v3" ? "inline-relative-v1" : "independent-v1"
10789
11316
  );
10790
- for (const comment of options.initialComments ?? []) {
11317
+ for (const comment of options2.initialComments ?? []) {
10791
11318
  this.comments.records.set(comment.id, { ...comment });
10792
11319
  if (comment.resolved !== void 0)
10793
11320
  this.comments.resolved.set(comment.id, comment.resolved);
@@ -10801,7 +11328,7 @@ var WordYjsCollaboration = class {
10801
11328
  this.comments.inlineAnchors.seed(doc, mapping);
10802
11329
  }
10803
11330
  }, this);
10804
- } else if (identity.get("documentId") !== options.documentId) {
11331
+ } else if (identity.get("documentId") !== options2.documentId) {
10805
11332
  throw new Error("Load the matching source package before joining this Word room.");
10806
11333
  } else if (identity.get("format") !== format) {
10807
11334
  throw new Error("Unsupported Word collaboration room format.");
@@ -10844,7 +11371,7 @@ var WordYjsCollaboration = class {
10844
11371
  this.session.doc.transact(() => seedEmptyParagraphText(this.fragment), this);
10845
11372
  };
10846
11373
  /** Fresh plugins per live view; the Y.Doc and local undo history survive view teardown. */
10847
- state(schema, options = {}) {
11374
+ state(schema, options2 = {}) {
10848
11375
  if (this.destroyed) throw new Error("The Word Yjs binding has been destroyed.");
10849
11376
  if (wordInlinePropertyCodec(schema) !== this.roomFormat)
10850
11377
  throw new Error("Unsupported Word collaboration schema for this room format.");
@@ -10874,8 +11401,8 @@ var WordYjsCollaboration = class {
10874
11401
  const unguard = binding ? guardDeletedNodeSelection(this.session.doc, view, binding) : () => {
10875
11402
  };
10876
11403
  const originalVisibility = binding?._isDomSelectionInView;
10877
- if (binding && options.selectionVisible)
10878
- binding._isDomSelectionInView = () => options.selectionVisible(view);
11404
+ if (binding && options2.selectionVisible)
11405
+ binding._isDomSelectionInView = () => options2.selectionVisible(view);
10879
11406
  const added = ({ stackItem }) => {
10880
11407
  const binding2 = yProsemirror.ySyncPluginKey.getState(view.state)?.binding;
10881
11408
  if (binding2) stackItem.meta.set(this.selectionKey, this.previousSelection);
@@ -10948,8 +11475,8 @@ function isWordYjsRemoteTransaction(transaction) {
10948
11475
  transaction.getMeta("dve-remote") || transaction.getMeta(yProsemirror.ySyncPluginKey)?.isChangeOrigin
10949
11476
  );
10950
11477
  }
10951
- function wordYjsPresencePlugin(session, options) {
10952
- return yProsemirror.yCursorPlugin(session.awareness, options);
11478
+ function wordYjsPresencePlugin(session, options2) {
11479
+ return yProsemirror.yCursorPlugin(session.awareness, options2);
10953
11480
  }
10954
11481
  function refreshWordYjsPresence(state) {
10955
11482
  return state.tr.setMeta(yProsemirror.yCursorPluginKey, { awarenessUpdated: true });
@@ -13769,7 +14296,7 @@ var newControlId = (doc) => {
13769
14296
  while (used.has(id));
13770
14297
  return id;
13771
14298
  };
13772
- function insertContentControl(state, kind, options = {}) {
14299
+ function insertContentControl(state, kind, options2 = {}) {
13773
14300
  const type = state.schema.marks.contentControl;
13774
14301
  if (!type) return void 0;
13775
14302
  const { selection } = state;
@@ -13777,10 +14304,10 @@ function insertContentControl(state, kind, options = {}) {
13777
14304
  id: newControlId(state.doc),
13778
14305
  level: "inline",
13779
14306
  kind,
13780
- ...options.alias ? { alias: options.alias } : {},
13781
- ...options.tag ? { tag: options.tag } : {},
13782
- ...options.items ? { items: options.items } : {},
13783
- ...kind === "date" ? { dateFormat: options.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
14307
+ ...options2.alias ? { alias: options2.alias } : {},
14308
+ ...options2.tag ? { tag: options2.tag } : {},
14309
+ ...options2.items ? { items: options2.items } : {},
14310
+ ...kind === "date" ? { dateFormat: options2.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
13784
14311
  };
13785
14312
  const wrapsText = !selection.empty && (kind === "richText" || kind === "text");
13786
14313
  if (wrapsText) {