@office-open/core 0.11.0 → 0.12.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 (85) hide show
  1. package/dist/chart/index.d.mts +2 -2
  2. package/dist/chart/index.mjs +1 -1
  3. package/dist/{chart-Kf_utasF.mjs → chart-DED4tXC9.mjs} +828 -283
  4. package/dist/chart-DED4tXC9.mjs.map +1 -0
  5. package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
  6. package/dist/descriptor/index.d.mts +1 -1
  7. package/dist/descriptor/index.mjs +1 -1
  8. package/dist/{descriptor-BX8xW8na.mjs → descriptor-BqaNZrrZ.mjs} +38 -10
  9. package/dist/{descriptor-BX8xW8na.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
  10. package/dist/drawing/index.d.mts +2 -2
  11. package/dist/drawing/index.mjs +2 -2
  12. package/dist/{drawing-FBzd2I0m.mjs → drawing-BCAyrCCw.mjs} +3056 -3130
  13. package/dist/drawing-BCAyrCCw.mjs.map +1 -0
  14. package/dist/{generators-CElPsAhd.mjs → ext-uri-BHBcIrW7.mjs} +599 -343
  15. package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
  16. package/dist/index-BAxlDUQ1.d.mts +590 -0
  17. package/dist/index-BAxlDUQ1.d.mts.map +1 -0
  18. package/dist/{index-DxwLMnBF.d.mts → index-BP541uS-.d.mts} +136 -31
  19. package/dist/index-BP541uS-.d.mts.map +1 -0
  20. package/dist/{index-CLX7gU9J.d.mts → index-BQLIofaF.d.mts} +3 -2
  21. package/dist/index-BQLIofaF.d.mts.map +1 -0
  22. package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
  23. package/dist/index-CaNwM5_e.d.mts.map +1 -0
  24. package/dist/{index-CnjCK-lF.d.mts → index-DPkf_CtG.d.mts} +566 -597
  25. package/dist/index-DPkf_CtG.d.mts.map +1 -0
  26. package/dist/{index-BsTUn4K1.d.mts → index-DcukVskh.d.mts} +9 -6
  27. package/dist/index-DcukVskh.d.mts.map +1 -0
  28. package/dist/{index-Cgz88FU0.d.mts → index-Di6XPdGl.d.mts} +26 -12
  29. package/dist/index-Di6XPdGl.d.mts.map +1 -0
  30. package/dist/{index-C0ClOhmZ.d.mts → index-L6AXewfV.d.mts} +11 -8
  31. package/dist/index-L6AXewfV.d.mts.map +1 -0
  32. package/dist/index.d.mts +140 -29
  33. package/dist/index.d.mts.map +1 -1
  34. package/dist/index.mjs +849 -87
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
  37. package/dist/output-yyxdkG0C.d.mts.map +1 -0
  38. package/dist/patch/index.d.mts +2 -2
  39. package/dist/patch/index.mjs +2 -2
  40. package/dist/{patch-3KLx2yEP.mjs → patch-AkQY17CD.mjs} +71 -26
  41. package/dist/patch-AkQY17CD.mjs.map +1 -0
  42. package/dist/smartart/index.d.mts +2 -2
  43. package/dist/smartart/index.mjs +1 -1
  44. package/dist/{smartart-BxnkROOp.mjs → smartart-n1kYJ6Jg.mjs} +27 -26
  45. package/dist/smartart-n1kYJ6Jg.mjs.map +1 -0
  46. package/dist/{style-matrix-DAP6XrLv.mjs → style-matrix-B6jhPAT3.mjs} +4 -4
  47. package/dist/style-matrix-B6jhPAT3.mjs.map +1 -0
  48. package/dist/theme/index.d.mts +4 -4
  49. package/dist/theme/index.mjs +3 -2
  50. package/dist/{theme-OAuRcA9_.mjs → theme-BKnXRmvn.mjs} +37 -71
  51. package/dist/theme-BKnXRmvn.mjs.map +1 -0
  52. package/dist/{theme-options-BbWccl85.d.mts → theme-options-kO89NUEX.d.mts} +17 -17
  53. package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
  54. package/dist/util/index.d.mts +3 -3
  55. package/dist/util/index.mjs +3 -3
  56. package/dist/{util-C94-JKtp.mjs → util-ptE16MEk.mjs} +69 -37
  57. package/dist/util-ptE16MEk.mjs.map +1 -0
  58. package/dist/{values-aVoirbWB.d.mts → values-BECDm4zr.d.mts} +15 -31
  59. package/dist/values-BECDm4zr.d.mts.map +1 -0
  60. package/dist/vector/index.d.mts +2 -2
  61. package/dist/vector/index.mjs +2 -2
  62. package/dist/{vector-TpjW6ZSc.mjs → vector-DhLGZjP5.mjs} +104 -147
  63. package/dist/vector-DhLGZjP5.mjs.map +1 -0
  64. package/package.json +3 -3
  65. package/dist/chart-Kf_utasF.mjs.map +0 -1
  66. package/dist/drawing-FBzd2I0m.mjs.map +0 -1
  67. package/dist/generators-CElPsAhd.mjs.map +0 -1
  68. package/dist/index-BsTUn4K1.d.mts.map +0 -1
  69. package/dist/index-C0ClOhmZ.d.mts.map +0 -1
  70. package/dist/index-CLX7gU9J.d.mts.map +0 -1
  71. package/dist/index-Cgz88FU0.d.mts.map +0 -1
  72. package/dist/index-CnjCK-lF.d.mts.map +0 -1
  73. package/dist/index-DpPeyf5f.d.mts +0 -316
  74. package/dist/index-DpPeyf5f.d.mts.map +0 -1
  75. package/dist/index-DxwLMnBF.d.mts.map +0 -1
  76. package/dist/index-k8WKLXnA.d.mts.map +0 -1
  77. package/dist/output-D_G_JR_8.d.mts.map +0 -1
  78. package/dist/patch-3KLx2yEP.mjs.map +0 -1
  79. package/dist/smartart-BxnkROOp.mjs.map +0 -1
  80. package/dist/style-matrix-DAP6XrLv.mjs.map +0 -1
  81. package/dist/theme-OAuRcA9_.mjs.map +0 -1
  82. package/dist/theme-options-BbWccl85.d.mts.map +0 -1
  83. package/dist/util-C94-JKtp.mjs.map +0 -1
  84. package/dist/values-aVoirbWB.d.mts.map +0 -1
  85. package/dist/vector-TpjW6ZSc.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
- import { ut as parseOnOff } from "./generators-CElPsAhd.mjs";
2
- import { o as parse$1, s as stringify$1 } from "./descriptor-BX8xW8na.mjs";
3
- import { B as blipFillDesc, C as shapePropertiesDesc, S as groupShapePropertiesDesc, T as transform2DDesc, a as textBodyDesc, pt as stringifyNonVisualDrawingProperties } from "./drawing-FBzd2I0m.mjs";
4
- import { i as stringifyShapeStyle, n as parseShapeStyle } from "./style-matrix-DAP6XrLv.mjs";
1
+ import { B as xsdAxisCrossBetween, Ct as xsdSizeRepresents, Ft as xsdTrendlineType, H as xsdAxisLabelAlignment, Tt as xsdSplitType, U as xsdAxisOrientation, V as xsdAxisCrosses, W as xsdAxisPosition, Z as xsdDataLabelPosition, Zt as parseOnOff, st as xsdLegendPosition, tt as xsdErrorValueType } from "./ext-uri-BHBcIrW7.mjs";
2
+ import { A as groupShapePropertiesDesc, N as transform2DDesc, a as textBodyDesc, dt as stringifyNonVisualDrawingProperties, hn as blipFillDesc, j as shapePropertiesDesc } from "./drawing-BCAyrCCw.mjs";
3
+ import { o as parse$1, s as stringify$1 } from "./descriptor-BqaNZrrZ.mjs";
4
+ import { i as stringifyShapeStyle, n as parseShapeStyle } from "./style-matrix-B6jhPAT3.mjs";
5
5
  import { n as parseColorMapping, r as stringifyColorMapping } from "./color-mapping-CFF0vRSe.mjs";
6
- import { attr, children, escapeXml, findChild, stringifyElement, textOf } from "@office-open/xml";
6
+ import { attr, children, escapeXml, findChild, findFirst, stringify, stringifyElement, textOf } from "@office-open/xml";
7
7
  //#region src/chart/chart-collection.ts
8
8
  var ChartCollection = class {
9
9
  map;
@@ -45,7 +45,7 @@ const CHART_TYPE_TAGS_3D = {
45
45
  pie: "c:pie3DChart",
46
46
  area: "c:area3DChart"
47
47
  };
48
- const NO_AXES_TYPES = new Set([
48
+ const NO_AXES_TYPES = /* @__PURE__ */ new Set([
49
49
  "pie",
50
50
  "doughnut",
51
51
  "ofPie"
@@ -93,7 +93,7 @@ function valEl(tag, value) {
93
93
  return `<${tag} ${attrVal("val", value)}/>`;
94
94
  }
95
95
  function boolVal(value) {
96
- return value === false ? ` val="0"` : "";
96
+ return ` val="${value === false ? 0 : 1}"`;
97
97
  }
98
98
  function stringifyNumLit(value) {
99
99
  return `<c:numLit><c:formatCode>General</c:formatCode><c:ptCount val="1"/><c:pt idx="0"><c:v>${value}</c:v></c:pt></c:numLit>`;
@@ -101,7 +101,7 @@ function stringifyNumLit(value) {
101
101
  function stringifyTrendline(opts) {
102
102
  const parts = [];
103
103
  if (opts.name !== void 0) parts.push(`<c:name>${escapeXml(opts.name)}</c:name>`);
104
- parts.push(valEl("c:trendlineType", opts.type ?? "linear"));
104
+ parts.push(valEl("c:trendlineType", xsdTrendlineType.to(opts.type ?? "linear")));
105
105
  if (opts.order !== void 0) parts.push(valEl("c:order", opts.order));
106
106
  if (opts.period !== void 0) parts.push(valEl("c:period", opts.period));
107
107
  if (opts.forward !== void 0) parts.push(valEl("c:forward", opts.forward));
@@ -115,26 +115,42 @@ function stringifyTrendline(opts) {
115
115
  }
116
116
  function stringifyErrBars(opts) {
117
117
  const parts = [];
118
- if (opts.direction !== void 0) parts.push(valEl("c:errDir", opts.direction));
118
+ if (opts.direction === "x" || opts.direction === "y") parts.push(valEl("c:errDir", opts.direction));
119
119
  parts.push(valEl("c:errBarType", opts.barType ?? "both"));
120
- parts.push(valEl("c:errValType", opts.valueType ?? "fixedVal"));
120
+ parts.push(valEl("c:errValType", xsdErrorValueType.to(opts.valueType ?? "fixedValue")));
121
121
  if (opts.noEndCap !== void 0) parts.push(`<c:noEndCap${boolVal(opts.noEndCap)}/>`);
122
122
  if (opts.plusValue !== void 0) parts.push(`<c:plus>${stringifyNumLit(opts.plusValue)}</c:plus>`);
123
123
  if (opts.minusValue !== void 0) parts.push(`<c:minus>${stringifyNumLit(opts.minusValue)}</c:minus>`);
124
124
  if (opts.value !== void 0) parts.push(valEl("c:val", opts.value));
125
125
  return `<c:errBars>${parts.join("")}</c:errBars>`;
126
126
  }
127
- function stringifyDataLabel(opts) {
127
+ function stringifyDataLabel(opts, ctx) {
128
128
  if (opts.delete) return `<c:dLbl><c:idx val="${opts.index}"/><c:delete val="1"/></c:dLbl>`;
129
129
  const inner = [];
130
+ if (opts.layout === true) inner.push("<c:layout/>");
131
+ else if (opts.layout) inner.push(stringifyLayout(opts.layout));
132
+ if (opts.text) inner.push(`<c:tx><c:rich>${textBodyDesc.stringify(opts.text, ctx) ?? ""}</c:rich></c:tx>`);
130
133
  if (opts.numberFormat !== void 0) inner.push(`<c:numFmt formatCode="${escapeXml(opts.numberFormat)}" sourceLinked="0"/>`);
131
- if (opts.position !== void 0) inner.push(valEl("c:dLblPos", opts.position));
134
+ inner.push(chartSpPr(opts.shapeProperties, ctx));
135
+ if (opts.textProperties) inner.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
136
+ if (opts.position !== void 0) inner.push(valEl("c:dLblPos", xsdDataLabelPosition.to(opts.position)));
137
+ if (opts.showLegendKey !== void 0) inner.push(`<c:showLegendKey${boolVal(opts.showLegendKey)}/>`);
138
+ if (opts.showVal !== void 0) inner.push(`<c:showVal${boolVal(opts.showVal)}/>`);
139
+ if (opts.showCatName !== void 0) inner.push(`<c:showCatName${boolVal(opts.showCatName)}/>`);
140
+ if (opts.showSerName !== void 0) inner.push(`<c:showSerName${boolVal(opts.showSerName)}/>`);
141
+ if (opts.showPercent !== void 0) inner.push(`<c:showPercent${boolVal(opts.showPercent)}/>`);
142
+ if (opts.showBubbleSize !== void 0) inner.push(`<c:showBubbleSize${boolVal(opts.showBubbleSize)}/>`);
143
+ if (opts.separator !== void 0) inner.push(`<c:separator>${escapeXml(opts.separator)}</c:separator>`);
132
144
  return `<c:dLbl><c:idx val="${opts.index}"/>${inner.join("")}</c:dLbl>`;
133
145
  }
134
- function stringifyDataLabels(opts) {
146
+ function stringifyDataLabels(opts, ctx) {
135
147
  const parts = [];
136
- if (opts.labels) for (const lbl of opts.labels) parts.push(stringifyDataLabel(lbl));
137
- if (opts.position !== void 0) parts.push(valEl("c:dLblPos", opts.position));
148
+ if (opts.labels) for (const lbl of opts.labels) parts.push(stringifyDataLabel(lbl, ctx));
149
+ if (opts.delete !== void 0) parts.push(`<c:delete${boolVal(opts.delete)}/>`);
150
+ if (opts.numberFormat !== void 0) parts.push(`<c:numFmt formatCode="${escapeXml(opts.numberFormat)}" sourceLinked="0"/>`);
151
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
152
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
153
+ if (opts.position !== void 0) parts.push(valEl("c:dLblPos", xsdDataLabelPosition.to(opts.position)));
138
154
  if (opts.showLegendKey !== void 0) parts.push(`<c:showLegendKey${boolVal(opts.showLegendKey)}/>`);
139
155
  if (opts.showVal !== void 0) parts.push(`<c:showVal${boolVal(opts.showVal)}/>`);
140
156
  if (opts.showCatName !== void 0) parts.push(`<c:showCatName${boolVal(opts.showCatName)}/>`);
@@ -142,8 +158,10 @@ function stringifyDataLabels(opts) {
142
158
  if (opts.showPercent !== void 0) parts.push(`<c:showPercent${boolVal(opts.showPercent)}/>`);
143
159
  if (opts.showBubbleSize !== void 0) parts.push(`<c:showBubbleSize${boolVal(opts.showBubbleSize)}/>`);
144
160
  if (opts.separator !== void 0) parts.push(`<c:separator>${escapeXml(opts.separator)}</c:separator>`);
145
- if (opts.showLeaderLines !== void 0) parts.push(`<c:showLeaderLines${boolVal(opts.showLeaderLines)}/>`);
146
- if (opts.leaderLines) parts.push(emptyEl("c:leaderLines"));
161
+ if (opts.delete === void 0) {
162
+ if (opts.showLeaderLines !== void 0) parts.push(`<c:showLeaderLines${boolVal(opts.showLeaderLines)}/>`);
163
+ if (opts.leaderLines) parts.push(emptyEl("c:leaderLines"));
164
+ }
147
165
  return `<c:dLbls>${parts.join("")}</c:dLbls>`;
148
166
  }
149
167
  function stringifyView3D(opts) {
@@ -170,10 +188,11 @@ function stringifyLayout(manualLayout) {
170
188
  if (manualLayout.h !== void 0) parts.push(valEl("c:h", manualLayout.h));
171
189
  return `<c:layout><c:manualLayout>${parts.join("")}</c:manualLayout></c:layout>`;
172
190
  }
173
- function stringifySurface(tag, opts) {
191
+ function stringifySurface(tag, opts, ctx) {
174
192
  if (!opts) return "";
175
193
  const parts = [];
176
194
  if (opts.thickness !== void 0) parts.push(valEl("c:thickness", typeof opts.thickness === "string" ? Number(opts.thickness.replace("%", "")) : opts.thickness));
195
+ if (opts.shapeProperties) parts.push(chartSpPr(opts.shapeProperties, ctx));
177
196
  return parts.length ? `<${tag}>${parts.join("")}</${tag}>` : `<${tag}/>`;
178
197
  }
179
198
  const AXIS_TAG = {
@@ -186,14 +205,11 @@ function stringifyScaling(opts) {
186
205
  if (!opts) return emptyEl("c:scaling");
187
206
  const parts = [];
188
207
  if (opts.logBase !== void 0) parts.push(valEl("c:logBase", opts.logBase));
189
- if (opts.orientation !== void 0) parts.push(valEl("c:orientation", opts.orientation));
208
+ if (opts.orientation !== void 0) parts.push(valEl("c:orientation", xsdAxisOrientation.to(opts.orientation)));
190
209
  if (opts.max !== void 0) parts.push(valEl("c:max", opts.max));
191
210
  if (opts.min !== void 0) parts.push(valEl("c:min", opts.min));
192
211
  return `<c:scaling>${parts.join("")}</c:scaling>`;
193
212
  }
194
- function stringifyAxisTitle(title) {
195
- return `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title)}</a:t></a:r></a:p></c:rich></c:tx><c:overlay val="0"/></c:title>`;
196
- }
197
213
  function stringifyDisplayUnits(opts) {
198
214
  const parts = [];
199
215
  if (opts.customUnit !== void 0) parts.push(valEl("c:custUnit", opts.customUnit));
@@ -206,26 +222,33 @@ function stringifyDisplayUnits(opts) {
206
222
  * EG_AxShared (axId…crosses/crossesAt), then the kind-specific tail from
207
223
  * CT_CatAx / CT_DateAx / CT_SerAx / CT_ValAx.
208
224
  */
209
- function stringifyAxis(opts) {
225
+ function stringifyAxis(opts, ctx) {
210
226
  const parts = [];
211
227
  parts.push(valEl("c:axId", opts.id));
212
228
  parts.push(stringifyScaling(opts.scaling));
213
229
  if (opts.delete !== void 0) parts.push(`<c:delete${boolVal(opts.delete)}/>`);
214
- if (opts.position !== void 0) parts.push(valEl("c:axPos", opts.position));
215
- if (opts.majorGridlines) parts.push(emptyEl("c:majorGridlines"));
216
- if (opts.minorGridlines) parts.push(emptyEl("c:minorGridlines"));
217
- if (opts.title !== void 0) parts.push(stringifyAxisTitle(opts.title));
218
- if (opts.numberFormat !== void 0) parts.push(`<c:numFmt formatCode="${escapeXml(opts.numberFormat)}" sourceLinked="1"/>`);
230
+ const axPos = opts.position ?? (opts.kind === "value" ? "left" : "bottom");
231
+ parts.push(valEl("c:axPos", xsdAxisPosition.to(axPos)));
232
+ parts.push(stringifyChartLines("c:majorGridlines", opts.majorGridlines, ctx));
233
+ parts.push(stringifyChartLines("c:minorGridlines", opts.minorGridlines, ctx));
234
+ if (opts.title !== void 0) parts.push(typeof opts.title === "string" && opts.title === "" ? emptyEl("c:title") : stringifyTitle(opts.title, ctx));
235
+ if (opts.numberFormat !== void 0) {
236
+ const fmt = typeof opts.numberFormat === "string" ? { formatCode: opts.numberFormat } : opts.numberFormat;
237
+ const linked = fmt.sourceLinked === void 0 || fmt.sourceLinked ? 1 : 0;
238
+ parts.push(`<c:numFmt formatCode="${escapeXml(fmt.formatCode)}" sourceLinked="${linked}"/>`);
239
+ }
219
240
  if (opts.majorTickMark !== void 0) parts.push(valEl("c:majorTickMark", opts.majorTickMark));
220
241
  if (opts.minorTickMark !== void 0) parts.push(valEl("c:minorTickMark", opts.minorTickMark));
221
242
  if (opts.tickLabelPosition !== void 0) parts.push(valEl("c:tickLblPos", opts.tickLabelPosition));
243
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
244
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
222
245
  parts.push(valEl("c:crossAx", opts.crossAxisId));
223
246
  if (opts.crossesAt !== void 0) parts.push(valEl("c:crossesAt", opts.crossesAt));
224
- else if (opts.crosses !== void 0) parts.push(valEl("c:crosses", opts.crosses));
247
+ else if (opts.crosses !== void 0) parts.push(valEl("c:crosses", xsdAxisCrosses.to(opts.crosses)));
225
248
  switch (opts.kind) {
226
249
  case "category":
227
250
  if (opts.auto !== void 0) parts.push(`<c:auto${boolVal(opts.auto)}/>`);
228
- if (opts.labelAlignment !== void 0) parts.push(valEl("c:lblAlgn", opts.labelAlignment));
251
+ if (opts.labelAlignment !== void 0) parts.push(valEl("c:lblAlgn", xsdAxisLabelAlignment.to(opts.labelAlignment)));
229
252
  if (opts.labelOffset !== void 0) parts.push(valEl("c:lblOffset", opts.labelOffset));
230
253
  if (opts.tickLabelSkip !== void 0) parts.push(valEl("c:tickLblSkip", opts.tickLabelSkip));
231
254
  if (opts.tickMarkSkip !== void 0) parts.push(valEl("c:tickMarkSkip", opts.tickMarkSkip));
@@ -245,38 +268,54 @@ function stringifyAxis(opts) {
245
268
  if (opts.tickMarkSkip !== void 0) parts.push(valEl("c:tickMarkSkip", opts.tickMarkSkip));
246
269
  break;
247
270
  case "value":
248
- if (opts.crossBetween !== void 0) parts.push(valEl("c:crossBetween", opts.crossBetween));
271
+ if (opts.crossBetween !== void 0) parts.push(valEl("c:crossBetween", xsdAxisCrossBetween.to(opts.crossBetween)));
249
272
  if (opts.majorUnit !== void 0) parts.push(valEl("c:majorUnit", opts.majorUnit));
250
273
  if (opts.minorUnit !== void 0) parts.push(valEl("c:minorUnit", opts.minorUnit));
251
274
  if (opts.displayUnits) parts.push(stringifyDisplayUnits(opts.displayUnits));
252
- break;
253
275
  }
254
276
  const tag = AXIS_TAG[opts.kind];
255
277
  return `<${tag}>${parts.join("")}</${tag}>`;
256
278
  }
257
- function stringifyStrRef(values) {
258
- const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("");
259
- return `<c:strRef><c:f/><c:strCache><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:strCache></c:strRef>`;
279
+ /** Worksheet reference formula (c:f); empty element when not round-tripped. */
280
+ function refFormula(formula) {
281
+ return `<c:f>${escapeXml(formula ?? "")}</c:f>`;
282
+ }
283
+ function stringifyStrRef(values, formula) {
284
+ const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v ?? "")}</c:v></c:pt>`).join("");
285
+ return `<c:strRef>${refFormula(formula)}<c:strCache><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:strCache></c:strRef>`;
260
286
  }
261
287
  function stringifyStrLit(values) {
262
288
  const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("");
263
289
  return `<c:strLit><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:strLit>`;
264
290
  }
265
- function stringifyMultiLvlStrRef(levels) {
291
+ function stringifyMultiLvlStrRef(levels, formula) {
266
292
  const ptCount = levels.reduce((max, lvl) => Math.max(max, lvl.length), 0);
267
293
  const lvls = levels.map((lvl) => {
268
294
  return `<c:lvl>${lvl.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("")}</c:lvl>`;
269
295
  }).join("");
270
- return `<c:multiLvlStrRef><c:f/><c:multiLvlStrCache><c:ptCount ${attrVal("val", ptCount)}/>${lvls}</c:multiLvlStrCache></c:multiLvlStrRef>`;
296
+ return `<c:multiLvlStrRef>${refFormula(formula)}<c:multiLvlStrCache><c:ptCount ${attrVal("val", ptCount)}/>${lvls}</c:multiLvlStrCache></c:multiLvlStrRef>`;
297
+ }
298
+ function stringifyNumCatRef(values, formula, formatCode) {
299
+ const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${escapeXml(v)}</c:v></c:pt>`).join("");
300
+ return `<c:numRef>${refFormula(formula)}<c:numCache><c:formatCode>${escapeXml(formatCode ?? "General")}</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numCache></c:numRef>`;
301
+ }
302
+ /** Whether the chart carries category-source data (c:cat is optional in CT_Ser). */
303
+ function hasCategoryData(opts) {
304
+ return opts.categories !== void 0 || opts.categoryLabels !== void 0 || opts.multiLevelCategories !== void 0 || opts.numericCategories === true;
271
305
  }
272
306
  function stringifyCategorySource(opts) {
273
- if (opts.multiLevelCategories) return stringifyMultiLvlStrRef(opts.multiLevelCategories);
307
+ if (opts.multiLevelCategories) return stringifyMultiLvlStrRef(opts.multiLevelCategories, opts.categoryFormula);
274
308
  if (opts.categoryLabels) return stringifyStrLit(opts.categoryLabels);
275
- return stringifyStrRef(opts.categories ?? []);
309
+ if (opts.numericCategories) return stringifyNumCatRef(opts.categories ?? [], opts.categoryFormula, opts.categoryFormatCode);
310
+ return stringifyStrRef(opts.categories ?? [], opts.categoryFormula);
311
+ }
312
+ function stringifyNumRef(values, formula, formatCode) {
313
+ const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${v}</c:v></c:pt>`).join("");
314
+ return `<c:numRef>${refFormula(formula)}<c:numCache><c:formatCode>${escapeXml(formatCode ?? "General")}</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numCache></c:numRef>`;
276
315
  }
277
- function stringifyNumRef(values) {
316
+ function stringifyNumLitList(values, formatCode) {
278
317
  const pts = values.map((v, i) => `<c:pt idx="${i}"><c:v>${v}</c:v></c:pt>`).join("");
279
- return `<c:numRef><c:f/><c:numCache><c:formatCode>General</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numCache></c:numRef>`;
318
+ return `<c:numLit><c:formatCode>${escapeXml(formatCode ?? "General")}</c:formatCode><c:ptCount ${attrVal("val", values.length)}/>${pts}</c:numLit>`;
280
319
  }
281
320
  function stringifyUpDownBars(gapWidth) {
282
321
  const inner = [];
@@ -285,12 +324,14 @@ function stringifyUpDownBars(gapWidth) {
285
324
  inner.push(emptyEl("c:downBars"));
286
325
  return `<c:upDownBars>${inner.join("")}</c:upDownBars>`;
287
326
  }
288
- function stringifyDataTable(opts) {
327
+ function stringifyDataTable(opts, ctx) {
289
328
  const parts = [];
290
329
  if (opts.showHorizontalBorder !== void 0) parts.push(`<c:showHorzBorder${boolVal(opts.showHorizontalBorder)}/>`);
291
330
  if (opts.showVerticalBorder !== void 0) parts.push(`<c:showVertBorder${boolVal(opts.showVerticalBorder)}/>`);
292
331
  if (opts.showOutline !== void 0) parts.push(`<c:showOutline${boolVal(opts.showOutline)}/>`);
293
332
  if (opts.showLegendKeys !== void 0) parts.push(`<c:showKeys${boolVal(opts.showLegendKeys)}/>`);
333
+ if (opts.shapeProperties) parts.push(chartSpPr(opts.shapeProperties, ctx));
334
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
294
335
  return `<c:dTable>${parts.join("")}</c:dTable>`;
295
336
  }
296
337
  function stringifyProtection(opts) {
@@ -303,6 +344,7 @@ function stringifyProtection(opts) {
303
344
  return `<c:protection>${parts.join("")}</c:protection>`;
304
345
  }
305
346
  function stringifyExternalData(opts) {
347
+ if (!opts.relationshipId || /^r?Id?(0|undefined)?$/i.test(opts.relationshipId)) return void 0;
306
348
  const auto = opts.autoUpdate !== void 0 ? `<c:autoUpdate val="${opts.autoUpdate ? 1 : 0}"/>` : "";
307
349
  return `<c:externalData r:id="${escapeXml(opts.relationshipId)}">${auto}</c:externalData>`;
308
350
  }
@@ -318,7 +360,9 @@ function stringifyHeaderFooter(opts) {
318
360
  if (opts.alignWithMargins !== void 0) attrs.push(`alignWithMargins="${opts.alignWithMargins ? 1 : 0}"`);
319
361
  if (opts.differentOddEven !== void 0) attrs.push(`differentOddEven="${opts.differentOddEven ? 1 : 0}"`);
320
362
  if (opts.differentFirst !== void 0) attrs.push(`differentFirst="${opts.differentFirst ? 1 : 0}"`);
321
- return `<c:headerFooter${attrs.length ? " " + attrs.join(" ") : ""}>${parts.join("")}</c:headerFooter>`;
363
+ const attrStr = attrs.length ? " " + attrs.join(" ") : "";
364
+ if (parts.length === 0) return `<c:headerFooter${attrStr}/>`;
365
+ return `<c:headerFooter${attrStr}>${parts.join("")}</c:headerFooter>`;
322
366
  }
323
367
  function stringifyPageMargins(opts) {
324
368
  return `<c:pageMargins l="${opts.left ?? .7}" r="${opts.right ?? .7}" t="${opts.top ?? .75}" b="${opts.bottom ?? .75}" header="${opts.header ?? .3}" footer="${opts.footer ?? .3}"/>`;
@@ -336,6 +380,7 @@ function stringifyPageSetup(opts) {
336
380
  if (opts.horizontalDpi !== void 0) attrs.push(`horizontalDpi="${opts.horizontalDpi}"`);
337
381
  if (opts.verticalDpi !== void 0) attrs.push(`verticalDpi="${opts.verticalDpi}"`);
338
382
  if (opts.copies !== void 0) attrs.push(`copies="${opts.copies}"`);
383
+ if (attrs.length === 0) return `<c:pageSetup/>`;
339
384
  return `<c:pageSetup ${attrs.join(" ")}/>`;
340
385
  }
341
386
  function stringifyPrintSettings(opts) {
@@ -354,34 +399,27 @@ function chartTypeHeader(opts) {
354
399
  case "column":
355
400
  case "bar":
356
401
  headerParts.push(valEl("c:barDir", opts.type === "column" ? "col" : "bar"));
357
- headerParts.push(valEl("c:grouping", "clustered"));
402
+ headerParts.push(valEl("c:grouping", opts.grouping ?? "clustered"));
358
403
  break;
359
404
  case "line":
360
405
  case "area":
361
- headerParts.push(valEl("c:grouping", "standard"));
406
+ headerParts.push(valEl("c:grouping", opts.grouping ?? "standard"));
362
407
  break;
363
408
  case "scatter":
364
409
  headerParts.push(valEl("c:scatterStyle", "line"));
365
410
  break;
366
411
  case "radar":
367
- headerParts.push(valEl("c:radarStyle", "standard"));
412
+ headerParts.push(valEl("c:radarStyle", opts.radarStyle ?? "standard"));
368
413
  break;
369
414
  case "ofPie":
370
415
  headerParts.push(valEl("c:ofPieType", opts.ofPieType ?? "pie"));
371
- headerParts.push(valEl("c:varyColors", 1));
372
- break;
373
- case "pie":
374
- case "doughnut":
375
- case "bubble":
376
- headerParts.push(valEl("c:varyColors", 1));
377
- break;
378
- case "surface":
379
- if (opts.wireframe !== void 0) headerParts.push(`<c:wireframe${boolVal(opts.wireframe)}/>`);
380
416
  break;
417
+ case "surface": if (opts.wireframe !== void 0) headerParts.push(`<c:wireframe${boolVal(opts.wireframe)}/>`);
381
418
  }
419
+ if (opts.varyColors !== void 0) headerParts.push(`<c:varyColors${boolVal(opts.varyColors)}/>`);
382
420
  return `<${tag}>${headerParts.join("")}`;
383
421
  }
384
- function chartTypeFooter(opts) {
422
+ function chartTypeFooter(opts, ctx) {
385
423
  const tag = opts.threeD ? CHART_TYPE_TAGS_3D[opts.type] : CHART_TYPE_TAGS[opts.type];
386
424
  const parts = [];
387
425
  switch (opts.type) {
@@ -390,25 +428,28 @@ function chartTypeFooter(opts) {
390
428
  if (opts.gapWidth !== void 0) parts.push(valEl("c:gapWidth", opts.gapWidth));
391
429
  if (opts.threeD) {
392
430
  if (opts.gapDepth !== void 0) parts.push(valEl("c:gapDepth", opts.gapDepth));
431
+ if (opts.shape !== void 0) parts.push(valEl("c:shape", opts.shape));
393
432
  } else {
394
433
  if (opts.overlap !== void 0) parts.push(valEl("c:overlap", opts.overlap));
395
- if (opts.seriesLines) parts.push(emptyEl("c:serLines"));
434
+ parts.push(stringifyChartLines("c:serLines", opts.seriesLines, ctx));
396
435
  }
397
436
  break;
398
437
  case "line":
399
- if (opts.dropLines) parts.push(emptyEl("c:dropLines"));
438
+ parts.push(stringifyChartLines("c:dropLines", opts.dropLines, ctx));
400
439
  if (!opts.threeD) {
401
- if (opts.highLowLines) parts.push(emptyEl("c:hiLowLines"));
440
+ parts.push(stringifyChartLines("c:hiLowLines", opts.highLowLines, ctx));
402
441
  if (opts.upDownBars) parts.push(stringifyUpDownBars(opts.upDownBarsGapWidth));
442
+ if (opts.markers !== void 0) parts.push(`<c:marker${boolVal(opts.markers)}/>`);
443
+ if (opts.smooth !== void 0) parts.push(`<c:smooth${boolVal(opts.smooth)}/>`);
403
444
  } else if (opts.gapDepth !== void 0) parts.push(valEl("c:gapDepth", opts.gapDepth));
404
445
  break;
405
446
  case "area":
406
- if (opts.dropLines) parts.push(emptyEl("c:dropLines"));
447
+ parts.push(stringifyChartLines("c:dropLines", opts.dropLines, ctx));
407
448
  if (opts.threeD && opts.gapDepth !== void 0) parts.push(valEl("c:gapDepth", opts.gapDepth));
408
449
  break;
409
450
  case "stock":
410
- if (opts.dropLines) parts.push(emptyEl("c:dropLines"));
411
- if (opts.highLowLines) parts.push(emptyEl("c:hiLowLines"));
451
+ parts.push(stringifyChartLines("c:dropLines", opts.dropLines, ctx));
452
+ parts.push(stringifyChartLines("c:hiLowLines", opts.highLowLines, ctx));
412
453
  if (opts.upDownBars) parts.push(stringifyUpDownBars(opts.upDownBarsGapWidth));
413
454
  break;
414
455
  case "pie":
@@ -416,35 +457,37 @@ function chartTypeFooter(opts) {
416
457
  break;
417
458
  case "doughnut":
418
459
  if (opts.firstSliceAngle !== void 0) parts.push(valEl("c:firstSliceAng", opts.firstSliceAngle));
419
- if (opts.holeSize !== void 0) parts.push(valEl("c:holeSize", opts.holeSize));
460
+ parts.push(valEl("c:holeSize", opts.holeSize ?? 10));
420
461
  break;
421
462
  case "bubble":
422
463
  if (opts.bubbleScale !== void 0) parts.push(valEl("c:bubbleScale", opts.bubbleScale));
423
464
  if (opts.showNegativeBubbles !== void 0) parts.push(`<c:showNegBubbles${boolVal(opts.showNegativeBubbles)}/>`);
424
- if (opts.sizeRepresents !== void 0) parts.push(valEl("c:sizeRepresents", opts.sizeRepresents));
465
+ if (opts.sizeRepresents !== void 0) parts.push(valEl("c:sizeRepresents", xsdSizeRepresents.to(opts.sizeRepresents)));
425
466
  break;
426
467
  case "ofPie":
427
468
  if (opts.gapWidth !== void 0) parts.push(valEl("c:gapWidth", opts.gapWidth));
428
- if (opts.splitType !== void 0) parts.push(valEl("c:splitType", opts.splitType));
469
+ if (opts.splitType !== void 0) parts.push(valEl("c:splitType", xsdSplitType.to(opts.splitType)));
429
470
  if (opts.splitPosition !== void 0) parts.push(valEl("c:splitPos", opts.splitPosition));
430
471
  if (opts.customSplitPoints?.length) {
431
472
  const pts = opts.customSplitPoints.map((p) => valEl("c:secondPiePt", p)).join("");
432
473
  parts.push(`<c:custSplit>${pts}</c:custSplit>`);
433
474
  }
434
475
  if (opts.secondPieSize !== void 0) parts.push(valEl("c:secondPieSize", opts.secondPieSize));
435
- if (opts.seriesLines) parts.push(emptyEl("c:serLines"));
436
- break;
437
- case "surface":
438
- if (opts.bandFormats?.length) parts.push(stringifyBandFormats(opts.bandFormats));
476
+ parts.push(stringifyChartLines("c:serLines", opts.seriesLines, ctx));
439
477
  break;
478
+ case "surface": if (opts.bandFormats?.length) parts.push(stringifyBandFormats(opts.bandFormats));
479
+ }
480
+ if (!NO_AXES_TYPES.has(opts.type)) {
481
+ const ids = opts.axes && opts.axisIds ? opts.axisIds : axesFor(opts).map((axis) => axis.id);
482
+ for (const id of ids) parts.push(valEl("c:axId", id));
440
483
  }
441
- if (!NO_AXES_TYPES.has(opts.type)) for (const axis of axesFor(opts)) parts.push(valEl("c:axId", axis.id));
442
484
  return `${parts.join("")}</${tag}>`;
443
485
  }
444
- function stringifyMarker$1(opts) {
486
+ function stringifyMarker$1(opts, ctx) {
445
487
  const parts = [];
446
488
  if (opts.symbol !== void 0) parts.push(valEl("c:symbol", opts.symbol));
447
489
  if (opts.size !== void 0) parts.push(valEl("c:size", opts.size));
490
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
448
491
  return `<c:marker>${parts.join("")}</c:marker>`;
449
492
  }
450
493
  function stringifyPictureOptions(opts) {
@@ -456,26 +499,27 @@ function stringifyPictureOptions(opts) {
456
499
  if (opts.pictureStackUnit !== void 0) parts.push(valEl("c:pictureStackUnit", opts.pictureStackUnit));
457
500
  return `<c:pictureOptions>${parts.join("")}</c:pictureOptions>`;
458
501
  }
459
- function stringifyDataPoint(opts) {
502
+ function stringifyDataPoint(opts, ctx) {
460
503
  const parts = [valEl("c:idx", opts.index)];
461
504
  if (opts.invertIfNegative !== void 0) parts.push(`<c:invertIfNegative${boolVal(opts.invertIfNegative)}/>`);
462
- if (opts.marker) parts.push(stringifyMarker$1(opts.marker));
505
+ if (opts.marker) parts.push(stringifyMarker$1(opts.marker, ctx));
463
506
  if (opts.bubble3D !== void 0) parts.push(`<c:bubble3D${boolVal(opts.bubble3D)}/>`);
464
507
  if (opts.explosion !== void 0) parts.push(valEl("c:explosion", opts.explosion));
508
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
465
509
  if (opts.pictureOptions) parts.push(stringifyPictureOptions(opts.pictureOptions));
466
510
  return `<c:dPt>${parts.join("")}</c:dPt>`;
467
511
  }
468
- function stringifySeries(index, series, opts) {
469
- const chartType = opts.type;
470
- const categories = opts.categories ?? [];
512
+ function stringifySeries(index, series, opts, ctx, groupType) {
513
+ const chartType = groupType ?? opts.type;
471
514
  const parts = [];
472
515
  const s = series;
473
- parts.push(valEl("c:idx", index));
474
- parts.push(valEl("c:order", index));
475
- parts.push(`<c:tx>${stringifyStrRef([series.name])}</c:tx>`);
476
- parts.push(emptyEl("c:spPr"));
516
+ parts.push(valEl("c:idx", s.index ?? index));
517
+ parts.push(valEl("c:order", s.order ?? index));
518
+ if (series.nameLiteral && series.name !== void 0) parts.push(`<c:tx><c:v>${escapeXml(series.name)}</c:v></c:tx>`);
519
+ else if (series.name !== void 0 || series.nameFormula !== void 0) parts.push(`<c:tx>${stringifyStrRef([series.name], series.nameFormula)}</c:tx>`);
520
+ parts.push(chartSpPr(s.shapeProperties, ctx));
477
521
  if (chartType === "line" || chartType === "scatter" || chartType === "radar") {
478
- if (s.marker) parts.push(stringifyMarker$1(s.marker));
522
+ if (s.marker) parts.push(stringifyMarker$1(s.marker, ctx));
479
523
  } else if (chartType === "column" || chartType === "bar") {
480
524
  if (s.invertIfNegative !== void 0) parts.push(`<c:invertIfNegative${boolVal(s.invertIfNegative)}/>`);
481
525
  if (s.pictureOptions) parts.push(stringifyPictureOptions(s.pictureOptions));
@@ -486,8 +530,8 @@ function stringifySeries(index, series, opts) {
486
530
  } else if (chartType === "pie" || chartType === "doughnut" || chartType === "ofPie") {
487
531
  if (s.explosion !== void 0) parts.push(valEl("c:explosion", s.explosion));
488
532
  }
489
- if (s.dataPoints) for (const dp of s.dataPoints) parts.push(stringifyDataPoint(dp));
490
- if (s.dataLabels) parts.push(stringifyDataLabels(s.dataLabels));
533
+ if (s.dataPoints) for (const dp of s.dataPoints) parts.push(stringifyDataPoint(dp, ctx));
534
+ if (s.dataLabels) parts.push(stringifyDataLabels(s.dataLabels, ctx));
491
535
  if (s.trendlines) for (const tl of s.trendlines) parts.push(stringifyTrendline(tl));
492
536
  if (s.errorBars) parts.push(stringifyErrBars(s.errorBars));
493
537
  if (chartType === "bubble") {
@@ -496,46 +540,186 @@ function stringifySeries(index, series, opts) {
496
540
  parts.push(`<c:yVal>${stringifyNumRef(bs.yValues)}</c:yVal>`);
497
541
  parts.push(`<c:bubbleSize>${stringifyNumRef(bs.bubbleSize)}</c:bubbleSize>`);
498
542
  } else if (chartType === "scatter") {
499
- parts.push(`<c:xVal>${stringifyStrRef(categories)}</c:xVal>`);
500
- parts.push(`<c:yVal>${stringifyNumRef(s.values)}</c:yVal>`);
501
- } else {
543
+ if ("xValues" in series) {
544
+ parts.push(`<c:xVal>${stringifyNumRef(series.xValues)}</c:xVal>`);
545
+ parts.push(`<c:yVal>${stringifyNumRef(series.yValues, series.valueFormula, series.formatCode)}</c:yVal>`);
546
+ } else {
547
+ parts.push(`<c:xVal>${stringifyCategorySource(opts)}</c:xVal>`);
548
+ parts.push(`<c:yVal>${stringifyNumRef(s.values, s.valueFormula, s.formatCode)}</c:yVal>`);
549
+ }
550
+ } else if (hasCategoryData(opts)) {
502
551
  parts.push(`<c:cat>${stringifyCategorySource(opts)}</c:cat>`);
503
- parts.push(`<c:val>${stringifyNumRef(s.values)}</c:val>`);
504
- }
552
+ parts.push(`<c:val>${s.valueLiteral ? stringifyNumLitList(s.values, s.formatCode) : stringifyNumRef(s.values, s.valueFormula, s.formatCode)}</c:val>`);
553
+ } else parts.push(`<c:val>${s.valueLiteral ? stringifyNumLitList(s.values, s.formatCode) : stringifyNumRef(s.values, s.valueFormula, s.formatCode)}</c:val>`);
505
554
  if ((chartType === "line" || chartType === "scatter") && s.smooth !== void 0) parts.push(`<c:smooth${boolVal(s.smooth)}/>`);
506
555
  if ((chartType === "column" || chartType === "bar") && s.shape !== void 0) parts.push(valEl("c:shape", s.shape));
507
556
  if (chartType === "bubble" && s.bubble3D !== void 0) parts.push(`<c:bubble3D${boolVal(s.bubble3D)}/>`);
557
+ if (s.ext) parts.push(`<c:extLst>${s.ext}</c:extLst>`);
508
558
  return `<c:ser>${parts.join("")}</c:ser>`;
509
559
  }
510
- function stringifyTitle(title) {
511
- return `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title)}</a:t></a:r></a:p></c:rich></c:tx><c:overlay val="0"/></c:title>`;
560
+ function stringifyChartLines(tag, opts, ctx) {
561
+ if (opts === void 0 || opts === false) return "";
562
+ if (opts === true) return emptyEl(tag);
563
+ return `<${tag}>${chartSpPr(opts.shapeProperties, ctx)}</${tag}>`;
564
+ }
565
+ /** Read any CT_ChartLines element: true when bare, decorations when carried. */
566
+ function readChartLines(parent, tag, ctx) {
567
+ const el = findChild(parent, tag);
568
+ if (!el) return void 0;
569
+ const spPrEl = findChild(el, "c:spPr");
570
+ if (!spPrEl) return true;
571
+ const lines = {};
572
+ const shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
573
+ if (shapeProperties) lines.shapeProperties = shapeProperties;
574
+ return lines;
575
+ }
576
+ /** Read one secondary chart group (combo): own series, flags, and 2D group tail. */
577
+ function readSecondaryGroup(secondaryEl, ctx) {
578
+ const mapping = TAG_TO_CHART_TYPE[secondaryEl.name ?? ""];
579
+ if (!mapping) return void 0;
580
+ let secType = mapping.type;
581
+ if (secondaryEl.name === "c:barChart" || secondaryEl.name === "c:bar3DChart") {
582
+ const barDir = findChild(secondaryEl, "c:barDir");
583
+ const barDirVal = barDir ? attr(barDir, "val") : void 0;
584
+ if (barDirVal === "bar") secType = "bar";
585
+ else if (barDirVal === "col") secType = "column";
586
+ }
587
+ const g = {
588
+ type: secType,
589
+ series: []
590
+ };
591
+ const grouping = readValStr(secondaryEl, "c:grouping");
592
+ if (grouping) g.grouping = grouping;
593
+ const varyColors = readBoolAttr(secondaryEl, "c:varyColors");
594
+ if (varyColors !== void 0) g.varyColors = varyColors;
595
+ const groupLabels = readDataLabels(secondaryEl, ctx);
596
+ if (groupLabels) g.dataLabels = groupLabels;
597
+ if (secType === "bar" || secType === "column") {
598
+ const gapWidth = readValNum(secondaryEl, "c:gapWidth");
599
+ if (gapWidth !== void 0) g.gapWidth = gapWidth;
600
+ if (!mapping.threeD) {
601
+ const overlap = readValNum(secondaryEl, "c:overlap");
602
+ if (overlap !== void 0) g.overlap = overlap;
603
+ } else {
604
+ const gapDepth = readValNum(secondaryEl, "c:gapDepth");
605
+ if (gapDepth !== void 0) g.gapDepth = gapDepth;
606
+ }
607
+ const seriesLines = readChartLines(secondaryEl, "c:serLines", ctx);
608
+ if (seriesLines !== void 0) g.seriesLines = seriesLines;
609
+ } else if (secType === "line") {
610
+ const dropLines = readChartLines(secondaryEl, "c:dropLines", ctx);
611
+ if (dropLines !== void 0) g.dropLines = dropLines;
612
+ const highLowLines = readChartLines(secondaryEl, "c:hiLowLines", ctx);
613
+ if (highLowLines !== void 0) g.highLowLines = highLowLines;
614
+ const upDownBars = findChild(secondaryEl, "c:upDownBars");
615
+ if (upDownBars) {
616
+ g.upDownBars = true;
617
+ const gw = readValNum(upDownBars, "c:gapWidth");
618
+ if (gw !== void 0) g.upDownBarsGapWidth = gw;
619
+ }
620
+ const markers = readBoolAttr(secondaryEl, "c:marker");
621
+ if (markers !== void 0) g.markers = markers;
622
+ const smooth = readBoolAttr(secondaryEl, "c:smooth");
623
+ if (smooth !== void 0) g.smooth = smooth;
624
+ } else if (secType === "area") {
625
+ const dropLines = readChartLines(secondaryEl, "c:dropLines", ctx);
626
+ if (dropLines !== void 0) g.dropLines = dropLines;
627
+ }
628
+ const secAxIds = children(secondaryEl, "c:axId");
629
+ if (secAxIds.length > 0) {
630
+ const ids = secAxIds.map((e) => Number(attr(e, "val"))).filter((n) => !isNaN(n));
631
+ if (ids.length > 0) g.axisIds = ids;
632
+ }
633
+ const secSeries = [];
634
+ for (const serEl of children(secondaryEl, "c:ser")) {
635
+ const { name, literal: nameLiteral } = readSeriesName(serEl);
636
+ const txEl = findChild(serEl, "c:tx");
637
+ const nameFormula = txEl ? readRefMeta(txEl).formula : void 0;
638
+ const valueEl = findChild(serEl, "c:val") ?? findChild(serEl, "c:yVal");
639
+ const valueLiteral = valueEl ? findChild(valueEl, "c:numLit") !== void 0 : false;
640
+ const values = valueEl ? readNumCache(valueEl) : [];
641
+ const valMeta = valueEl ? readRefMeta(valueEl) : {};
642
+ secSeries.push({
643
+ name,
644
+ ...nameLiteral ? { nameLiteral } : {},
645
+ ...nameFormula ? { nameFormula } : {},
646
+ ...valueLiteral ? { valueLiteral } : {},
647
+ ...valMeta.formula ? { valueFormula: valMeta.formula } : {},
648
+ ...valMeta.formatCode ? { formatCode: valMeta.formatCode } : {},
649
+ values,
650
+ ...readSeriesCommon(serEl, ctx)
651
+ });
652
+ }
653
+ g.series = secSeries;
654
+ return g;
655
+ }
656
+ function stringifySecondaryGroup(g, opts, ctx) {
657
+ const parts = [chartTypeHeader(g)];
658
+ for (const [i, series] of (g.series ?? []).entries()) parts.push(stringifySeries(i, series, opts, ctx, g.type));
659
+ if (g.dataLabels) parts.push(stringifyDataLabels(g.dataLabels, ctx));
660
+ switch (g.type) {
661
+ case "bar":
662
+ case "column":
663
+ if (g.gapWidth !== void 0) parts.push(valEl("c:gapWidth", g.gapWidth));
664
+ if (g.overlap !== void 0) parts.push(valEl("c:overlap", g.overlap));
665
+ parts.push(stringifyChartLines("c:serLines", g.seriesLines, ctx));
666
+ break;
667
+ case "line":
668
+ parts.push(stringifyChartLines("c:dropLines", g.dropLines, ctx));
669
+ parts.push(stringifyChartLines("c:hiLowLines", g.highLowLines, ctx));
670
+ if (g.upDownBars) parts.push(stringifyUpDownBars(g.upDownBarsGapWidth));
671
+ if (g.markers !== void 0) parts.push(`<c:marker${boolVal(g.markers)}/>`);
672
+ if (g.smooth !== void 0) parts.push(`<c:smooth${boolVal(g.smooth)}/>`);
673
+ break;
674
+ case "area": parts.push(stringifyChartLines("c:dropLines", g.dropLines, ctx));
675
+ }
676
+ for (const id of g.axisIds ?? []) parts.push(valEl("c:axId", id));
677
+ return `${parts.join("")}</${CHART_TYPE_TAGS[g.type]}>`;
678
+ }
679
+ function stringifyTitle(title, ctx) {
680
+ if (typeof title !== "string") {
681
+ const parts = [];
682
+ if (title.text !== void 0) parts.push(typeof title.text === "string" ? `<c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title.text)}</a:t></a:r></a:p></c:rich></c:tx>` : `<c:tx><c:rich>${textBodyDesc.stringify(title.text, ctx) ?? ""}</c:rich></c:tx>`);
683
+ if (title.layout !== void 0) parts.push(title.layout === true ? "<c:layout/>" : stringifyLayout(title.layout));
684
+ if (title.overlay !== void 0) parts.push(`<c:overlay${boolVal(title.overlay)}/>`);
685
+ if (title.shapeProperties) parts.push(chartSpPr(title.shapeProperties, ctx));
686
+ if (title.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(title.textProperties, ctx) ?? ""}</c:txPr>`);
687
+ return `<c:title>${parts.join("")}</c:title>`;
688
+ }
689
+ return `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(title)}</a:t></a:r></a:p></c:rich></c:tx></c:title>`;
512
690
  }
513
- const LEGEND_TXPR = "<c:txPr><a:bodyPr rot=\"0\" spcFirstLastPara=\"1\" vertOverflow=\"ellipsis\" vert=\"horz\" wrap=\"square\" anchor=\"ctr\" anchorCtr=\"1\"/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr lang=\"en-US\"/></a:p></c:txPr>";
514
- function stringifyLegendEntry(entry) {
515
- if (!entry.delete) return "";
516
- return `<c:legendEntry><c:idx val="${entry.index}"/><c:delete val="1"/></c:legendEntry>`;
691
+ function stringifyLegendEntry(entry, ctx) {
692
+ if (entry.delete) return `<c:legendEntry><c:idx val="${entry.index}"/><c:delete val="1"/></c:legendEntry>`;
693
+ if (entry.textProperties) {
694
+ const txPr = textBodyDesc.stringify(entry.textProperties, ctx) ?? "";
695
+ return `<c:legendEntry><c:idx val="${entry.index}"/><c:txPr>${txPr}</c:txPr></c:legendEntry>`;
696
+ }
697
+ return "";
517
698
  }
518
- function stringifyLegend(opts) {
519
- return `<c:legend><c:legendPos val="${opts.legendPosition ?? "b"}"/>${(opts.legendEntries ?? []).map(stringifyLegendEntry).join("")}<c:layout/><c:overlay val="0"/><c:spPr><a:noFill/><a:ln><a:noFill/></a:ln><a:effectLst/></c:spPr>${LEGEND_TXPR}</c:legend>`;
699
+ function stringifyLegend(opts, ctx) {
700
+ return `<c:legend>${opts.legendPosition !== void 0 ? `<c:legendPos val="${xsdLegendPosition.to(opts.legendPosition)}"/>` : opts.showLegend === true ? "" : `<c:legendPos val="b"/>`}${(opts.legendEntries ?? []).map((e) => stringifyLegendEntry(e, ctx)).join("")}${opts.legendLayout === true ? "<c:layout/>" : opts.legendLayout ? stringifyLayout(opts.legendLayout) : ""}${opts.legendOverlay !== void 0 ? `<c:overlay${boolVal(opts.legendOverlay)}/>` : ""}${chartSpPr(opts.legendShapeProperties, ctx)}${opts.legendTextProperties ? `<c:txPr>${textBodyDesc.stringify(opts.legendTextProperties, ctx) ?? ""}</c:txPr>` : ""}</c:legend>`;
520
701
  }
521
702
  function stringifyPivotSource(opts) {
522
703
  return `<c:pivotSource><c:name>${escapeXml(opts.name)}</c:name><c:fmtId val="${opts.formatId}"/></c:pivotSource>`;
523
704
  }
524
- function stringifyPivotFormats(formats) {
705
+ function stringifyPivotFormats(formats, ctx) {
525
706
  return `<c:pivotFmts>${formats.map((f) => {
526
707
  let entry = `<c:idx val="${f.index}"/>`;
527
- if (f.marker) entry += stringifyMarker$1(f.marker);
708
+ if (f.marker) entry += stringifyMarker$1(f.marker, ctx);
528
709
  return `<c:pivotFmt>${entry}</c:pivotFmt>`;
529
710
  }).join("")}</c:pivotFmts>`;
530
711
  }
531
712
  function stringifyBandFormats(formats) {
532
713
  return `<c:bandFmts>${formats.map((f) => `<c:bandFmt><c:idx val="${f.index}"/></c:bandFmt>`).join("")}</c:bandFmts>`;
533
714
  }
534
- function noFillSpPr() {
535
- return `<c:spPr><a:noFill/><a:ln><a:noFill/></a:ln><a:effectLst/></c:spPr>`;
536
- }
537
- function chartTxPr() {
538
- return `<c:txPr><a:bodyPr/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr lang="en-US"/></a:p></c:txPr>`;
715
+ /**
716
+ * Wrap c:spPr inner content. An empty shape-properties object is a real
717
+ * `<c:spPr/>` placeholder (presence itself is the content), so undefined
718
+ * inner still emits the bare element.
719
+ */
720
+ function chartSpPr(opts, ctx) {
721
+ if (!opts) return "";
722
+ return `<c:spPr>${shapePropertiesDesc.stringify(opts, ctx) ?? ""}</c:spPr>`;
539
723
  }
540
724
  /** Default bottom category axis (c:catAx) for generated charts. */
541
725
  function categoryAxis(id, crossAxisId) {
@@ -543,10 +727,10 @@ function categoryAxis(id, crossAxisId) {
543
727
  kind: "category",
544
728
  id,
545
729
  crossAxisId,
546
- scaling: { orientation: "minMax" },
730
+ scaling: { orientation: "ascending" },
547
731
  delete: false,
548
- position: "b",
549
- crosses: "autoZero",
732
+ position: "bottom",
733
+ crosses: "zero",
550
734
  auto: true,
551
735
  labelOffset: 100,
552
736
  noMultiLevelLabel: false
@@ -558,11 +742,11 @@ function valueAxis(id, crossAxisId) {
558
742
  kind: "value",
559
743
  id,
560
744
  crossAxisId,
561
- scaling: { orientation: "minMax" },
745
+ scaling: { orientation: "ascending" },
562
746
  delete: false,
563
- position: "l",
747
+ position: "left",
564
748
  numberFormat: "General",
565
- crosses: "autoZero"
749
+ crosses: "zero"
566
750
  };
567
751
  }
568
752
  /** Default series axis (c:serAx) for surface charts. */
@@ -571,11 +755,11 @@ function seriesAxis(id, crossAxisId) {
571
755
  kind: "series",
572
756
  id,
573
757
  crossAxisId,
574
- scaling: { orientation: "minMax" },
758
+ scaling: { orientation: "ascending" },
575
759
  delete: false,
576
- position: "b",
760
+ position: "bottom",
577
761
  numberFormat: "General",
578
- crosses: "autoZero",
762
+ crosses: "zero",
579
763
  tickLabelSkip: 1
580
764
  };
581
765
  }
@@ -598,10 +782,19 @@ function defaultAxesFor(chartType, threeD) {
598
782
  }
599
783
  /** Provided axes override defaults; otherwise defaults are derived from chart type. */
600
784
  function axesFor(opts) {
601
- return opts.axes ?? defaultAxesFor(opts.type, opts.threeD);
785
+ if (!opts.axes) return defaultAxesFor(opts.type, opts.threeD);
786
+ const slots = defaultAxesFor(opts.type, opts.threeD);
787
+ return opts.axes.map((axis, i) => {
788
+ const slot = slots[i] ?? slots[slots.length - 1];
789
+ return {
790
+ ...axis,
791
+ id: axis.id ?? slot.id,
792
+ crossAxisId: axis.crossAxisId ?? slot.crossAxisId
793
+ };
794
+ });
602
795
  }
603
- function stringifyAxes(opts) {
604
- return axesFor(opts).map(stringifyAxis).join("");
796
+ function stringifyAxes(opts, ctx) {
797
+ return axesFor(opts).map((axis) => stringifyAxis(axis, ctx)).join("");
605
798
  }
606
799
  function readStrCache(el) {
607
800
  const strRef = findChild(el, "c:strRef");
@@ -609,13 +802,53 @@ function readStrCache(el) {
609
802
  const strCache = findChild(strRef, "c:strCache");
610
803
  if (!strCache?.elements) return [];
611
804
  const result = [];
612
- for (const pt of strCache.elements) if (pt.name === "c:pt" && pt.elements) {
613
- const v = pt.elements.find((c) => c.name === "c:v");
805
+ for (const pt of strCache.elements) if (pt.name === "c:pt") {
806
+ const v = findChild(pt, "c:v");
614
807
  const text = v ? textOf(v) : "";
615
808
  if (text !== "") result.push(text);
616
809
  }
617
810
  return result;
618
811
  }
812
+ /** Numeric category labels read as literal text (c:cat > c:numRef > c:numCache). */
813
+ function readNumCacheText(el) {
814
+ const numRef = findChild(el, "c:numRef");
815
+ if (!numRef) return [];
816
+ const numCache = findChild(numRef, "c:numCache");
817
+ if (!numCache?.elements) return [];
818
+ const result = [];
819
+ for (const pt of numCache.elements) if (pt.name === "c:pt") {
820
+ const v = findChild(pt, "c:v");
821
+ const text = v ? textOf(v) ?? "" : "";
822
+ result.push(text);
823
+ }
824
+ return result;
825
+ }
826
+ /** Reference metadata on a data-source slot: the c:f formula and, for numRef,
827
+ * the cached c:formatCode — both round-trip only. */
828
+ function readRefMeta(el) {
829
+ const strRef = findChild(el, "c:strRef");
830
+ const numRef = strRef ? void 0 : findChild(el, "c:numRef");
831
+ const ref = strRef ?? numRef;
832
+ const meta = {};
833
+ if (ref) {
834
+ const f = findChild(ref, "c:f");
835
+ const text = f ? textOf(f) : "";
836
+ if (text) meta.formula = text;
837
+ }
838
+ if (numRef) {
839
+ const cache = findChild(numRef, "c:numCache");
840
+ const fc = cache ? findChild(cache, "c:formatCode") : void 0;
841
+ const text = fc ? textOf(fc) : "";
842
+ if (text) meta.formatCode = text;
843
+ }
844
+ const numLit = strRef || numRef ? void 0 : findChild(el, "c:numLit");
845
+ if (numLit) {
846
+ const fc = findChild(numLit, "c:formatCode");
847
+ const text = fc ? textOf(fc) : "";
848
+ if (text) meta.formatCode = text;
849
+ }
850
+ return meta;
851
+ }
619
852
  function readStrLit(el) {
620
853
  const strLit = findChild(el, "c:strLit");
621
854
  if (!strLit) return void 0;
@@ -645,14 +878,32 @@ function readMultiLvlStrCache(el) {
645
878
  }
646
879
  return levels;
647
880
  }
881
+ function readNumLitPoints(numLit) {
882
+ const result = [];
883
+ for (const pt of numLit.elements ?? []) if (pt.name === "c:pt") {
884
+ const v = findChild(pt, "c:v");
885
+ const text = v ? textOf(v) : "";
886
+ if (text !== "") result.push(Number(text));
887
+ }
888
+ return result;
889
+ }
890
+ /** A scatter series carries numeric x values when c:xVal holds the
891
+ * CT_NumDataSource choice (numRef/numLit); the label-x shape stringifies
892
+ * x as a strRef category source instead. */
893
+ function hasNumericXRef(serEl) {
894
+ const xVal = findChild(serEl, "c:xVal");
895
+ return xVal !== void 0 && (findChild(xVal, "c:numRef") !== void 0 || findChild(xVal, "c:numLit") !== void 0);
896
+ }
648
897
  function readNumCache(el) {
898
+ const numLit = findChild(el, "c:numLit");
899
+ if (numLit) return readNumLitPoints(numLit);
649
900
  const numRef = findChild(el, "c:numRef");
650
901
  if (!numRef) return [];
651
902
  const numCache = findChild(numRef, "c:numCache");
652
903
  if (!numCache?.elements) return [];
653
904
  const result = [];
654
- for (const pt of numCache.elements) if (pt.name === "c:pt" && pt.elements) {
655
- const v = pt.elements.find((c) => c.name === "c:v");
905
+ for (const pt of numCache.elements) if (pt.name === "c:pt") {
906
+ const v = findChild(pt, "c:v");
656
907
  const text = v ? textOf(v) : "";
657
908
  if (text !== "") result.push(Number(text));
658
909
  }
@@ -660,16 +911,79 @@ function readNumCache(el) {
660
911
  }
661
912
  function readSeriesName(serEl) {
662
913
  const tx = findChild(serEl, "c:tx");
663
- if (!tx) return "";
664
- return readStrCache(tx)[0] ?? "";
914
+ if (!tx) return {
915
+ name: void 0,
916
+ literal: false
917
+ };
918
+ const v = findChild(tx, "c:v");
919
+ if (v && !findChild(tx, "c:strRef")) {
920
+ const text = textOf(v);
921
+ return {
922
+ name: text !== "" ? text : void 0,
923
+ literal: true
924
+ };
925
+ }
926
+ return {
927
+ name: readStrCache(tx)[0] ?? "",
928
+ literal: false
929
+ };
930
+ }
931
+ /** Read a c:title. Plain text stays a string; layout/overlay/spPr/txPr
932
+ * decorations promote it to the ChartTitleOptions object form. */
933
+ /** Read the title's c:tx > c:rich body; undefined when absent or strRef-linked. */
934
+ function readTitleBody(titleEl, ctx) {
935
+ const rich = findChild(findChild(titleEl, "c:tx") ?? titleEl, "c:rich");
936
+ if (!rich) return void 0;
937
+ return collapseTitleBody(textBodyDesc.parse(rich, ctx));
938
+ }
939
+ /**
940
+ * Collapse a parsed title body to its plain text when it is exactly what the
941
+ * string form emits (empty bodyPr/listStyle, one bare run), keeping simple
942
+ * titles readable in the Options JSON.
943
+ */
944
+ function collapseTitleBody(body) {
945
+ if (body.listStyle !== void 0) return body;
946
+ if (body.bodyProperties !== void 0 && Object.keys(body.bodyProperties).length > 0) return body;
947
+ const ps = body.paragraphs ?? [];
948
+ if (ps.length !== 1) return body;
949
+ const p = ps[0];
950
+ if (p === void 0) return body;
951
+ if (typeof p === "string") return p;
952
+ if (p.properties !== void 0 || p.children !== void 0) return body;
953
+ if (p.endParagraphProperties !== void 0 && p.endParagraphProperties !== false) return body;
954
+ return p.text ?? "";
955
+ }
956
+ function readTitle(titleEl, ctx) {
957
+ const body = readTitleBody(titleEl, ctx);
958
+ const text = body === void 0 ? readTitleText(titleEl) : void 0;
959
+ const layoutEl = findChild(titleEl, "c:layout");
960
+ const overlayEl = findChild(titleEl, "c:overlay");
961
+ const spPrEl = findChild(titleEl, "c:spPr");
962
+ const txPrEl = findChild(titleEl, "c:txPr");
963
+ if (!layoutEl && !overlayEl && !spPrEl && !txPrEl) {
964
+ if (typeof body === "string" || body === void 0) return body ?? text ?? "";
965
+ return { text: body };
966
+ }
967
+ const title = {};
968
+ if (body !== void 0) title.text = body;
969
+ else if (text !== void 0) title.text = text;
970
+ if (layoutEl) title.layout = readManualLayout(layoutEl) ?? true;
971
+ if (overlayEl) title.overlay = parseOnOff(attr(overlayEl, "val")) ?? false;
972
+ if (spPrEl) title.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
973
+ if (txPrEl) title.textProperties = textBodyDesc.parse(txPrEl, ctx);
974
+ return title;
665
975
  }
666
976
  function readTitleText(titleEl) {
667
977
  const tx = findChild(titleEl, "c:tx");
668
978
  if (!tx?.elements) return void 0;
669
- for (const child of tx.elements) if (child.name === "c:rich" && child.elements) {
670
- for (const sub of child.elements) if (sub.name === "a:p" && sub.elements) {
671
- for (const r of sub.elements) if (r.name === "a:r" && r.elements) {
672
- for (const t of r.elements) if (t.name === "a:t") {
979
+ for (const child of tx.elements) {
980
+ if (child.name !== "c:rich") continue;
981
+ for (const sub of child.elements ?? []) {
982
+ if (sub.name !== "a:p") continue;
983
+ for (const r of sub.elements ?? []) {
984
+ if (r.name !== "a:r") continue;
985
+ const t = findChild(r, "a:t");
986
+ if (t) {
673
987
  const text = textOf(t);
674
988
  if (text) return text;
675
989
  }
@@ -700,8 +1014,8 @@ function readNumLit(el, childName) {
700
1014
  if (!child) return void 0;
701
1015
  const numLit = findChild(child, "c:numLit");
702
1016
  if (!numLit?.elements) return void 0;
703
- for (const pt of numLit.elements) if (pt.name === "c:pt" && pt.elements) {
704
- const v = pt.elements.find((c) => c.name === "c:v");
1017
+ for (const pt of numLit.elements) if (pt.name === "c:pt") {
1018
+ const v = findChild(pt, "c:v");
705
1019
  if (v) {
706
1020
  const text = textOf(v);
707
1021
  if (text) return Number(text);
@@ -714,7 +1028,7 @@ function readTrendlines(serEl) {
714
1028
  return tlEls.map((tl) => {
715
1029
  const opts = {};
716
1030
  const type = readValStr(tl, "c:trendlineType");
717
- if (type) opts.type = type;
1031
+ if (type) opts.type = xsdTrendlineType.from(type);
718
1032
  const order = readValNum(tl, "c:order");
719
1033
  if (order !== void 0) opts.order = order;
720
1034
  const period = readValNum(tl, "c:period");
@@ -729,7 +1043,8 @@ function readTrendlines(serEl) {
729
1043
  if (dispRSqr !== void 0) opts.dispRSqr = dispRSqr;
730
1044
  const dispEq = readBoolAttr(tl, "c:dispEq");
731
1045
  if (dispEq !== void 0) opts.dispEq = dispEq;
732
- const nameText = textOf(findChild(tl, "c:name"));
1046
+ const nameEl = findChild(tl, "c:name");
1047
+ const nameText = textOf(nameEl);
733
1048
  if (nameText) opts.name = nameText;
734
1049
  const labelFmt = attr(findChild(findChild(tl, "c:trendlineLbl"), "c:numFmt"), "formatCode");
735
1050
  if (labelFmt) opts.label = { numberFormat: labelFmt };
@@ -745,7 +1060,7 @@ function readErrBars(serEl) {
745
1060
  const barType = readValStr(ebEl, "c:errBarType");
746
1061
  if (barType) opts.barType = barType;
747
1062
  const valueType = readValStr(ebEl, "c:errValType");
748
- if (valueType) opts.valueType = valueType;
1063
+ if (valueType) opts.valueType = xsdErrorValueType.from(valueType);
749
1064
  const noEndCap = readBoolAttr(ebEl, "c:noEndCap");
750
1065
  if (noEndCap !== void 0) opts.noEndCap = noEndCap;
751
1066
  const plusValue = readNumLit(ebEl, "c:plus");
@@ -756,12 +1071,26 @@ function readErrBars(serEl) {
756
1071
  if (value !== void 0) opts.value = value;
757
1072
  return opts;
758
1073
  }
759
- function readDataLabels(serEl) {
1074
+ function readDataLabels(serEl, ctx) {
760
1075
  const dlEl = findChild(serEl, "c:dLbls");
761
1076
  if (!dlEl) return void 0;
762
1077
  const opts = {};
1078
+ const groupDelete = readBoolAttr(dlEl, "c:delete");
1079
+ if (groupDelete !== void 0) opts.delete = groupDelete;
1080
+ const numFmt = attr(findChild(dlEl, "c:numFmt"), "formatCode");
1081
+ if (numFmt) opts.numberFormat = numFmt;
1082
+ const dlSpPr = findChild(dlEl, "c:spPr");
1083
+ if (dlSpPr) {
1084
+ const shapeProperties = shapePropertiesDesc.parse(dlSpPr, ctx);
1085
+ if (shapeProperties) opts.shapeProperties = shapeProperties;
1086
+ }
1087
+ const dlTxPr = findChild(dlEl, "c:txPr");
1088
+ if (dlTxPr) {
1089
+ const textProperties = textBodyDesc.parse(dlTxPr, ctx);
1090
+ if (textProperties) opts.textProperties = textProperties;
1091
+ }
763
1092
  const position = readValStr(dlEl, "c:dLblPos");
764
- if (position) opts.position = position;
1093
+ if (position) opts.position = xsdDataLabelPosition.from(position);
765
1094
  const showLegendKey = readBoolAttr(dlEl, "c:showLegendKey");
766
1095
  if (showLegendKey !== void 0) opts.showLegendKey = showLegendKey;
767
1096
  const showVal = readBoolAttr(dlEl, "c:showVal");
@@ -776,22 +1105,53 @@ function readDataLabels(serEl) {
776
1105
  if (showBubbleSize !== void 0) opts.showBubbleSize = showBubbleSize;
777
1106
  const showLeaderLines = readBoolAttr(dlEl, "c:showLeaderLines");
778
1107
  if (showLeaderLines !== void 0) opts.showLeaderLines = showLeaderLines;
779
- const sepText = textOf(findChild(dlEl, "c:separator"));
1108
+ const sepEl = findChild(dlEl, "c:separator");
1109
+ const sepText = textOf(sepEl);
780
1110
  if (sepText) opts.separator = sepText;
781
1111
  const lblEls = children(dlEl, "c:dLbl");
782
1112
  if (lblEls.length > 0) opts.labels = lblEls.map((el) => {
783
1113
  const result = { index: readValNum(el, "c:idx") ?? 0 };
784
1114
  if (findChild(el, "c:delete")) result.delete = true;
1115
+ const layoutEl = findChild(el, "c:layout");
1116
+ if (layoutEl) result.layout = readManualLayout(layoutEl) ?? true;
1117
+ const richEl = findChild(findChild(el, "c:tx"), "c:rich");
1118
+ if (richEl) {
1119
+ const text = textBodyDesc.parse(richEl, ctx);
1120
+ if (text) result.text = text;
1121
+ }
785
1122
  const numFmt = attr(findChild(el, "c:numFmt"), "formatCode");
786
1123
  if (numFmt) result.numberFormat = numFmt;
1124
+ const lblSpPr = findChild(el, "c:spPr");
1125
+ if (lblSpPr) {
1126
+ const shapeProperties = shapePropertiesDesc.parse(lblSpPr, ctx);
1127
+ if (shapeProperties) result.shapeProperties = shapeProperties;
1128
+ }
1129
+ const lblTxPr = findChild(el, "c:txPr");
1130
+ if (lblTxPr) {
1131
+ const textProperties = textBodyDesc.parse(lblTxPr, ctx);
1132
+ if (textProperties) result.textProperties = textProperties;
1133
+ }
787
1134
  const pos = readValStr(el, "c:dLblPos");
788
- if (pos) result.position = pos;
1135
+ if (pos) result.position = xsdDataLabelPosition.from(pos);
1136
+ for (const flag of [
1137
+ "showLegendKey",
1138
+ "showVal",
1139
+ "showCatName",
1140
+ "showSerName",
1141
+ "showPercent",
1142
+ "showBubbleSize"
1143
+ ]) {
1144
+ const v = readBoolAttr(el, `c:${flag}`);
1145
+ if (v !== void 0) result[flag] = v;
1146
+ }
1147
+ const sep = textOf(findChild(el, "c:separator"));
1148
+ if (sep) result.separator = sep;
789
1149
  return result;
790
1150
  });
791
1151
  if (findChild(dlEl, "c:leaderLines")) opts.leaderLines = true;
792
1152
  return opts;
793
1153
  }
794
- function readMarker$1(parent) {
1154
+ function readMarker$1(parent, ctx) {
795
1155
  const el = findChild(parent, "c:marker");
796
1156
  if (!el) return void 0;
797
1157
  const opts = {};
@@ -799,6 +1159,11 @@ function readMarker$1(parent) {
799
1159
  if (symbol) opts.symbol = symbol;
800
1160
  const size = readValNum(el, "c:size");
801
1161
  if (size !== void 0) opts.size = size;
1162
+ const spPr = findChild(el, "c:spPr");
1163
+ if (spPr) {
1164
+ const shapeProperties = shapePropertiesDesc.parse(spPr, ctx);
1165
+ if (shapeProperties) opts.shapeProperties = shapeProperties;
1166
+ }
802
1167
  return Object.keys(opts).length ? opts : void 0;
803
1168
  }
804
1169
  function readPictureOptions(parent) {
@@ -817,36 +1182,47 @@ function readPictureOptions(parent) {
817
1182
  if (stack !== void 0) opts.pictureStackUnit = stack;
818
1183
  return Object.keys(opts).length ? opts : void 0;
819
1184
  }
820
- function readDataPoints(serEl) {
1185
+ function readDataPoints(serEl, ctx) {
821
1186
  const els = children(serEl, "c:dPt");
822
1187
  if (els.length === 0) return void 0;
823
1188
  return els.map((el) => {
824
1189
  const dp = { index: readValNum(el, "c:idx") ?? 0 };
825
1190
  const invertIfNegative = readBoolAttr(el, "c:invertIfNegative");
826
1191
  if (invertIfNegative !== void 0) dp.invertIfNegative = invertIfNegative;
827
- const marker = readMarker$1(el);
1192
+ const marker = readMarker$1(el, ctx);
828
1193
  if (marker) dp.marker = marker;
829
1194
  const bubble3D = readBoolAttr(el, "c:bubble3D");
830
1195
  if (bubble3D !== void 0) dp.bubble3D = bubble3D;
831
1196
  const explosion = readValNum(el, "c:explosion");
832
1197
  if (explosion !== void 0) dp.explosion = explosion;
1198
+ const spPr = findChild(el, "c:spPr");
1199
+ if (spPr) {
1200
+ const shapeProperties = shapePropertiesDesc.parse(spPr, ctx);
1201
+ if (shapeProperties) dp.shapeProperties = shapeProperties;
1202
+ }
833
1203
  const pictureOptions = readPictureOptions(el);
834
1204
  if (pictureOptions) dp.pictureOptions = pictureOptions;
835
1205
  return dp;
836
1206
  });
837
1207
  }
838
1208
  /** Read shared ser enhancement fields (CT_Ser children beyond EG_SerShared). */
839
- function readSeriesCommon(serEl) {
1209
+ function readSeriesCommon(serEl, ctx) {
840
1210
  const common = {};
1211
+ const idx = readValNum(serEl, "c:idx");
1212
+ if (idx !== void 0) common.index = idx;
1213
+ const order = readValNum(serEl, "c:order");
1214
+ if (order !== void 0) common.order = order;
1215
+ const spPrEl = findChild(serEl, "c:spPr");
1216
+ if (spPrEl) common.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
841
1217
  const trendlines = readTrendlines(serEl);
842
1218
  if (trendlines) common.trendlines = trendlines;
843
1219
  const errorBars = readErrBars(serEl);
844
1220
  if (errorBars) common.errorBars = errorBars;
845
- const dataLabels = readDataLabels(serEl);
1221
+ const dataLabels = readDataLabels(serEl, ctx);
846
1222
  if (dataLabels) common.dataLabels = dataLabels;
847
- const dataPoints = readDataPoints(serEl);
1223
+ const dataPoints = readDataPoints(serEl, ctx);
848
1224
  if (dataPoints) common.dataPoints = dataPoints;
849
- const marker = readMarker$1(serEl);
1225
+ const marker = readMarker$1(serEl, ctx);
850
1226
  if (marker) common.marker = marker;
851
1227
  const invertIfNegative = readBoolAttr(serEl, "c:invertIfNegative");
852
1228
  if (invertIfNegative !== void 0) common.invertIfNegative = invertIfNegative;
@@ -860,6 +1236,11 @@ function readSeriesCommon(serEl) {
860
1236
  if (shape) common.shape = shape;
861
1237
  const bubble3D = readBoolAttr(serEl, "c:bubble3D");
862
1238
  if (bubble3D !== void 0) common.bubble3D = bubble3D;
1239
+ const extLst = findChild(serEl, "c:extLst");
1240
+ if (extLst) {
1241
+ const inner = stringify(extLst);
1242
+ if (inner) common.ext = inner;
1243
+ }
863
1244
  return common;
864
1245
  }
865
1246
  function readView3D(chartEl) {
@@ -905,25 +1286,43 @@ function readManualLayout(layoutEl) {
905
1286
  if (h !== void 0) opts.h = h;
906
1287
  return Object.keys(opts).length ? opts : void 0;
907
1288
  }
908
- function readSurface(chartEl, tag) {
1289
+ function readSurface(chartEl, tag, ctx) {
909
1290
  const el = findChild(chartEl, tag);
910
1291
  if (!el) return void 0;
1292
+ const opts = {};
911
1293
  const thickness = readValStr(el, "c:thickness");
912
- if (thickness === void 0) return void 0;
913
- return { thickness: thickness.endsWith("%") ? thickness : Number(thickness) };
1294
+ if (thickness !== void 0) opts.thickness = thickness.endsWith("%") ? thickness : Number(thickness);
1295
+ const spPr = findChild(el, "c:spPr");
1296
+ if (spPr) opts.shapeProperties = shapePropertiesDesc.parse(spPr, ctx);
1297
+ return opts;
914
1298
  }
915
- function readChartTypeScalars(chartTypeEl, type, threeD, result) {
1299
+ function readChartTypeScalars(chartTypeEl, type, threeD, result, ctx) {
916
1300
  if (!chartTypeEl) return;
1301
+ if (type !== "surface" && type !== "stock") {
1302
+ const varyColors = readBoolAttr(chartTypeEl, "c:varyColors");
1303
+ if (varyColors !== void 0) result.varyColors = varyColors;
1304
+ }
1305
+ if (type === "column" || type === "bar" || type === "line" || type === "area") {
1306
+ const grouping = readValStr(chartTypeEl, "c:grouping");
1307
+ if (grouping) {
1308
+ if (grouping !== (type === "column" || type === "bar" ? "clustered" : "standard")) result.grouping = grouping;
1309
+ }
1310
+ }
917
1311
  if (type === "column" || type === "bar") {
918
1312
  const gapWidth = readValNum(chartTypeEl, "c:gapWidth");
919
1313
  if (gapWidth !== void 0) result.gapWidth = gapWidth;
920
1314
  if (threeD) {
921
1315
  const gapDepth = readValNum(chartTypeEl, "c:gapDepth");
922
1316
  if (gapDepth !== void 0) result.gapDepth = gapDepth;
1317
+ const shape = readValStr(chartTypeEl, "c:shape");
1318
+ if (shape) result.shape = shape;
923
1319
  } else {
924
1320
  const overlap = readValNum(chartTypeEl, "c:overlap");
925
1321
  if (overlap !== void 0) result.overlap = overlap;
926
1322
  }
1323
+ } else if (type === "area" && threeD) {
1324
+ const gapDepth = readValNum(chartTypeEl, "c:gapDepth");
1325
+ if (gapDepth !== void 0) result.gapDepth = gapDepth;
927
1326
  } else if (type === "pie" || type === "doughnut") {
928
1327
  const firstSliceAng = readValNum(chartTypeEl, "c:firstSliceAng");
929
1328
  if (firstSliceAng !== void 0) result.firstSliceAngle = firstSliceAng;
@@ -935,19 +1334,22 @@ function readChartTypeScalars(chartTypeEl, type, threeD, result) {
935
1334
  const showNeg = readBoolAttr(chartTypeEl, "c:showNegBubbles");
936
1335
  if (showNeg !== void 0) result.showNegativeBubbles = showNeg;
937
1336
  const sizeRep = readValStr(chartTypeEl, "c:sizeRepresents");
938
- if (sizeRep) result.sizeRepresents = sizeRep;
1337
+ if (sizeRep) result.sizeRepresents = xsdSizeRepresents.from(sizeRep);
939
1338
  } else if (type === "surface") {
940
1339
  const wireframe = readBoolAttr(chartTypeEl, "c:wireframe");
941
1340
  if (wireframe !== void 0) result.wireframe = wireframe;
942
1341
  const bandFormats = readBandFormats(chartTypeEl);
943
1342
  if (bandFormats) result.bandFormats = bandFormats;
1343
+ } else if (type === "radar") {
1344
+ const radarStyle = readValStr(chartTypeEl, "c:radarStyle");
1345
+ if (radarStyle) result.radarStyle = radarStyle;
944
1346
  } else if (type === "ofPie") {
945
1347
  const ofPieType = readValStr(chartTypeEl, "c:ofPieType");
946
1348
  if (ofPieType) result.ofPieType = ofPieType;
947
1349
  const gapWidth = readValNum(chartTypeEl, "c:gapWidth");
948
1350
  if (gapWidth !== void 0) result.gapWidth = gapWidth;
949
1351
  const splitType = readValStr(chartTypeEl, "c:splitType");
950
- if (splitType) result.splitType = splitType;
1352
+ if (splitType) result.splitType = xsdSplitType.from(splitType);
951
1353
  const splitPos = readValNum(chartTypeEl, "c:splitPos");
952
1354
  if (splitPos !== void 0) result.splitPosition = splitPos;
953
1355
  const custSplit = findChild(chartTypeEl, "c:custSplit");
@@ -957,38 +1359,53 @@ function readChartTypeScalars(chartTypeEl, type, threeD, result) {
957
1359
  }
958
1360
  const secondPieSize = readValStr(chartTypeEl, "c:secondPieSize");
959
1361
  if (secondPieSize !== void 0) result.secondPieSize = secondPieSize.endsWith("%") ? secondPieSize : Number(secondPieSize);
960
- if (findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1362
+ const seriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1363
+ if (seriesLines !== void 0) result.seriesLines = seriesLines;
961
1364
  }
962
1365
  }
963
- function readChartTypeDecorations(chartTypeEl, type, threeD, result) {
1366
+ function readChartTypeDecorations(chartTypeEl, type, threeD, result, ctx) {
964
1367
  if (!chartTypeEl) return;
965
1368
  const readUpDownBars = (el) => {
966
1369
  result.upDownBars = true;
967
1370
  const gw = readValNum(el, "c:gapWidth");
968
1371
  if (gw !== void 0) result.upDownBarsGapWidth = gw;
969
1372
  };
970
- if (type === "line") if (threeD) {
971
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
972
- } else {
973
- if (findChild(chartTypeEl, "c:hiLowLines")) result.highLowLines = true;
974
- const upDownBars = findChild(chartTypeEl, "c:upDownBars");
975
- if (upDownBars) readUpDownBars(upDownBars);
976
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
977
- }
978
- else if (type === "area") {
979
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
980
- if (threeD && findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1373
+ if (type === "line") {
1374
+ if (threeD) {
1375
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1376
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1377
+ } else {
1378
+ const highLowLinesV = readChartLines(chartTypeEl, "c:hiLowLines", ctx);
1379
+ if (highLowLinesV !== void 0) result.highLowLines = highLowLinesV;
1380
+ const upDownBars = findChild(chartTypeEl, "c:upDownBars");
1381
+ if (upDownBars) readUpDownBars(upDownBars);
1382
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1383
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1384
+ const markers = readBoolAttr(chartTypeEl, "c:marker");
1385
+ if (markers !== void 0) result.markers = markers;
1386
+ const smooth = readBoolAttr(chartTypeEl, "c:smooth");
1387
+ if (smooth !== void 0) result.smooth = smooth;
1388
+ }
1389
+ } else if (type === "area") {
1390
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1391
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1392
+ const threeDSeriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1393
+ if (threeD && threeDSeriesLines !== void 0) result.seriesLines = threeDSeriesLines;
981
1394
  } else if (type === "stock") {
982
- if (findChild(chartTypeEl, "c:dropLines")) result.dropLines = true;
983
- if (findChild(chartTypeEl, "c:hiLowLines")) result.highLowLines = true;
1395
+ const dropLinesV = readChartLines(chartTypeEl, "c:dropLines", ctx);
1396
+ if (dropLinesV !== void 0) result.dropLines = dropLinesV;
1397
+ const highLowLinesV = readChartLines(chartTypeEl, "c:hiLowLines", ctx);
1398
+ if (highLowLinesV !== void 0) result.highLowLines = highLowLinesV;
984
1399
  const upDownBars = findChild(chartTypeEl, "c:upDownBars");
985
1400
  if (upDownBars) readUpDownBars(upDownBars);
986
- if (findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1401
+ const seriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1402
+ if (seriesLines !== void 0) result.seriesLines = seriesLines;
987
1403
  } else if ((type === "column" || type === "bar") && !threeD) {
988
- if (findChild(chartTypeEl, "c:serLines")) result.seriesLines = true;
1404
+ const seriesLines = readChartLines(chartTypeEl, "c:serLines", ctx);
1405
+ if (seriesLines !== void 0) result.seriesLines = seriesLines;
989
1406
  }
990
1407
  }
991
- function readDataTable(plotArea) {
1408
+ function readDataTable(plotArea, ctx) {
992
1409
  if (!plotArea) return void 0;
993
1410
  const dTable = findChild(plotArea, "c:dTable");
994
1411
  if (!dTable) return void 0;
@@ -1001,7 +1418,11 @@ function readDataTable(plotArea) {
1001
1418
  if (outline !== void 0) opts.showOutline = outline;
1002
1419
  const keys = readBoolAttr(dTable, "c:showKeys");
1003
1420
  if (keys !== void 0) opts.showLegendKeys = keys;
1004
- return Object.keys(opts).length ? opts : void 0;
1421
+ const spPrEl = findChild(dTable, "c:spPr");
1422
+ if (spPrEl) opts.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
1423
+ const txPrEl = findChild(dTable, "c:txPr");
1424
+ if (txPrEl) opts.textProperties = textBodyDesc.parse(txPrEl, ctx);
1425
+ return opts;
1005
1426
  }
1006
1427
  function readProtection(el) {
1007
1428
  const protection = findChild(el, "c:protection");
@@ -1049,7 +1470,7 @@ function readPivotSource(el) {
1049
1470
  formatId: Number(attr(fmtIdEl, "val"))
1050
1471
  };
1051
1472
  }
1052
- function readPivotFormats(chart) {
1473
+ function readPivotFormats(chart, ctx) {
1053
1474
  const pf = findChild(chart, "c:pivotFmts");
1054
1475
  if (!pf) return void 0;
1055
1476
  const result = [];
@@ -1057,7 +1478,7 @@ function readPivotFormats(chart) {
1057
1478
  const idxEl = findChild(fmt, "c:idx");
1058
1479
  if (!idxEl) continue;
1059
1480
  const opt = { index: Number(attr(idxEl, "val")) };
1060
- const marker = readMarker$1(fmt);
1481
+ const marker = readMarker$1(fmt, ctx);
1061
1482
  if (marker) opt.marker = marker;
1062
1483
  result.push(opt);
1063
1484
  }
@@ -1073,7 +1494,7 @@ function readBandFormats(chartTypeEl) {
1073
1494
  }
1074
1495
  return result.length ? result : void 0;
1075
1496
  }
1076
- function readLegendEntries(legend) {
1497
+ function readLegendEntries(legend, ctx) {
1077
1498
  const entries = children(legend, "c:legendEntry");
1078
1499
  if (!entries.length) return void 0;
1079
1500
  const result = [];
@@ -1081,26 +1502,41 @@ function readLegendEntries(legend) {
1081
1502
  const idxEl = findChild(entry, "c:idx");
1082
1503
  if (!idxEl) continue;
1083
1504
  const deleteEl = findChild(entry, "c:delete");
1084
- if (!deleteEl) continue;
1085
- const v = attr(deleteEl, "val");
1086
- result.push({
1505
+ if (deleteEl) {
1506
+ const v = attr(deleteEl, "val");
1507
+ result.push({
1508
+ index: Number(attr(idxEl, "val")),
1509
+ delete: parseOnOff(v) ?? true
1510
+ });
1511
+ continue;
1512
+ }
1513
+ const txPrEl = findChild(entry, "c:txPr");
1514
+ if (txPrEl) result.push({
1087
1515
  index: Number(attr(idxEl, "val")),
1088
- delete: parseOnOff(v) ?? true
1516
+ textProperties: textBodyDesc.parse(txPrEl, ctx)
1089
1517
  });
1090
1518
  }
1091
1519
  return result.length ? result : void 0;
1092
1520
  }
1093
- function readLegend(chart) {
1521
+ function readLegend(chart, ctx) {
1094
1522
  const legend = findChild(chart, "c:legend");
1095
1523
  if (!legend) return void 0;
1096
1524
  const result = {};
1097
1525
  const posEl = findChild(legend, "c:legendPos");
1098
1526
  if (posEl) {
1099
1527
  const v = attr(posEl, "val");
1100
- if (v) result.position = v;
1528
+ if (v) result.position = xsdLegendPosition.from(v);
1101
1529
  }
1102
- const entries = readLegendEntries(legend);
1530
+ const entries = readLegendEntries(legend, ctx);
1103
1531
  if (entries) result.entries = entries;
1532
+ const layoutEl = findChild(legend, "c:layout");
1533
+ if (layoutEl) result.layout = readManualLayout(layoutEl) ?? true;
1534
+ const overlayEl = findChild(legend, "c:overlay");
1535
+ if (overlayEl) result.overlay = parseOnOff(attr(overlayEl, "val")) ?? false;
1536
+ const spPrEl = findChild(legend, "c:spPr");
1537
+ if (spPrEl) result.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
1538
+ const txPr = findChild(legend, "c:txPr");
1539
+ if (txPr) result.textProperties = textBodyDesc.parse(txPr, ctx);
1104
1540
  return Object.keys(result).length ? result : void 0;
1105
1541
  }
1106
1542
  function readHeaderFooter(ps) {
@@ -1133,7 +1569,7 @@ function readHeaderFooter(ps) {
1133
1569
  if (differentOddEven !== void 0) opts.differentOddEven = differentOddEven;
1134
1570
  const differentFirst = readFlag("differentFirst");
1135
1571
  if (differentFirst !== void 0) opts.differentFirst = differentFirst;
1136
- return Object.keys(opts).length ? opts : void 0;
1572
+ return opts;
1137
1573
  }
1138
1574
  function readPageMargins(ps) {
1139
1575
  const pm = findChild(ps, "c:pageMargins");
@@ -1191,7 +1627,7 @@ function readPageSetup(ps) {
1191
1627
  if (verticalDpi !== void 0) opts.verticalDpi = verticalDpi;
1192
1628
  const copies = readNum("copies");
1193
1629
  if (copies !== void 0) opts.copies = copies;
1194
- return Object.keys(opts).length ? opts : void 0;
1630
+ return opts;
1195
1631
  }
1196
1632
  function readPrintSettings(el) {
1197
1633
  const ps = findChild(el, "c:printSettings");
@@ -1216,7 +1652,7 @@ const AXIS_KIND_BY_TAG = {
1216
1652
  "c:dateAx": "date",
1217
1653
  "c:serAx": "series"
1218
1654
  };
1219
- function readAxis(el, kind) {
1655
+ function readAxis(el, kind, ctx) {
1220
1656
  const result = {
1221
1657
  kind,
1222
1658
  id: readValNum(el, "c:axId") ?? 0,
@@ -1228,7 +1664,7 @@ function readAxis(el, kind) {
1228
1664
  const logBase = readValNum(scalingEl, "c:logBase");
1229
1665
  if (logBase !== void 0) scaling.logBase = logBase;
1230
1666
  const orientation = readValStr(scalingEl, "c:orientation");
1231
- if (orientation) scaling.orientation = orientation;
1667
+ if (orientation) scaling.orientation = xsdAxisOrientation.from(orientation);
1232
1668
  const max = readValNum(scalingEl, "c:max");
1233
1669
  if (max !== void 0) scaling.max = max;
1234
1670
  const min = readValNum(scalingEl, "c:min");
@@ -1238,18 +1674,18 @@ function readAxis(el, kind) {
1238
1674
  const del = readBoolAttr(el, "c:delete");
1239
1675
  if (del !== void 0) result.delete = del;
1240
1676
  const pos = readValStr(el, "c:axPos");
1241
- if (pos) result.position = pos;
1242
- if (findChild(el, "c:majorGridlines")) result.majorGridlines = true;
1243
- if (findChild(el, "c:minorGridlines")) result.minorGridlines = true;
1677
+ if (pos) result.position = xsdAxisPosition.from(pos);
1678
+ result.majorGridlines = readChartLines(el, "c:majorGridlines", ctx);
1679
+ result.minorGridlines = readChartLines(el, "c:minorGridlines", ctx);
1244
1680
  const titleEl = findChild(el, "c:title");
1245
- if (titleEl) {
1246
- const titleText = readTitleText(titleEl);
1247
- if (titleText !== void 0) result.title = titleText;
1248
- }
1681
+ if (titleEl) result.title = readTitle(titleEl, ctx);
1249
1682
  const numFmtEl = findChild(el, "c:numFmt");
1250
1683
  if (numFmtEl) {
1251
1684
  const formatCode = attr(numFmtEl, "formatCode");
1252
- if (formatCode) result.numberFormat = formatCode;
1685
+ if (formatCode) result.numberFormat = attr(numFmtEl, "sourceLinked") === "0" ? {
1686
+ formatCode,
1687
+ sourceLinked: false
1688
+ } : formatCode;
1253
1689
  }
1254
1690
  const majorTickMark = readValStr(el, "c:majorTickMark");
1255
1691
  if (majorTickMark) result.majorTickMark = majorTickMark;
@@ -1257,11 +1693,15 @@ function readAxis(el, kind) {
1257
1693
  if (minorTickMark) result.minorTickMark = minorTickMark;
1258
1694
  const tickLblPos = readValStr(el, "c:tickLblPos");
1259
1695
  if (tickLblPos) result.tickLabelPosition = tickLblPos;
1696
+ const spPrEl = findChild(el, "c:spPr");
1697
+ if (spPrEl) result.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
1698
+ const axisTxPr = findChild(el, "c:txPr");
1699
+ if (axisTxPr) result.textProperties = textBodyDesc.parse(axisTxPr, ctx);
1260
1700
  const crossesAt = readValNum(el, "c:crossesAt");
1261
1701
  if (crossesAt !== void 0) result.crossesAt = crossesAt;
1262
1702
  else {
1263
1703
  const crosses = readValStr(el, "c:crosses");
1264
- if (crosses) result.crosses = crosses;
1704
+ if (crosses) result.crosses = xsdAxisCrosses.from(crosses);
1265
1705
  }
1266
1706
  if (kind === "category" || kind === "date") {
1267
1707
  const auto = readBoolAttr(el, "c:auto");
@@ -1269,7 +1709,7 @@ function readAxis(el, kind) {
1269
1709
  }
1270
1710
  if (kind === "category") {
1271
1711
  const lblAlgn = readValStr(el, "c:lblAlgn");
1272
- if (lblAlgn) result.labelAlignment = lblAlgn;
1712
+ if (lblAlgn) result.labelAlignment = xsdAxisLabelAlignment.from(lblAlgn);
1273
1713
  }
1274
1714
  if (kind === "category" || kind === "date") {
1275
1715
  const lblOffsetEl = findChild(el, "c:lblOffset");
@@ -1304,7 +1744,7 @@ function readAxis(el, kind) {
1304
1744
  }
1305
1745
  if (kind === "value") {
1306
1746
  const crossBetween = readValStr(el, "c:crossBetween");
1307
- if (crossBetween) result.crossBetween = crossBetween;
1747
+ if (crossBetween) result.crossBetween = xsdAxisCrossBetween.from(crossBetween);
1308
1748
  const dispUnitsEl = findChild(el, "c:dispUnits");
1309
1749
  if (dispUnitsEl) {
1310
1750
  const displayUnits = {};
@@ -1319,60 +1759,88 @@ function readAxis(el, kind) {
1319
1759
  return result;
1320
1760
  }
1321
1761
  /** Read all axis elements (c:catAx/c:valAx/c:dateAx/c:serAx) under plotArea. */
1322
- function readAxes(plotArea) {
1762
+ function readAxes(plotArea, ctx) {
1323
1763
  if (!plotArea?.elements) return void 0;
1324
1764
  const axes = [];
1325
1765
  for (const child of plotArea.elements) {
1326
1766
  if (!child.name) continue;
1327
1767
  const kind = AXIS_KIND_BY_TAG[child.name];
1328
- if (kind) axes.push(readAxis(child, kind));
1768
+ if (kind) axes.push(readAxis(child, kind, ctx));
1329
1769
  }
1330
1770
  return axes.length > 0 ? axes : void 0;
1331
1771
  }
1332
1772
  const chartSpaceDesc = {
1333
1773
  kind: "custom",
1334
- stringify(opts, _ctx) {
1774
+ stringify(opts, ctx) {
1335
1775
  const parts = [];
1336
- parts.push(`<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">`);
1337
- parts.push(valEl("c:date1904", 0));
1338
- parts.push(valEl("c:lang", "en-US"));
1339
- parts.push(valEl("c:roundedCorners", 0));
1340
- if (opts.style !== void 0) parts.push(valEl("c:style", opts.style));
1776
+ const ns = opts.dialect === "strict" ? `xmlns:c="http://purl.oclc.org/ooxml/drawingml/chart" xmlns:a="http://purl.oclc.org/ooxml/drawingml/main" xmlns:r="http://purl.oclc.org/ooxml/officeDocument/relationships"` : `xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"`;
1777
+ parts.push(`<c:chartSpace ${ns}>`);
1778
+ if (opts.date1904 !== void 0) parts.push(`<c:date1904${boolVal(opts.date1904)}/>`);
1779
+ if (opts.lang !== void 0) parts.push(valEl("c:lang", opts.lang));
1780
+ if (opts.roundedCorners !== void 0) parts.push(`<c:roundedCorners${boolVal(opts.roundedCorners)}/>`);
1781
+ if (opts.style2010) {
1782
+ const fallback = opts.style2010.fallbackStyle !== void 0 ? `<mc:Fallback>${valEl("c:style", opts.style2010.fallbackStyle)}</mc:Fallback>` : "";
1783
+ parts.push(`<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><mc:Choice xmlns:c14="http://schemas.microsoft.com/office/drawing/2007/8/2/chart" Requires="c14"><c14:style val="${opts.style2010.style}"/></mc:Choice>${fallback}</mc:AlternateContent>`);
1784
+ } else if (opts.style !== void 0) parts.push(valEl("c:style", opts.style));
1341
1785
  if (opts.colorMappingOverride) parts.push(stringifyColorMapping(opts.colorMappingOverride, "c:clrMapOvr"));
1342
1786
  if (opts.pivotSource) parts.push(stringifyPivotSource(opts.pivotSource));
1343
1787
  if (opts.protection) parts.push(stringifyProtection(opts.protection));
1344
1788
  parts.push("<c:chart>");
1345
- if (opts.title) parts.push(stringifyTitle(opts.title));
1346
- parts.push(valEl("c:autoTitleDeleted", 0));
1347
- if (opts.pivotFormats?.length) parts.push(stringifyPivotFormats(opts.pivotFormats));
1789
+ if (opts.title !== void 0) parts.push(typeof opts.title === "string" && opts.title === "" ? emptyEl("c:title") : stringifyTitle(opts.title, ctx));
1790
+ if (opts.autoTitleDeleted !== void 0) parts.push(`<c:autoTitleDeleted${boolVal(opts.autoTitleDeleted)}/>`);
1791
+ if (opts.pivotFormats?.length) parts.push(stringifyPivotFormats(opts.pivotFormats, ctx));
1348
1792
  if (opts.view3D) parts.push(stringifyView3D(opts.view3D));
1349
- parts.push(stringifySurface("c:floor", opts.floor));
1350
- parts.push(stringifySurface("c:sideWall", opts.sideWall));
1351
- parts.push(stringifySurface("c:backWall", opts.backWall));
1793
+ parts.push(stringifySurface("c:floor", opts.floor, ctx));
1794
+ parts.push(stringifySurface("c:sideWall", opts.sideWall, ctx));
1795
+ parts.push(stringifySurface("c:backWall", opts.backWall, ctx));
1352
1796
  parts.push(`<c:plotArea>${stringifyLayout(opts.plotAreaLayout)}`);
1353
1797
  parts.push(chartTypeHeader(opts));
1354
- for (const [i, series] of opts.series.entries()) parts.push(stringifySeries(i, series, opts));
1355
- parts.push(chartTypeFooter(opts));
1356
- parts.push(stringifyAxes(opts));
1357
- if (opts.dataTable) parts.push(stringifyDataTable(opts.dataTable));
1798
+ for (const [i, series] of (opts.series ?? []).entries()) parts.push(stringifySeries(i, series, opts, ctx));
1799
+ if (opts.dataLabels) parts.push(stringifyDataLabels(opts.dataLabels, ctx));
1800
+ parts.push(chartTypeFooter(opts, ctx));
1801
+ for (const g of opts.secondaryGroups ?? []) parts.push(stringifySecondaryGroup(g, opts, ctx));
1802
+ parts.push(stringifyAxes(opts, ctx));
1803
+ if (opts.dataTable) parts.push(stringifyDataTable(opts.dataTable, ctx));
1804
+ parts.push(chartSpPr(opts.plotAreaShapeProperties, ctx));
1358
1805
  parts.push("</c:plotArea>");
1359
- if (opts.showLegend !== false) parts.push(stringifyLegend(opts));
1806
+ if (opts.showLegend !== false) parts.push(stringifyLegend(opts, ctx));
1360
1807
  parts.push(`<c:plotVisOnly${boolVal(opts.plotVisOnly ?? true)}/>`);
1361
1808
  if (opts.displayBlanksAs !== void 0) parts.push(valEl("c:dispBlanksAs", opts.displayBlanksAs));
1362
1809
  if (opts.showDataLabelsOverMax !== void 0) parts.push(`<c:showDLblsOverMax${boolVal(opts.showDataLabelsOverMax)}/>`);
1363
1810
  parts.push("</c:chart>");
1364
- parts.push(noFillSpPr());
1365
- parts.push(chartTxPr());
1366
- if (opts.externalData) parts.push(stringifyExternalData(opts.externalData));
1811
+ parts.push(chartSpPr(opts.shapeProperties, ctx));
1812
+ if (opts.textProperties) parts.push(`<c:txPr>${textBodyDesc.stringify(opts.textProperties, ctx) ?? ""}</c:txPr>`);
1813
+ if (opts.externalData) {
1814
+ const ext = stringifyExternalData(opts.externalData);
1815
+ if (ext) parts.push(ext);
1816
+ }
1367
1817
  if (opts.printSettings) parts.push(stringifyPrintSettings(opts.printSettings));
1368
1818
  if (opts.userShapes !== void 0) parts.push(`<c:userShapes r:id="${escapeXml(opts.userShapes)}"/>`);
1819
+ if (opts.ext) parts.push(`<c:extLst>${opts.ext}</c:extLst>`);
1369
1820
  parts.push("</c:chartSpace>");
1370
1821
  return parts.join("");
1371
1822
  },
1372
- parse(el, _ctx) {
1823
+ parse(el, ctx) {
1373
1824
  const result = {};
1374
- const styleEl = findChild(el, "c:style");
1375
- if (styleEl?.attributes?.["val"] !== void 0) result.style = Number(styleEl.attributes["val"]);
1825
+ if (el.attributes?.["xmlns:c"] === "http://purl.oclc.org/ooxml/drawingml/chart") result.dialect = "strict";
1826
+ const date1904 = readBoolAttr(el, "c:date1904");
1827
+ if (date1904 !== void 0) result.date1904 = date1904;
1828
+ const langVal = readValStr(el, "c:lang");
1829
+ if (langVal) result.lang = langVal;
1830
+ const roundedCorners = readBoolAttr(el, "c:roundedCorners");
1831
+ if (roundedCorners !== void 0) result.roundedCorners = roundedCorners;
1832
+ const mcStyleEl = findChild(el, "mc:AlternateContent");
1833
+ const c14StyleEl = mcStyleEl && findChild(findChild(mcStyleEl, "mc:Choice") ?? mcStyleEl, "c14:style");
1834
+ if (c14StyleEl?.attributes?.["val"] !== void 0) {
1835
+ const fallbackEl = findFirst(mcStyleEl, "c:style");
1836
+ result.style2010 = {
1837
+ style: Number(c14StyleEl.attributes["val"]),
1838
+ ...fallbackEl?.attributes?.["val"] !== void 0 ? { fallbackStyle: Number(fallbackEl.attributes["val"]) } : {}
1839
+ };
1840
+ } else {
1841
+ const styleEl = findChild(el, "c:style");
1842
+ if (styleEl?.attributes?.["val"] !== void 0) result.style = Number(styleEl.attributes["val"]);
1843
+ }
1376
1844
  const colorMappingOverride = parseColorMapping(findChild(el, "c:clrMapOvr"));
1377
1845
  if (colorMappingOverride) result.colorMappingOverride = colorMappingOverride;
1378
1846
  const protection = readProtection(el);
@@ -1382,33 +1850,37 @@ const chartSpaceDesc = {
1382
1850
  const chart = findChild(el, "c:chart");
1383
1851
  if (!chart) return result;
1384
1852
  const titleEl = findChild(chart, "c:title");
1385
- if (titleEl) {
1386
- const title = readTitleText(titleEl);
1387
- if (title !== void 0) result.title = title;
1388
- }
1389
- const pivotFormats = readPivotFormats(chart);
1853
+ if (titleEl) result.title = readTitle(titleEl, ctx);
1854
+ const autoTitleDeleted = readBoolAttr(chart, "c:autoTitleDeleted");
1855
+ if (autoTitleDeleted !== void 0) result.autoTitleDeleted = autoTitleDeleted;
1856
+ const pivotFormats = readPivotFormats(chart, ctx);
1390
1857
  if (pivotFormats) result.pivotFormats = pivotFormats;
1391
1858
  const view3D = readView3D(chart);
1392
1859
  if (view3D) result.view3D = view3D;
1393
- const floor = readSurface(chart, "c:floor");
1860
+ const floor = readSurface(chart, "c:floor", ctx);
1394
1861
  if (floor) result.floor = floor;
1395
- const sideWall = readSurface(chart, "c:sideWall");
1862
+ const sideWall = readSurface(chart, "c:sideWall", ctx);
1396
1863
  if (sideWall) result.sideWall = sideWall;
1397
- const backWall = readSurface(chart, "c:backWall");
1864
+ const backWall = readSurface(chart, "c:backWall", ctx);
1398
1865
  if (backWall) result.backWall = backWall;
1399
1866
  const plotArea = findChild(chart, "c:plotArea");
1400
1867
  if (plotArea?.elements) {
1401
1868
  const manualLayout = readManualLayout(findChild(plotArea, "c:layout"));
1402
1869
  if (manualLayout) result.plotAreaLayout = manualLayout;
1403
- const dataTable = readDataTable(plotArea);
1870
+ const dataTable = readDataTable(plotArea, ctx);
1404
1871
  if (dataTable) result.dataTable = dataTable;
1405
1872
  let detectedType;
1406
1873
  let threeD = false;
1407
1874
  let chartTypeEl;
1875
+ const secondaryEls = [];
1408
1876
  for (const child of plotArea.elements) {
1409
1877
  if (!child.name) continue;
1410
1878
  const mapping = TAG_TO_CHART_TYPE[child.name];
1411
1879
  if (mapping) {
1880
+ if (chartTypeEl) {
1881
+ secondaryEls.push(child);
1882
+ continue;
1883
+ }
1412
1884
  detectedType = mapping.type;
1413
1885
  threeD = mapping.threeD ?? false;
1414
1886
  chartTypeEl = child;
@@ -1418,69 +1890,132 @@ const chartSpaceDesc = {
1418
1890
  if (barDirVal === "bar") detectedType = "bar";
1419
1891
  else if (barDirVal === "col") detectedType = "column";
1420
1892
  }
1421
- break;
1422
1893
  }
1423
1894
  }
1424
- if (detectedType) {
1895
+ if (detectedType && chartTypeEl) {
1425
1896
  result.type = detectedType;
1426
1897
  if (threeD) result.threeD = true;
1427
- readChartTypeScalars(chartTypeEl, detectedType, threeD, result);
1428
- readChartTypeDecorations(chartTypeEl, detectedType, threeD, result);
1898
+ readChartTypeScalars(chartTypeEl, detectedType, threeD, result, ctx);
1899
+ readChartTypeDecorations(chartTypeEl, detectedType, threeD, result, ctx);
1900
+ const groupLabels = readDataLabels(chartTypeEl, ctx);
1901
+ if (groupLabels) result.dataLabels = groupLabels;
1902
+ const axIdEls = children(chartTypeEl, "c:axId");
1903
+ if (axIdEls.length > 0) result.axisIds = axIdEls.map((e) => Number(attr(e, "val"))).filter((n) => !isNaN(n));
1429
1904
  }
1430
1905
  const seriesEls = chartTypeEl ? children(chartTypeEl, "c:ser") : [];
1431
- if (seriesEls.length > 0) if (detectedType === "bubble") {
1432
- const bubbleSeries = [];
1433
- for (const serEl of seriesEls) {
1434
- const name = readSeriesName(serEl);
1435
- const xVal = findChild(serEl, "c:xVal");
1436
- const yVal = findChild(serEl, "c:yVal");
1437
- const bubbleSize = findChild(serEl, "c:bubbleSize");
1438
- bubbleSeries.push({
1439
- name,
1440
- xValues: xVal ? readNumCache(xVal) : [],
1441
- yValues: yVal ? readNumCache(yVal) : [],
1442
- bubbleSize: bubbleSize ? readNumCache(bubbleSize) : [],
1443
- ...readSeriesCommon(serEl)
1444
- });
1445
- }
1446
- result.series = bubbleSeries;
1447
- } else {
1448
- const chartSeries = [];
1449
- let categories;
1450
- for (const serEl of seriesEls) {
1451
- const name = readSeriesName(serEl);
1452
- if (!categories && !result.multiLevelCategories && !result.categoryLabels) {
1453
- const catEl = findChild(serEl, "c:cat") ?? findChild(serEl, "c:xVal");
1454
- if (catEl) {
1455
- const multi = readMultiLvlStrCache(catEl);
1456
- if (multi) result.multiLevelCategories = multi;
1457
- else {
1458
- const lit = readStrLit(catEl);
1459
- if (lit) {
1460
- result.categoryLabels = lit;
1461
- categories = lit;
1462
- } else categories = readStrCache(catEl);
1906
+ if (seriesEls.length > 0) {
1907
+ if (detectedType === "bubble") {
1908
+ const bubbleSeries = [];
1909
+ for (const serEl of seriesEls) {
1910
+ const { name } = readSeriesName(serEl);
1911
+ const xVal = findChild(serEl, "c:xVal");
1912
+ const yVal = findChild(serEl, "c:yVal");
1913
+ const bubbleSize = findChild(serEl, "c:bubbleSize");
1914
+ bubbleSeries.push({
1915
+ name,
1916
+ xValues: xVal ? readNumCache(xVal) : [],
1917
+ yValues: yVal ? readNumCache(yVal) : [],
1918
+ bubbleSize: bubbleSize ? readNumCache(bubbleSize) : [],
1919
+ ...readSeriesCommon(serEl, ctx)
1920
+ });
1921
+ }
1922
+ result.series = bubbleSeries;
1923
+ } else if (detectedType === "scatter" && hasNumericXRef(seriesEls[0])) {
1924
+ const xySeries = [];
1925
+ for (const serEl of seriesEls) {
1926
+ const { name, literal: nameLiteral } = readSeriesName(serEl);
1927
+ const txEl = findChild(serEl, "c:tx");
1928
+ const nameFormula = txEl ? readRefMeta(txEl).formula : void 0;
1929
+ const xVal = findChild(serEl, "c:xVal");
1930
+ const yVal = findChild(serEl, "c:yVal");
1931
+ const valueLiteral = yVal ? findChild(yVal, "c:numLit") !== void 0 : false;
1932
+ const yMeta = yVal ? readRefMeta(yVal) : {};
1933
+ xySeries.push({
1934
+ name,
1935
+ ...nameLiteral ? { nameLiteral } : {},
1936
+ ...nameFormula ? { nameFormula } : {},
1937
+ ...valueLiteral ? { valueLiteral } : {},
1938
+ ...yMeta.formula ? { valueFormula: yMeta.formula } : {},
1939
+ ...yMeta.formatCode ? { formatCode: yMeta.formatCode } : {},
1940
+ xValues: xVal ? readNumCache(xVal) : [],
1941
+ yValues: yVal ? readNumCache(yVal) : [],
1942
+ ...readSeriesCommon(serEl, ctx)
1943
+ });
1944
+ }
1945
+ result.series = xySeries;
1946
+ } else {
1947
+ const chartSeries = [];
1948
+ let categories;
1949
+ for (const serEl of seriesEls) {
1950
+ const { name, literal: nameLiteral } = readSeriesName(serEl);
1951
+ const txEl = findChild(serEl, "c:tx");
1952
+ const nameFormula = txEl ? readRefMeta(txEl).formula : void 0;
1953
+ if (!categories && !result.multiLevelCategories && !result.categoryLabels) {
1954
+ const catEl = findChild(serEl, "c:cat") ?? findChild(serEl, "c:xVal");
1955
+ if (catEl) {
1956
+ const multi = readMultiLvlStrCache(catEl);
1957
+ if (multi) {
1958
+ result.multiLevelCategories = multi;
1959
+ const multiRef = findChild(catEl, "c:multiLvlStrRef");
1960
+ const multiF = multiRef ? findChild(multiRef, "c:f") : void 0;
1961
+ const multiText = multiF ? textOf(multiF) : "";
1962
+ if (multiText) result.categoryFormula = multiText;
1963
+ } else {
1964
+ const lit = readStrLit(catEl);
1965
+ if (lit) {
1966
+ result.categoryLabels = lit;
1967
+ categories = lit;
1968
+ } else if (findChild(catEl, "c:numRef")) {
1969
+ result.numericCategories = true;
1970
+ categories = readNumCacheText(catEl);
1971
+ } else categories = readStrCache(catEl);
1972
+ const catMeta = readRefMeta(catEl);
1973
+ if (catMeta.formula) result.categoryFormula = catMeta.formula;
1974
+ if (catMeta.formatCode) result.categoryFormatCode = catMeta.formatCode;
1975
+ }
1463
1976
  }
1464
1977
  }
1978
+ const valueEl = findChild(serEl, "c:val") ?? findChild(serEl, "c:yVal");
1979
+ const valueLiteral = valueEl ? findChild(valueEl, "c:numLit") !== void 0 : false;
1980
+ const values = valueEl ? readNumCache(valueEl) : [];
1981
+ const valMeta = valueEl ? readRefMeta(valueEl) : {};
1982
+ chartSeries.push({
1983
+ name,
1984
+ ...nameLiteral ? { nameLiteral } : {},
1985
+ ...nameFormula ? { nameFormula } : {},
1986
+ ...valueLiteral ? { valueLiteral } : {},
1987
+ ...valMeta.formula ? { valueFormula: valMeta.formula } : {},
1988
+ ...valMeta.formatCode ? { formatCode: valMeta.formatCode } : {},
1989
+ values,
1990
+ ...readSeriesCommon(serEl, ctx)
1991
+ });
1465
1992
  }
1466
- const valEl = findChild(serEl, "c:val") ?? findChild(serEl, "c:yVal");
1467
- const values = valEl ? readNumCache(valEl) : [];
1468
- chartSeries.push({
1469
- name,
1470
- values,
1471
- ...readSeriesCommon(serEl)
1472
- });
1993
+ result.series = chartSeries;
1994
+ if (categories) result.categories = categories;
1473
1995
  }
1474
- result.series = chartSeries;
1475
- if (categories?.length) result.categories = categories;
1996
+ }
1997
+ if (secondaryEls.length > 0) {
1998
+ const groups = [];
1999
+ for (const secondaryEl of secondaryEls) {
2000
+ const g = readSecondaryGroup(secondaryEl, ctx);
2001
+ if (g) groups.push(g);
2002
+ }
2003
+ if (groups.length > 0) result.secondaryGroups = groups;
1476
2004
  }
1477
2005
  }
1478
- const axes = readAxes(plotArea);
2006
+ const axes = readAxes(plotArea, ctx);
1479
2007
  if (axes) result.axes = axes;
2008
+ const plotSpPr = plotArea && findChild(plotArea, "c:spPr");
2009
+ if (plotSpPr) result.plotAreaShapeProperties = shapePropertiesDesc.parse(plotSpPr, ctx);
1480
2010
  if (!findChild(chart, "c:legend")) result.showLegend = false;
1481
2011
  else {
1482
- const legendData = readLegend(chart);
2012
+ result.showLegend = true;
2013
+ const legendData = readLegend(chart, ctx);
1483
2014
  if (legendData?.position) result.legendPosition = legendData.position;
2015
+ if (legendData?.layout !== void 0) result.legendLayout = legendData.layout;
2016
+ if (legendData?.overlay !== void 0) result.legendOverlay = legendData.overlay;
2017
+ if (legendData?.shapeProperties) result.legendShapeProperties = legendData.shapeProperties;
2018
+ if (legendData?.textProperties) result.legendTextProperties = legendData.textProperties;
1484
2019
  if (legendData?.entries) result.legendEntries = legendData.entries;
1485
2020
  }
1486
2021
  const plotVisOnly = readBoolAttr(chart, "c:plotVisOnly");
@@ -1489,6 +2024,10 @@ const chartSpaceDesc = {
1489
2024
  if (dispBlanksAs) result.displayBlanksAs = dispBlanksAs;
1490
2025
  const showDLblsOverMax = readBoolAttr(chart, "c:showDLblsOverMax");
1491
2026
  if (showDLblsOverMax !== void 0) result.showDataLabelsOverMax = showDLblsOverMax;
2027
+ const spPrEl = findChild(el, "c:spPr");
2028
+ if (spPrEl) result.shapeProperties = shapePropertiesDesc.parse(spPrEl, ctx);
2029
+ const spaceTxPr = findChild(el, "c:txPr");
2030
+ if (spaceTxPr) result.textProperties = textBodyDesc.parse(spaceTxPr, ctx);
1492
2031
  const externalData = readExternalData(el);
1493
2032
  if (externalData) result.externalData = externalData;
1494
2033
  const printSettings = readPrintSettings(el);
@@ -1498,6 +2037,8 @@ const chartSpaceDesc = {
1498
2037
  const rid = attr(userShapesEl, "r:id");
1499
2038
  if (rid !== void 0) result.userShapes = rid;
1500
2039
  }
2040
+ const spaceExtLst = findChild(el, "c:extLst");
2041
+ if (spaceExtLst) result.ext = (spaceExtLst.elements ?? []).map((e) => stringifyElement(e)).join("");
1501
2042
  return result;
1502
2043
  }
1503
2044
  };
@@ -1560,10 +2101,11 @@ function stringifyObject(obj) {
1560
2101
  }
1561
2102
  case "picture": {
1562
2103
  const nvPicPr = `<cdr:nvPicPr>${stringifyCnvPr(obj.id, obj.nonVisualProperties)}<cdr:cNvPicPr/></cdr:nvPicPr>`;
1563
- const blipFillXml = (stringify$1(blipFillDesc, {
2104
+ const fillOpts = {
1564
2105
  ...obj.blipFill,
1565
2106
  referenceId: obj.referenceId
1566
- }, DIRECT_CTX) ?? "").replace(/pic:blipFill/g, "cdr:blipFill");
2107
+ };
2108
+ const blipFillXml = (stringify$1(blipFillDesc, fillOpts, DIRECT_CTX) ?? "").replace(/pic:blipFill/g, "cdr:blipFill");
1567
2109
  const spPrXml = stringify$1(shapePropertiesDesc, obj.shapeProperties, DIRECT_CTX) ?? "";
1568
2110
  const styleXml = obj.style ? stringifyShapeStyle(obj.style, DIRECT_CTX) : "";
1569
2111
  return `<cdr:pic${commonAttrs(obj)}>` + nvPicPr + blipFillXml + `<cdr:spPr>${spPrXml}</cdr:spPr>` + styleXml + "</cdr:pic>";
@@ -1605,6 +2147,13 @@ function readCnvPr(el) {
1605
2147
  nvp
1606
2148
  };
1607
2149
  }
2150
+ /** macro/fPublished attributes shared by every non-group user-shape object. */
2151
+ function readCommonAttrs(el) {
2152
+ const out = {};
2153
+ if (el.attributes?.["macro"] !== void 0) out.macro = String(el.attributes["macro"]);
2154
+ if (el.attributes?.["fPublished"] !== void 0) out.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2155
+ return out;
2156
+ }
1608
2157
  function readObject(el, ctx) {
1609
2158
  switch (el.name) {
1610
2159
  case "cdr:sp": {
@@ -1625,10 +2174,9 @@ function readObject(el, ctx) {
1625
2174
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
1626
2175
  const txBody = findChild(el, "cdr:txBody");
1627
2176
  if (txBody) result.textBody = parse$1(textBodyDesc, txBody, ctx);
1628
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
2177
+ Object.assign(result, readCommonAttrs(el));
1629
2178
  if (el.attributes?.["textlink"] !== void 0) result.textLink = String(el.attributes["textlink"]);
1630
2179
  if (el.attributes?.["fLocksText"] !== void 0) result.locksText = parseOnOff(el.attributes["fLocksText"]) ?? true;
1631
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
1632
2180
  return result;
1633
2181
  }
1634
2182
  case "cdr:cxnSp": {
@@ -1645,8 +2193,7 @@ function readObject(el, ctx) {
1645
2193
  };
1646
2194
  const styleEl = findChild(el, "a:style");
1647
2195
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
1648
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
1649
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2196
+ Object.assign(result, readCommonAttrs(el));
1650
2197
  return result;
1651
2198
  }
1652
2199
  case "cdr:pic": {
@@ -1667,8 +2214,7 @@ function readObject(el, ctx) {
1667
2214
  if (Object.keys(blipFillOpts).length > 0) result.blipFill = blipFillOpts;
1668
2215
  const styleEl = findChild(el, "a:style");
1669
2216
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
1670
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
1671
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2217
+ Object.assign(result, readCommonAttrs(el));
1672
2218
  return result;
1673
2219
  }
1674
2220
  case "cdr:graphicFrame": {
@@ -1704,8 +2250,7 @@ function readObject(el, ctx) {
1704
2250
  if (Object.keys(flags).length > 0) result.graphicFrameLocks = flags;
1705
2251
  } else result.graphicFrameLocks = {};
1706
2252
  }
1707
- if (el.attributes?.["macro"] !== void 0) result.macro = String(el.attributes["macro"]);
1708
- if (el.attributes?.["fPublished"] !== void 0) result.published = parseOnOff(el.attributes["fPublished"]) ?? false;
2253
+ Object.assign(result, readCommonAttrs(el));
1709
2254
  return result;
1710
2255
  }
1711
2256
  case "cdr:grpSp": {
@@ -1777,4 +2322,4 @@ function readAnchorObject(anchorEl, ctx) {
1777
2322
  //#endregion
1778
2323
  export { chartSpaceDesc as n, ChartCollection as r, userShapesDesc as t };
1779
2324
 
1780
- //# sourceMappingURL=chart-Kf_utasF.mjs.map
2325
+ //# sourceMappingURL=chart-DED4tXC9.mjs.map