@extend-ai/react-xlsx 0.20.2 → 0.20.4

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 (103) hide show
  1. package/dist/browser-IQ4UDS5M.js +209 -0
  2. package/dist/browser-IQ4UDS5M.js.map +1 -0
  3. package/dist/browser-S6E2BS5S.cjs +212 -0
  4. package/dist/browser-S6E2BS5S.cjs.map +1 -0
  5. package/dist/{chart-renderer-F355CYSE.js → chart-renderer-4HTNG3SX.js} +94 -180
  6. package/dist/chart-renderer-4HTNG3SX.js.map +1 -0
  7. package/dist/{chart-renderer-7DTEXXG6.js → chart-renderer-5IN2B3YS.js} +94 -180
  8. package/dist/chart-renderer-5IN2B3YS.js.map +1 -0
  9. package/dist/{chart-renderer-LGW4EH4M.cjs → chart-renderer-6CWSXOSC.cjs} +324 -410
  10. package/dist/chart-renderer-6CWSXOSC.cjs.map +1 -0
  11. package/dist/{chart-renderer-3QDNTMRN.cjs → chart-renderer-H4BLRO5P.cjs} +324 -410
  12. package/dist/chart-renderer-H4BLRO5P.cjs.map +1 -0
  13. package/dist/chunk-GX5LAENE.cjs +108 -0
  14. package/dist/chunk-GX5LAENE.cjs.map +1 -0
  15. package/dist/{chunk-GXYDJPHM.js → chunk-H62SZBEY.js} +401 -132
  16. package/dist/chunk-H62SZBEY.js.map +1 -0
  17. package/dist/{chunk-3LMOGW6A.js → chunk-IISMO3AX.js} +30 -15
  18. package/dist/chunk-IISMO3AX.js.map +1 -0
  19. package/dist/{chunk-ZJ76CZAL.cjs → chunk-KQSUAIZD.cjs} +1168 -899
  20. package/dist/chunk-KQSUAIZD.cjs.map +1 -0
  21. package/dist/{chunk-IYGZTLDY.js → chunk-LZXL5E4W.js} +16 -7
  22. package/dist/chunk-LZXL5E4W.js.map +1 -0
  23. package/dist/chunk-MYN475JP.cjs +32 -0
  24. package/dist/chunk-MYN475JP.cjs.map +1 -0
  25. package/dist/{chunk-D2UA4P6N.cjs → chunk-NAYVSTCX.cjs} +22 -9
  26. package/dist/chunk-NAYVSTCX.cjs.map +1 -0
  27. package/dist/chunk-PK3MCNDK.js +32 -0
  28. package/dist/chunk-PK3MCNDK.js.map +1 -0
  29. package/dist/full-3FSPB3R6.cjs +212 -0
  30. package/dist/full-3FSPB3R6.cjs.map +1 -0
  31. package/dist/full-GPY27HZY.js +209 -0
  32. package/dist/full-GPY27HZY.js.map +1 -0
  33. package/dist/index.cjs +834 -602
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +57 -1
  36. package/dist/index.d.ts +57 -1
  37. package/dist/index.js +347 -115
  38. package/dist/index.js.map +1 -1
  39. package/dist/{internal-BJsg5os3.d.cts → internal-Cks9H21d.d.cts} +56 -1
  40. package/dist/{internal-BJsg5os3.d.ts → internal-Cks9H21d.d.ts} +56 -1
  41. package/dist/internal.cjs +3 -3
  42. package/dist/internal.d.cts +1 -1
  43. package/dist/internal.d.ts +1 -1
  44. package/dist/internal.js +2 -2
  45. package/dist/office_charts_bg.wasm +0 -0
  46. package/dist/office_charts_full_bg.wasm +0 -0
  47. package/dist/payload-B55ZKNYO.js +6 -0
  48. package/dist/payload-B55ZKNYO.js.map +1 -0
  49. package/dist/payload-E2KM77DZ.js +6 -0
  50. package/dist/payload-E2KM77DZ.js.map +1 -0
  51. package/dist/payload-K4S5RLJN.cjs +8 -0
  52. package/dist/payload-K4S5RLJN.cjs.map +1 -0
  53. package/dist/payload-PL4646XV.cjs +8 -0
  54. package/dist/payload-PL4646XV.cjs.map +1 -0
  55. package/dist/rust-office-charts-LICENSE.txt +21 -0
  56. package/dist/{shared-chart-3STFRVWT.js → shared-chart-5KTGZEZ5.js} +38 -20
  57. package/dist/shared-chart-5KTGZEZ5.js.map +1 -0
  58. package/dist/{shared-chart-DVC5S2P6.cjs → shared-chart-ACR4M7BP.cjs} +37 -20
  59. package/dist/shared-chart-ACR4M7BP.cjs.map +1 -0
  60. package/dist/{shared-chart-BFQNYOIQ.js → shared-chart-EGN5JTKT.js} +37 -20
  61. package/dist/shared-chart-EGN5JTKT.js.map +1 -0
  62. package/dist/{shared-chart-MFQSQG4K.cjs → shared-chart-XAV7VA45.cjs} +37 -19
  63. package/dist/shared-chart-XAV7VA45.cjs.map +1 -0
  64. package/dist/{surface-regl-R2N54JT2.js → surface-webgl-2ZZ6JQR2.js} +87 -151
  65. package/dist/surface-webgl-2ZZ6JQR2.js.map +1 -0
  66. package/dist/{surface-regl-BBJ6OIKK.cjs → surface-webgl-3HS6VBCK.cjs} +88 -152
  67. package/dist/surface-webgl-3HS6VBCK.cjs.map +1 -0
  68. package/dist/{surface-regl-7CDGGVDG.js → surface-webgl-4DQXDDXU.js} +87 -151
  69. package/dist/surface-webgl-4DQXDDXU.js.map +1 -0
  70. package/dist/{surface-regl-SUJ2TFZA.cjs → surface-webgl-SVYD564V.cjs} +88 -152
  71. package/dist/surface-webgl-SVYD564V.cjs.map +1 -0
  72. package/dist/vanilla.cjs +3 -3
  73. package/dist/vanilla.d.cts +2 -2
  74. package/dist/vanilla.d.ts +2 -2
  75. package/dist/vanilla.js +2 -2
  76. package/dist/xlsx-worker.js +298 -92
  77. package/dist/xlsx-worker.js.map +1 -1
  78. package/package.json +7 -15
  79. package/dist/chart-renderer-3QDNTMRN.cjs.map +0 -1
  80. package/dist/chart-renderer-7DTEXXG6.js.map +0 -1
  81. package/dist/chart-renderer-F355CYSE.js.map +0 -1
  82. package/dist/chart-renderer-LGW4EH4M.cjs.map +0 -1
  83. package/dist/chunk-3LMOGW6A.js.map +0 -1
  84. package/dist/chunk-D2UA4P6N.cjs.map +0 -1
  85. package/dist/chunk-GXYDJPHM.js.map +0 -1
  86. package/dist/chunk-IYGZTLDY.js.map +0 -1
  87. package/dist/chunk-OCF75R75.cjs +0 -90
  88. package/dist/chunk-OCF75R75.cjs.map +0 -1
  89. package/dist/chunk-ZJ76CZAL.cjs.map +0 -1
  90. package/dist/region-map-geography-24TXETDP.cjs +0 -184
  91. package/dist/region-map-geography-24TXETDP.cjs.map +0 -1
  92. package/dist/region-map-geography-OR6DHAF7.js +0 -182
  93. package/dist/region-map-geography-OR6DHAF7.js.map +0 -1
  94. package/dist/shared-chart-3STFRVWT.js.map +0 -1
  95. package/dist/shared-chart-BFQNYOIQ.js.map +0 -1
  96. package/dist/shared-chart-DVC5S2P6.cjs.map +0 -1
  97. package/dist/shared-chart-MFQSQG4K.cjs.map +0 -1
  98. package/dist/surface-regl-7CDGGVDG.js.map +0 -1
  99. package/dist/surface-regl-BBJ6OIKK.cjs.map +0 -1
  100. package/dist/surface-regl-R2N54JT2.js.map +0 -1
  101. package/dist/surface-regl-SUJ2TFZA.cjs.map +0 -1
  102. package/dist/world-atlas-LICENSE.txt +0 -13
  103. /package/dist/{us-atlas-LICENSE.txt → rust-office-charts-MAP-DATA-LICENSE.txt} +0 -0
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import "./chunk-IYGZTLDY.js";
1
+ import "./chunk-LZXL5E4W.js";
2
2
  import {
3
3
  getBuiltinChartColor,
4
4
  getBuiltinChartSurfaceStyle,
@@ -89,10 +89,81 @@ function loadSpreadsheetFonts() {
89
89
  import * as React from "react";
90
90
  import { formatBinaryBytes, XlsxFileSizeLimitExceededError } from "@extend-ai/react-xlsx/internal";
91
91
  import { XlsxFileSizeLimitExceededError as XlsxFileSizeLimitExceededError2 } from "@extend-ai/react-xlsx/internal";
92
- import { strFromU8 as strFromU83, strToU8 as strToU83, unzipSync as unzipSync2, zipSync as zipSync2 } from "fflate";
92
+ import { strFromU8 as strFromU84, strToU8 as strToU83, unzipSync as unzipSync2, zipSync as zipSync2 } from "fflate";
93
+
94
+ // src/chartsheet-payload.ts
95
+ import { strFromU8 } from "fflate";
96
+ var REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
97
+ function readXml(archive, path) {
98
+ const bytes = archive[path];
99
+ if (!bytes || typeof DOMParser === "undefined") return null;
100
+ const document2 = new DOMParser().parseFromString(strFromU8(bytes), "application/xml");
101
+ return document2.getElementsByTagName("parsererror").length > 0 ? null : document2;
102
+ }
103
+ function relationshipPath(partPath) {
104
+ const separator = partPath.lastIndexOf("/");
105
+ return `${partPath.slice(0, separator + 1)}_rels/${partPath.slice(separator + 1)}.rels`;
106
+ }
107
+ function resolveTarget(partPath, target) {
108
+ if (/^[a-z][a-z0-9+.-]*:/i.test(target) || target.startsWith("//")) return null;
109
+ const segments = target.startsWith("/") ? [] : partPath.split("/").slice(0, -1);
110
+ for (const segment of target.replace(/\\/g, "/").split("/")) {
111
+ if (!segment || segment === ".") continue;
112
+ if (segment === "..") {
113
+ if (segments.length === 0) return null;
114
+ segments.pop();
115
+ } else {
116
+ segments.push(segment);
117
+ }
118
+ }
119
+ return segments.join("/");
120
+ }
121
+ function readRelationships(archive, partPath) {
122
+ const relationships = /* @__PURE__ */ new Map();
123
+ const document2 = readXml(archive, relationshipPath(partPath));
124
+ for (const element of Array.from(document2?.getElementsByTagNameNS("*", "Relationship") ?? [])) {
125
+ if (element.getAttribute("TargetMode") === "External") continue;
126
+ const id = element.getAttribute("Id");
127
+ const rawTarget = element.getAttribute("Target");
128
+ const type = element.getAttribute("Type");
129
+ const target = rawTarget ? resolveTarget(partPath, rawTarget) : null;
130
+ if (id && type && target && archive[target]) relationships.set(id, { target, type });
131
+ }
132
+ return relationships;
133
+ }
134
+ function collectChartsheetDrawingOrigins(archive, chartsheets) {
135
+ const origins = /* @__PURE__ */ new Map();
136
+ if (chartsheets.length === 0) return origins;
137
+ const workbookPath = "xl/workbook.xml";
138
+ const workbookDocument = readXml(archive, workbookPath);
139
+ const workbookRelationships = readRelationships(archive, workbookPath);
140
+ for (const sheet of Array.from(workbookDocument?.getElementsByTagNameNS("*", "sheet") ?? [])) {
141
+ const relationshipId = sheet.getAttributeNS(REL_NS, "id") ?? sheet.getAttribute("r:id");
142
+ const relationship = relationshipId ? workbookRelationships.get(relationshipId) : null;
143
+ if (!relationship?.type.endsWith("/chartsheet")) continue;
144
+ const chartsheet = chartsheets.find((entry) => entry.name === sheet.getAttribute("name"));
145
+ if (!chartsheet || chartsheet.workbookSheetIndex == null) continue;
146
+ const sheetDocument = readXml(archive, relationship.target);
147
+ const sheetRelationships = readRelationships(archive, relationship.target);
148
+ const attachments = [];
149
+ for (const drawing of Array.from(sheetDocument?.getElementsByTagNameNS("*", "drawing") ?? [])) {
150
+ const drawingId = drawing.getAttributeNS(REL_NS, "id") ?? drawing.getAttribute("r:id");
151
+ const drawingRelationship = drawingId ? sheetRelationships.get(drawingId) : null;
152
+ if (!drawingRelationship?.type.endsWith("/drawing")) continue;
153
+ const drawingRelsPath = relationshipPath(drawingRelationship.target);
154
+ attachments.push({
155
+ drawingPath: drawingRelationship.target,
156
+ drawingRelsPath: archive[drawingRelsPath] ? drawingRelsPath : null,
157
+ mediaPaths: []
158
+ });
159
+ }
160
+ origins.set(chartsheet.index, { attachments, workbookSheetIndex: chartsheet.workbookSheetIndex });
161
+ }
162
+ return origins;
163
+ }
93
164
 
94
165
  // src/charts.ts
95
- import { strFromU8, strToU8 } from "fflate";
166
+ import { strFromU8 as strFromU82, strToU8 } from "fflate";
96
167
  var CHART_NS = "http://schemas.openxmlformats.org/drawingml/2006/chart";
97
168
  var DRAWINGML_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
98
169
  var CHART_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
@@ -241,18 +312,33 @@ function applyChartSeriesFormula(chart, seriesIndex, formula, workbook) {
241
312
  }
242
313
  const categoriesRef = {
243
314
  ...currentSeries.categoriesRef ?? {},
244
- formula: parsed.categoryFormula
315
+ formula: parsed.categoryFormula,
316
+ values: parsed.categoryFormula === currentSeries.categoriesRef?.formula ? currentSeries.categoriesRef.values : void 0
245
317
  };
246
318
  const valuesRef = {
247
319
  ...currentSeries.valuesRef ?? {},
248
- formula: parsed.valueFormula
320
+ formula: parsed.valueFormula,
321
+ values: parsed.valueFormula === currentSeries.valuesRef?.formula ? currentSeries.valuesRef.values : void 0
249
322
  };
250
323
  const bubbleSizeRef = chart.chartType === "Bubble" || parsed.bubbleSizeFormula ? {
251
324
  ...currentSeries.bubbleSizeRef ?? {},
252
- formula: parsed.bubbleSizeFormula
325
+ formula: parsed.bubbleSizeFormula,
326
+ values: parsed.bubbleSizeFormula === currentSeries.bubbleSizeRef?.formula ? currentSeries.bubbleSizeRef?.values : void 0
253
327
  } : currentSeries.bubbleSizeRef ?? null;
328
+ const isUnresolved = (formula2) => Boolean(
329
+ workbook && formula2 && !resolveReferenceSheet(workbook, chart.workbookSheetIndex, formula2).sheet
330
+ );
331
+ const resolveEditedReference = (reference, currentReference, currentValues, mode) => {
332
+ if (!workbook) return currentValues;
333
+ if (reference?.formula === currentReference?.formula && isUnresolved(reference?.formula)) return currentValues;
334
+ return resolveReferenceValues(workbook, chart.workbookSheetIndex, reference, mode);
335
+ };
254
336
  const raw = {
255
- ...currentSeries.raw ?? {}
337
+ ...currentSeries.raw ?? {},
338
+ unresolvedCategoriesReference: isUnresolved(categoriesRef.formula),
339
+ unresolvedValuesReference: isUnresolved(valuesRef.formula),
340
+ unresolvedBubbleSizeReference: isUnresolved(bubbleSizeRef?.formula),
341
+ unresolvedNameReference: isUnresolved(parsed.nameFormula)
256
342
  };
257
343
  if (parsed.nameFormula) {
258
344
  raw.name = parsed.nameFormula;
@@ -262,17 +348,21 @@ function applyChartSeriesFormula(chart, seriesIndex, formula, workbook) {
262
348
  const nextSeries = {
263
349
  ...currentSeries,
264
350
  bubbleSizeRef,
265
- bubbleSizes: workbook && bubbleSizeRef?.formula ? resolveReferenceValues(workbook, chart.workbookSheetIndex, bubbleSizeRef, "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null) : currentSeries.bubbleSizes,
266
- categories: workbook ? resolveReferenceValues(workbook, chart.workbookSheetIndex, categoriesRef, "category") : currentSeries.categories,
351
+ bubbleSizes: resolveEditedReference(bubbleSizeRef, currentSeries.bubbleSizeRef, currentSeries.bubbleSizes ?? [], "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null),
352
+ categories: resolveEditedReference(categoriesRef, currentSeries.categoriesRef, currentSeries.categories, "category"),
267
353
  categoriesRef,
268
- name: parsed.nameLiteral ?? (parsed.nameFormula && workbook ? resolveSeriesName(workbook, chart.workbookSheetIndex, parsed.nameFormula) : parsed.nameFormula ?? currentSeries.name),
354
+ name: parsed.nameLiteral ?? (parsed.nameFormula === currentSeries.raw?.name && isUnresolved(parsed.nameFormula) ? currentSeries.name : parsed.nameFormula && workbook ? resolveSeriesName(workbook, chart.workbookSheetIndex, parsed.nameFormula) : parsed.nameFormula ?? currentSeries.name),
269
355
  raw,
270
- values: workbook ? resolveReferenceValues(workbook, chart.workbookSheetIndex, valuesRef, "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null) : currentSeries.values,
356
+ values: resolveEditedReference(valuesRef, currentSeries.valuesRef, currentSeries.values, "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null),
271
357
  valuesRef
272
358
  };
273
359
  return {
274
360
  ...chart,
275
- series: chart.series.map((series, index) => index === seriesIndex ? nextSeries : series)
361
+ series: chart.series.map((series, index) => index === seriesIndex ? nextSeries : series),
362
+ typeGroups: chart.typeGroups?.map((group) => ({
363
+ ...group,
364
+ series: group.series.map((series) => series.id === currentSeries.id ? nextSeries : series)
365
+ }))
276
366
  };
277
367
  }
278
368
  function normalizeWorksheetVisibility(value) {
@@ -978,9 +1068,10 @@ function applyBuiltinChartDefaults(chart, themePalette) {
978
1068
  };
979
1069
  };
980
1070
  chart.series = chart.series.map(applySeriesDefaults);
1071
+ const canonicalSeries = chart.id.startsWith("chart-ex-") ? null : new Map(chart.series.map((series) => [series.id, series]));
981
1072
  let groupSeriesOffset = 0;
982
1073
  chart.typeGroups = chart.typeGroups?.map((group) => {
983
- const series = group.series.map((entry, index) => applySeriesDefaults(entry, groupSeriesOffset + index));
1074
+ const series = group.series.map((entry, index) => canonicalSeries?.get(entry.id) ?? applySeriesDefaults(entry, groupSeriesOffset + index));
984
1075
  groupSeriesOffset += group.series.length;
985
1076
  return { ...group, series };
986
1077
  });
@@ -1124,11 +1215,12 @@ function applyChartSeriesStyleFromXml(chart, chartTypeNode, themePalette) {
1124
1215
  const rawFillColor = typeof existingShapeProperties?.solidFillHex === "string" ? normalizeHexColor(existingShapeProperties.solidFillHex) : null;
1125
1216
  const rawLineColor = typeof existingShapeProperties?.lineColorHex === "string" ? normalizeHexColor(existingShapeProperties.lineColorHex) : null;
1126
1217
  const resolvedLineColor = lineStyle.hidden ? void 0 : rawLineColor ?? lineStyle.color ?? rawFillColor ?? fillColor ?? series.lineColor ?? series.color;
1127
- const hasCategoryReference = typeof series.categoriesRef?.formula === "string" && series.categoriesRef.formula.length > 0;
1128
- const hasValueReference = typeof series.valuesRef?.formula === "string" && series.valuesRef.formula.length > 0;
1129
- const hasBubbleSizeReference = typeof series.bubbleSizeRef?.formula === "string" && series.bubbleSizeRef.formula.length > 0;
1218
+ const hasCategoryReference = typeof series.categoriesRef?.formula === "string" && series.categoriesRef.formula.length > 0 && !series.raw?.unresolvedCategoriesReference;
1219
+ const hasValueReference = typeof series.valuesRef?.formula === "string" && series.valuesRef.formula.length > 0 && !series.raw?.unresolvedValuesReference;
1220
+ const hasBubbleSizeReference = typeof series.bubbleSizeRef?.formula === "string" && series.bubbleSizeRef.formula.length > 0 && !series.raw?.unresolvedBubbleSizeReference;
1130
1221
  return {
1131
1222
  ...series,
1223
+ name: series.raw?.unresolvedNameReference ? parseChartCacheValues(getFirstLocalChild(seriesNode, "tx"), "strCache", "category")?.[0]?.toString() ?? series.name : series.name,
1132
1224
  bubbleSizes: !hasBubbleSizeReference && cachedBubbleSizes ? cachedBubbleSizes.map((value) => typeof value === "number" && Number.isFinite(value) ? value : null) : series.bubbleSizes,
1133
1225
  categories: !hasCategoryReference && cachedCategories ? cachedCategories : series.categories,
1134
1226
  color: rawFillColor ?? rawLineColor ?? fillColor ?? lineStyle.color ?? series.color,
@@ -1388,6 +1480,23 @@ function applyChartStyleFromXml(chart, chartPath, archive, themePalette) {
1388
1480
  if (typeof fallbackStyleId === "number" && Number.isFinite(fallbackStyleId)) {
1389
1481
  chart.chartStyleId = fallbackStyleId;
1390
1482
  }
1483
+ const sourceSeries = chart.raw?.officeSourceSeries;
1484
+ if (sourceSeries && chartDocument?.documentElement.namespaceURI === "http://schemas.microsoft.com/office/drawing/2014/chartex") {
1485
+ chart.renderSource = {
1486
+ kind: chart.chartExLayout ?? "",
1487
+ seriesTypes: getLocalDescendants(chartNode, "series").map((node) => node.getAttribute("layoutId") ?? ""),
1488
+ sourceSeries,
1489
+ experimental: true,
1490
+ xml: chartXml,
1491
+ themeColors: themePalette ? Object.fromEntries(Object.entries(THEME_COLOR_INDEX_BY_NAME).flatMap(([key, index]) => {
1492
+ const color = themePalette.colorsByIndex[index];
1493
+ return color ? [[key, color]] : [];
1494
+ })) : void 0,
1495
+ themeOverrideXml: readArchiveText(archive, relationships.get("http://schemas.openxmlformats.org/officeDocument/2006/relationships/themeOverride")) ?? void 0,
1496
+ styleXml: readArchiveText(archive, relationships.get(CHART_STYLE_REL_TYPE)) ?? void 0,
1497
+ colorStyleXml: readArchiveText(archive, relationships.get(CHART_COLOR_STYLE_REL_TYPE)) ?? void 0
1498
+ };
1499
+ }
1391
1500
  applyModernChartExStyles();
1392
1501
  applyFallbackSeriesStyles();
1393
1502
  applyBuiltinChartDefaults(chart, themePalette);
@@ -1629,11 +1738,22 @@ function applyChartStyleFromXml(chart, chartPath, archive, themePalette) {
1629
1738
  chart.axes = [...chart.axes, seriesAxis];
1630
1739
  }
1631
1740
  }
1632
- const kind = chartTypeNode.localName === "lineChart" && chart.chartType === "Line" ? "line" : chartTypeNode.localName === "barChart" && chart.chartType === "ColumnClustered" ? "bar" : null;
1633
- const groupCount = Array.from(plotArea.children).filter((entry) => entry.localName.endsWith("Chart")).length;
1634
- if (kind && groupCount === 1 && !chart.is3d && !plotArea.querySelector("trendline, errBars, dropLines, hiLowLines, upDownBars, dateAx, multiLvlStrRef, pictureOptions") && getLocalChildren(chartTypeNode, "ser").length === chart.series.length) {
1741
+ const groups = Array.from(plotArea.children).filter((entry) => entry.localName.endsWith("Chart"));
1742
+ const seriesTypes = groups.flatMap((group) => getLocalChildren(group, "ser").map(() => group.localName.slice(0, -5)));
1743
+ const seriesNodes = groups.flatMap((group) => getLocalChildren(group, "ser"));
1744
+ const indexedXSeries = seriesNodes.map((series) => {
1745
+ const x = getFirstLocalChild(series, "xVal");
1746
+ return Boolean(x && (getFirstLocalChild(x, "multiLvlStrRef") || getFirstLocalChild(x, "strRef") || getFirstLocalChild(x, "strLit")));
1747
+ });
1748
+ const unsupportedHierarchy = getLocalDescendants(plotArea, "multiLvlStrRef").some((node) => node.parentElement?.localName !== "xVal");
1749
+ const kind = chartTypeNode.localName.slice(0, -5);
1750
+ const stable = groups.length === 1 && !chart.is3d && (kind === "line" && chart.chartType === "Line" || kind === "bar" && chart.chartType === "ColumnClustered") && !plotArea.querySelector("trendline, errBars, dropLines, hiLowLines, upDownBars, dateAx, multiLvlStrRef, pictureOptions");
1751
+ if (seriesTypes.length === chart.series.length && !unsupportedHierarchy && !plotArea.querySelector("pictureOptions")) {
1635
1752
  chart.renderSource = {
1636
1753
  kind,
1754
+ seriesTypes,
1755
+ indexedXSeries,
1756
+ experimental: !stable,
1637
1757
  xml: chartXml,
1638
1758
  themeColors: themePalette ? Object.fromEntries(Object.entries(THEME_COLOR_INDEX_BY_NAME).flatMap(([key, index]) => {
1639
1759
  const color = themePalette.colorsByIndex[index];
@@ -1644,7 +1764,21 @@ function applyChartStyleFromXml(chart, chartPath, archive, themePalette) {
1644
1764
  colorStyleXml: readArchiveText(archive, relationships.get(CHART_COLOR_STYLE_REL_TYPE)) ?? void 0
1645
1765
  };
1646
1766
  }
1647
- applyChartSeriesStyleFromXml(chart, chartTypeNode, themePalette);
1767
+ if (groups.length > 1 && chart.typeGroups?.length === groups.length) {
1768
+ let seriesOffset = 0;
1769
+ const hydratedSeries = [];
1770
+ chart.typeGroups = chart.typeGroups.map((group, index) => {
1771
+ const count = getLocalChildren(groups[index], "ser").length;
1772
+ const groupChart = { ...chart, chartType: group.chartType, series: chart.series.slice(seriesOffset, seriesOffset + count) };
1773
+ applyChartSeriesStyleFromXml(groupChart, groups[index], themePalette);
1774
+ seriesOffset += count;
1775
+ hydratedSeries.push(...groupChart.series);
1776
+ return { ...group, series: groupChart.series };
1777
+ });
1778
+ chart.series = [...hydratedSeries, ...chart.series.slice(seriesOffset)];
1779
+ } else {
1780
+ applyChartSeriesStyleFromXml(chart, chartTypeNode, themePalette);
1781
+ }
1648
1782
  applyFallbackSeriesStyles();
1649
1783
  applyBuiltinChartDefaults(chart, themePalette);
1650
1784
  }
@@ -1695,7 +1829,7 @@ function readArchiveText(archive, path) {
1695
1829
  return null;
1696
1830
  }
1697
1831
  const entry = archive[normalizeArchivePath(path)];
1698
- return entry ? strFromU8(entry) : null;
1832
+ return entry ? strFromU82(entry) : null;
1699
1833
  }
1700
1834
  function parseXml(xml) {
1701
1835
  if (typeof DOMParser === "undefined") {
@@ -1831,8 +1965,8 @@ function resolveReferenceSheet(workbook, fallbackSheetIndex, formula) {
1831
1965
  if (!formula) {
1832
1966
  return {
1833
1967
  range: null,
1834
- sheet: workbook.getSheet(fallbackSheetIndex),
1835
- sheetName: workbook.getSheet(fallbackSheetIndex)?.name ?? ""
1968
+ sheet: fallbackSheetIndex < workbook.sheetCount ? workbook.getSheet(fallbackSheetIndex) : null,
1969
+ sheetName: fallbackSheetIndex < workbook.sheetCount ? workbook.getSheet(fallbackSheetIndex)?.name ?? "" : ""
1836
1970
  };
1837
1971
  }
1838
1972
  const trimmedFormula = formula.trim();
@@ -1849,8 +1983,8 @@ function resolveReferenceSheet(workbook, fallbackSheetIndex, formula) {
1849
1983
  if (!split) {
1850
1984
  return {
1851
1985
  range: parseA1Range(trimmedFormula),
1852
- sheet: workbook.getSheet(fallbackSheetIndex),
1853
- sheetName: workbook.getSheet(fallbackSheetIndex)?.name ?? ""
1986
+ sheet: fallbackSheetIndex < workbook.sheetCount ? workbook.getSheet(fallbackSheetIndex) : null,
1987
+ sheetName: fallbackSheetIndex < workbook.sheetCount ? workbook.getSheet(fallbackSheetIndex)?.name ?? "" : ""
1854
1988
  };
1855
1989
  }
1856
1990
  try {
@@ -1862,8 +1996,8 @@ function resolveReferenceSheet(workbook, fallbackSheetIndex, formula) {
1862
1996
  } catch {
1863
1997
  return {
1864
1998
  range: parseA1Range(split.range),
1865
- sheet: workbook.getSheet(fallbackSheetIndex),
1866
- sheetName: workbook.getSheet(fallbackSheetIndex)?.name ?? ""
1999
+ sheet: null,
2000
+ sheetName: split.sheetName
1867
2001
  };
1868
2002
  }
1869
2003
  }
@@ -2132,6 +2266,7 @@ function buildChartExParetoLineSeries(series, sourceRaw, index) {
2132
2266
  });
2133
2267
  return {
2134
2268
  ...series,
2269
+ id: series.id.replace(/-series-\d+$/, `-series-${index}`),
2135
2270
  color: void 0,
2136
2271
  lineColor: void 0,
2137
2272
  markerColor: void 0,
@@ -2394,7 +2529,7 @@ function normalizeChartExChart(workbook, workbookSheetIndex, visibleSheetIndex,
2394
2529
  name: typeof drawing.name === "string" ? drawing.name : chartTitle,
2395
2530
  overlap: void 0,
2396
2531
  plotVisibleOnly: void 0,
2397
- raw: chart,
2532
+ raw: { ...chart, officeSourceSeries: normalizedSeries },
2398
2533
  radarStyle: void 0,
2399
2534
  scatterStyle: void 0,
2400
2535
  roundedCorners: void 0,
@@ -2862,7 +2997,13 @@ function normalizeChartSeries(workbook, workbookSheetIndex, chartId, raw, index)
2862
2997
  name: resolveSeriesName(workbook, workbookSheetIndex, series.name),
2863
2998
  negativeColor: void 0,
2864
2999
  negativeLineColor: void 0,
2865
- raw: series,
3000
+ raw: {
3001
+ ...series,
3002
+ unresolvedCategoriesReference: Boolean(categoriesRef?.formula && !resolveReferenceSheet(workbook, workbookSheetIndex, categoriesRef.formula).sheet),
3003
+ unresolvedValuesReference: Boolean(valuesRef?.formula && !resolveReferenceSheet(workbook, workbookSheetIndex, valuesRef.formula).sheet),
3004
+ unresolvedBubbleSizeReference: Boolean(bubbleSizeRef?.formula && !resolveReferenceSheet(workbook, workbookSheetIndex, bubbleSizeRef.formula).sheet),
3005
+ unresolvedNameReference: typeof series.name === "string" && series.name.includes("!") && !resolveReferenceSheet(workbook, workbookSheetIndex, series.name).sheet
3006
+ },
2866
3007
  shapeProperties,
2867
3008
  smooth: typeof series.smooth === "boolean" ? series.smooth : void 0,
2868
3009
  values: resolveReferenceValues(workbook, workbookSheetIndex, valuesRef, "value").map((value) => typeof value === "number" && Number.isFinite(value) ? value : null),
@@ -2924,12 +3065,15 @@ function buildTabs(workbook, chartsheets, visibleSheetIndexByWorkbookSheetIndex,
2924
3065
  const slotIndex = typeof entry.index === "number" ? entry.index : index;
2925
3066
  if (slotType === "chartsheet") {
2926
3067
  const chartsheet = chartsheets[slotIndex];
3068
+ const visibility2 = normalizeWorksheetVisibility(chartsheet?.raw?.visibility);
3069
+ if (!showHiddenSheets && visibility2 !== "visible") return [];
2927
3070
  return chartsheet ? [{
2928
3071
  chartsheetIndex: slotIndex,
2929
3072
  id: `chartsheet-${slotIndex}`,
2930
3073
  index,
2931
3074
  kind: "chartsheet",
2932
- name: chartsheet.name
3075
+ name: chartsheet.name,
3076
+ visibility: visibility2
2933
3077
  }] : [];
2934
3078
  }
2935
3079
  const worksheet = workbook.getSheet(slotIndex);
@@ -3033,9 +3177,24 @@ function applyChartOrigins(chartsByWorkbookSheetIndex, chartOriginsById, archive
3033
3177
  });
3034
3178
  }
3035
3179
  }
3036
- function hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets) {
3180
+ function hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets, chartsheets = []) {
3037
3181
  const chartOriginsById = /* @__PURE__ */ new Map();
3038
3182
  applyChartOrigins(chartsByWorkbookSheetIndex, chartOriginsById, imageAssets.archive, imageAssets.sheetOrigins);
3183
+ const chartsheetOrigins = collectChartsheetDrawingOrigins(imageAssets.archive, chartsheets);
3184
+ for (const chartsheet of chartsheets) {
3185
+ if (chartsheet.workbookSheetIndex == null) continue;
3186
+ const charts = chartsByWorkbookSheetIndex[chartsheet.workbookSheetIndex] ?? [];
3187
+ const origins = collectChartOriginsForSheet(imageAssets.archive, chartsheetOrigins.get(chartsheet.index) ?? null);
3188
+ for (const chart of charts) {
3189
+ const kind = chart.id.startsWith("chart-ex-") ? "modern" : "classic";
3190
+ const origin = origins.find((entry) => entry.chartKind === kind);
3191
+ if (!origin) continue;
3192
+ if (origin.anchor) chart.anchor = origin.anchor;
3193
+ chart.chartPath = origin.chartPath ?? void 0;
3194
+ chartsheet.chartPath = chart.chartPath;
3195
+ chartOriginsById.set(chart.id, origin);
3196
+ }
3197
+ }
3039
3198
  for (const charts of chartsByWorkbookSheetIndex) {
3040
3199
  for (const chart of charts) {
3041
3200
  applyChartStyleFromXml(chart, chart.chartPath, imageAssets.archive, imageAssets.themePalette);
@@ -3044,6 +3203,84 @@ function hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets) {
3044
3203
  }
3045
3204
  return chartOriginsById;
3046
3205
  }
3206
+ function normalizeClassicChartDrawing(workbook, workbookSheetIndex, visibleSheetIndex, rawChart, chartIndex, chartId = `chart-${workbookSheetIndex}-${chartIndex}`) {
3207
+ const drawing = rawChart && typeof rawChart === "object" ? rawChart : {};
3208
+ const chart = drawing.chart && typeof drawing.chart === "object" ? drawing.chart : {};
3209
+ const rawView3d = chart.view3D && typeof chart.view3D === "object" ? chart.view3D : null;
3210
+ const rawSeries = Array.isArray(chart.series) ? chart.series : [];
3211
+ const typeGroups = Array.isArray(chart.typeGroups) ? chart.typeGroups.map((entry, groupIndex) => normalizeChartTypeGroup(workbook, workbookSheetIndex, chartId, entry, groupIndex)).filter((value) => value != null) : [];
3212
+ let seriesOrdinal = 0;
3213
+ const series = typeGroups.some((group) => group.series.length > 0) ? typeGroups.flatMap((group) => {
3214
+ group.series = group.series.map((entry) => ({ ...entry, id: `${chartId}-series-${seriesOrdinal++}` }));
3215
+ return group.series;
3216
+ }) : rawSeries.map((entry, seriesIndex) => normalizeChartSeries(workbook, workbookSheetIndex, chartId, entry, seriesIndex));
3217
+ const chartLevelDataLabels = normalizeChartDataLabels(chart.dataLabels);
3218
+ const firstSeriesDataLabels = rawSeries.length > 0 && rawSeries[0] && typeof rawSeries[0] === "object" ? normalizeChartDataLabels(rawSeries[0].dataLabels) : null;
3219
+ return {
3220
+ anchor: normalizeChartAnchor(drawing.anchor),
3221
+ autoTitleDeleted: typeof chart.autoTitleDeleted === "boolean" ? chart.autoTitleDeleted : void 0,
3222
+ axes: Array.isArray(chart.axes) ? chart.axes.map(normalizeChartAxis).filter((value) => Boolean(value)) : [],
3223
+ axisLabelColor: void 0,
3224
+ axisLineColor: void 0,
3225
+ categoryAxis: normalizeChartAxis(chart.categoryAxis),
3226
+ chartAreaBorderColor: void 0,
3227
+ chartAreaFillColor: void 0,
3228
+ chartColorPalette: void 0,
3229
+ chartColorPaletteOffset: void 0,
3230
+ chartPath: void 0,
3231
+ chartStyleId: void 0,
3232
+ chartType: typeof chart.chartType === "string" ? chart.chartType : "ColumnClustered",
3233
+ dataLabels: chartLevelDataLabels ?? firstSeriesDataLabels,
3234
+ displayBlanksAs: typeof chart.displayBlanksAs === "string" ? chart.displayBlanksAs : void 0,
3235
+ editable: true,
3236
+ firstSliceAngle: typeof chart.firstSliceAngle === "number" ? chart.firstSliceAngle : void 0,
3237
+ fontFamily: void 0,
3238
+ gapWidth: typeof chart.gapWidth === "number" ? chart.gapWidth : void 0,
3239
+ holeSize: typeof chart.holeSize === "number" ? chart.holeSize : void 0,
3240
+ id: chartId,
3241
+ is3d: typeof chart.is3D === "boolean" ? chart.is3D : typeof chart.is3d === "boolean" ? chart.is3d : void 0,
3242
+ legend: normalizeLegend(chart.legend) ? {
3243
+ ...normalizeLegend(chart.legend),
3244
+ position: normalizeLegendPosition(normalizeLegend(chart.legend)?.position)
3245
+ } : null,
3246
+ name: typeof drawing.name === "string" ? drawing.name : void 0,
3247
+ overlap: typeof chart.overlap === "number" ? chart.overlap : void 0,
3248
+ plotVisibleOnly: typeof chart.plotVisibleOnly === "boolean" ? chart.plotVisibleOnly : void 0,
3249
+ raw: chart,
3250
+ radarStyle: typeof chart.radarStyle === "string" ? chart.radarStyle : void 0,
3251
+ scatterStyle: typeof chart.scatterStyle === "string" ? chart.scatterStyle : void 0,
3252
+ roundedCorners: typeof chart.roundedCorners === "boolean" ? chart.roundedCorners : void 0,
3253
+ shape3d: typeof chart.shape === "string" ? chart.shape : typeof chart.shape3d === "string" ? chart.shape3d : void 0,
3254
+ seriesAxis: null,
3255
+ series,
3256
+ sheetIndex: visibleSheetIndex,
3257
+ showDlblsOverMax: typeof chart.showDlblsOverMax === "boolean" ? chart.showDlblsOverMax : void 0,
3258
+ sideWall: null,
3259
+ backWall: null,
3260
+ bubbleScale: typeof chart.bubbleScale === "number" ? chart.bubbleScale : void 0,
3261
+ bubble3d: typeof chart.bubble3d === "boolean" ? chart.bubble3d : void 0,
3262
+ floor: null,
3263
+ surfaceMaterial: void 0,
3264
+ textColor: void 0,
3265
+ title: typeof chart.title === "string" ? chart.title : void 0,
3266
+ titleColor: void 0,
3267
+ titleFontFamily: void 0,
3268
+ typeGroups,
3269
+ valueAxis: normalizeChartAxis(chart.valueAxis),
3270
+ varyColors: typeof chart.varyColors === "boolean" ? chart.varyColors : void 0,
3271
+ view3d: rawView3d ? {
3272
+ depthPercent: typeof rawView3d.depthPercent === "number" ? rawView3d.depthPercent : void 0,
3273
+ heightPercent: typeof rawView3d.heightPercent === "number" ? rawView3d.heightPercent : void 0,
3274
+ perspective: typeof rawView3d.perspective === "number" ? rawView3d.perspective : void 0,
3275
+ rAngAx: typeof rawView3d.rAngAx === "boolean" ? rawView3d.rAngAx : typeof rawView3d.rightAngleAxes === "boolean" ? rawView3d.rightAngleAxes : void 0,
3276
+ rotX: typeof rawView3d.rotX === "number" ? rawView3d.rotX : typeof rawView3d.rotateX === "number" ? rawView3d.rotateX : void 0,
3277
+ rotY: typeof rawView3d.rotY === "number" ? rawView3d.rotY : typeof rawView3d.rotateY === "number" ? rawView3d.rotateY : void 0
3278
+ } : void 0,
3279
+ wireframe: typeof chart.wireframe === "boolean" ? chart.wireframe : void 0,
3280
+ workbookSheetIndex,
3281
+ zIndex: Array.isArray(drawing.drawingPath) && typeof drawing.drawingPath[0] === "number" ? drawing.drawingPath[0] + 1 : chartIndex + 1
3282
+ };
3283
+ }
3047
3284
  function loadWorkbookChartAssets(workbook, imageAssets, visibleSheetIndexByWorkbookSheetIndex, showHiddenSheets = false) {
3048
3285
  const excludedChartIds = /* @__PURE__ */ new Set();
3049
3286
  const chartsByWorkbookSheetIndex = Array.from({ length: workbook.sheetCount }, (_, workbookSheetIndex) => {
@@ -3056,76 +3293,7 @@ function loadWorkbookChartAssets(workbook, imageAssets, visibleSheetIndexByWorkb
3056
3293
  if (rawChart.hidden || !rawChart.anchor) {
3057
3294
  excludedChartIds.add(chartId);
3058
3295
  }
3059
- const drawing = rawChart && typeof rawChart === "object" ? rawChart : {};
3060
- const chart = drawing.chart && typeof drawing.chart === "object" ? drawing.chart : {};
3061
- const rawView3d = chart.view3D && typeof chart.view3D === "object" ? chart.view3D : null;
3062
- const rawSeries = Array.isArray(chart.series) ? chart.series : [];
3063
- const chartLevelDataLabels = normalizeChartDataLabels(chart.dataLabels);
3064
- const firstSeriesDataLabels = rawSeries.length > 0 && rawSeries[0] && typeof rawSeries[0] === "object" ? normalizeChartDataLabels(rawSeries[0].dataLabels) : null;
3065
- return {
3066
- anchor: normalizeChartAnchor(drawing.anchor),
3067
- autoTitleDeleted: typeof chart.autoTitleDeleted === "boolean" ? chart.autoTitleDeleted : void 0,
3068
- axes: Array.isArray(chart.axes) ? chart.axes.map(normalizeChartAxis).filter((value) => Boolean(value)) : [],
3069
- axisLabelColor: void 0,
3070
- axisLineColor: void 0,
3071
- categoryAxis: normalizeChartAxis(chart.categoryAxis),
3072
- chartAreaBorderColor: void 0,
3073
- chartAreaFillColor: void 0,
3074
- chartColorPalette: void 0,
3075
- chartColorPaletteOffset: void 0,
3076
- chartPath: void 0,
3077
- chartStyleId: void 0,
3078
- chartType: typeof chart.chartType === "string" ? chart.chartType : "ColumnClustered",
3079
- dataLabels: chartLevelDataLabels ?? firstSeriesDataLabels,
3080
- displayBlanksAs: typeof chart.displayBlanksAs === "string" ? chart.displayBlanksAs : void 0,
3081
- editable: true,
3082
- firstSliceAngle: typeof chart.firstSliceAngle === "number" ? chart.firstSliceAngle : void 0,
3083
- fontFamily: void 0,
3084
- gapWidth: typeof chart.gapWidth === "number" ? chart.gapWidth : void 0,
3085
- holeSize: typeof chart.holeSize === "number" ? chart.holeSize : void 0,
3086
- id: chartId,
3087
- is3d: typeof chart.is3D === "boolean" ? chart.is3D : void 0,
3088
- legend: normalizeLegend(chart.legend) ? {
3089
- ...normalizeLegend(chart.legend),
3090
- position: normalizeLegendPosition(normalizeLegend(chart.legend)?.position)
3091
- } : null,
3092
- name: typeof drawing.name === "string" ? drawing.name : void 0,
3093
- overlap: typeof chart.overlap === "number" ? chart.overlap : void 0,
3094
- plotVisibleOnly: typeof chart.plotVisibleOnly === "boolean" ? chart.plotVisibleOnly : void 0,
3095
- raw: chart,
3096
- radarStyle: typeof chart.radarStyle === "string" ? chart.radarStyle : void 0,
3097
- scatterStyle: typeof chart.scatterStyle === "string" ? chart.scatterStyle : void 0,
3098
- roundedCorners: typeof chart.roundedCorners === "boolean" ? chart.roundedCorners : void 0,
3099
- shape3d: typeof chart.shape === "string" ? chart.shape : typeof chart.shape3d === "string" ? chart.shape3d : void 0,
3100
- seriesAxis: null,
3101
- series: rawSeries.map((entry, seriesIndex) => normalizeChartSeries(workbook, workbookSheetIndex, chartId, entry, seriesIndex)),
3102
- sheetIndex: visibleSheetIndex,
3103
- showDlblsOverMax: typeof chart.showDlblsOverMax === "boolean" ? chart.showDlblsOverMax : void 0,
3104
- sideWall: null,
3105
- backWall: null,
3106
- bubbleScale: typeof chart.bubbleScale === "number" ? chart.bubbleScale : void 0,
3107
- bubble3d: typeof chart.bubble3d === "boolean" ? chart.bubble3d : void 0,
3108
- floor: null,
3109
- surfaceMaterial: void 0,
3110
- textColor: void 0,
3111
- title: typeof chart.title === "string" ? chart.title : void 0,
3112
- titleColor: void 0,
3113
- titleFontFamily: void 0,
3114
- typeGroups: Array.isArray(chart.typeGroups) ? chart.typeGroups.map((entry, groupIndex) => normalizeChartTypeGroup(workbook, workbookSheetIndex, chartId, entry, groupIndex)).filter((value) => value != null) : [],
3115
- valueAxis: normalizeChartAxis(chart.valueAxis),
3116
- varyColors: typeof chart.varyColors === "boolean" ? chart.varyColors : void 0,
3117
- view3d: rawView3d ? {
3118
- depthPercent: typeof rawView3d.depthPercent === "number" ? rawView3d.depthPercent : void 0,
3119
- heightPercent: typeof rawView3d.heightPercent === "number" ? rawView3d.heightPercent : void 0,
3120
- perspective: typeof rawView3d.perspective === "number" ? rawView3d.perspective : void 0,
3121
- rAngAx: typeof rawView3d.rAngAx === "boolean" ? rawView3d.rAngAx : typeof rawView3d.rightAngleAxes === "boolean" ? rawView3d.rightAngleAxes : void 0,
3122
- rotX: typeof rawView3d.rotX === "number" ? rawView3d.rotX : typeof rawView3d.rotateX === "number" ? rawView3d.rotateX : void 0,
3123
- rotY: typeof rawView3d.rotY === "number" ? rawView3d.rotY : typeof rawView3d.rotateY === "number" ? rawView3d.rotateY : void 0
3124
- } : void 0,
3125
- wireframe: typeof chart.wireframe === "boolean" ? chart.wireframe : void 0,
3126
- workbookSheetIndex,
3127
- zIndex: Array.isArray(drawing.drawingPath) && typeof drawing.drawingPath[0] === "number" ? drawing.drawingPath[0] + 1 : chartIndex + 1
3128
- };
3296
+ return normalizeClassicChartDrawing(workbook, workbookSheetIndex, visibleSheetIndex, rawChart, chartIndex, chartId);
3129
3297
  });
3130
3298
  const modernCharts = rawChartsEx.map((rawChartEx, chartExIndex) => {
3131
3299
  const chartId = `chart-ex-${workbookSheetIndex}-${chartExIndex}`;
@@ -3144,8 +3312,36 @@ function loadWorkbookChartAssets(workbook, imageAssets, visibleSheetIndexByWorkb
3144
3312
  return [...classicCharts, ...modernCharts];
3145
3313
  });
3146
3314
  const chartsheets = Array.isArray(workbook.chartsheets) ? workbook.chartsheets.map((entry, index) => normalizeChartsheet(entry, index)) : [];
3315
+ for (const chartsheet of chartsheets) {
3316
+ const workbookSheetIndex = workbook.sheetCount + chartsheet.index;
3317
+ const raw = chartsheet.raw;
3318
+ const charts = [];
3319
+ if (raw?.chart && typeof raw.chart === "object") {
3320
+ charts.push(normalizeClassicChartDrawing(
3321
+ workbook,
3322
+ workbookSheetIndex,
3323
+ workbookSheetIndex,
3324
+ raw,
3325
+ 0,
3326
+ `${chartsheet.id}-chart-0`
3327
+ ));
3328
+ }
3329
+ if (raw?.chartEx && typeof raw.chartEx === "object") {
3330
+ charts.push(normalizeChartExChart(
3331
+ workbook,
3332
+ workbookSheetIndex,
3333
+ workbookSheetIndex,
3334
+ raw,
3335
+ 0,
3336
+ imageAssets?.themePalette ?? null
3337
+ ));
3338
+ }
3339
+ chartsByWorkbookSheetIndex[workbookSheetIndex] = charts;
3340
+ chartsheet.chartIds = charts.map((chart) => chart.id);
3341
+ chartsheet.workbookSheetIndex = workbookSheetIndex;
3342
+ }
3147
3343
  const tabs = buildTabs(workbook, chartsheets, visibleSheetIndexByWorkbookSheetIndex, showHiddenSheets);
3148
- const chartOriginsById = imageAssets ? hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets) : /* @__PURE__ */ new Map();
3344
+ const chartOriginsById = imageAssets ? hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets, chartsheets) : /* @__PURE__ */ new Map();
3149
3345
  if (imageAssets) {
3150
3346
  for (let index = 0; index < chartsByWorkbookSheetIndex.length; index += 1) {
3151
3347
  chartsByWorkbookSheetIndex[index] = (chartsByWorkbookSheetIndex[index] ?? []).filter((chart) => !excludedChartIds.has(chart.id));
@@ -3616,8 +3812,8 @@ function resolveWorkbookFillStyle(fill, themePalette) {
3616
3812
  }
3617
3813
 
3618
3814
  // src/images.ts
3619
- import { strFromU8 as strFromU82, strToU8 as strToU82, unzipSync, zipSync } from "fflate";
3620
- var REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
3815
+ import { strFromU8 as strFromU83, strToU8 as strToU82, unzipSync, zipSync } from "fflate";
3816
+ var REL_NS2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
3621
3817
  var PKG_REL_NS = "http://schemas.openxmlformats.org/package/2006/relationships";
3622
3818
  var SPREADSHEET_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
3623
3819
  var CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types";
@@ -3666,6 +3862,19 @@ function measureColumnCharacterWidthPx(fontFamily, fontSizePt) {
3666
3862
  columnCharacterWidthCache.set(cacheKey, width);
3667
3863
  return width;
3668
3864
  }
3865
+ function measureOfficeDigitWidthPt(fontFamily, fontSizePt) {
3866
+ const family = fontFamily?.trim() || "Calibri";
3867
+ const size = typeof fontSizePt === "number" && fontSizePt > 0 ? fontSizePt : 11;
3868
+ const key = `office|${family}|${size}`;
3869
+ const cached = columnCharacterWidthCache.get(key);
3870
+ if (cached !== void 0) return cached;
3871
+ const context = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : null;
3872
+ if (!context) return 6;
3873
+ context.font = `${size}px ${JSON.stringify(family)}, "React XLSX Carlito"`;
3874
+ const width = Math.max(1, Math.round(Math.max(...Array.from("0123456789", (digit) => context.measureText(digit).width))));
3875
+ columnCharacterWidthCache.set(key, width);
3876
+ return width;
3877
+ }
3669
3878
  function sheetColumnWidthToPixels(width, columnCharacterWidthPx = DEFAULT_COLUMN_CHARACTER_WIDTH_PX) {
3670
3879
  if (!Number.isFinite(width) || width <= 0) {
3671
3880
  return MIN_COL_WIDTH_PX;
@@ -3838,7 +4047,7 @@ function serializeXml2(document2) {
3838
4047
  }
3839
4048
  function readArchiveText2(archive, path) {
3840
4049
  const entry = archive[path];
3841
- return entry ? strFromU82(entry) : null;
4050
+ return entry ? strFromU83(entry) : null;
3842
4051
  }
3843
4052
  function parseColumnReference(reference) {
3844
4053
  let value = 0;
@@ -3933,10 +4142,10 @@ function readFeaturePropertyBagCheckboxComplements(archive) {
3933
4142
  return checkboxComplementIndices;
3934
4143
  }
3935
4144
  function getRelationshipId(element) {
3936
- return element.getAttributeNS(REL_NS, "id") ?? element.getAttribute("r:id") ?? element.getAttribute("id");
4145
+ return element.getAttributeNS(REL_NS2, "id") ?? element.getAttribute("r:id") ?? element.getAttribute("id");
3937
4146
  }
3938
4147
  function getEmbeddedRelationshipId(element) {
3939
- return element.getAttributeNS(REL_NS, "embed") ?? element.getAttribute("r:embed") ?? element.getAttribute("embed");
4148
+ return element.getAttributeNS(REL_NS2, "embed") ?? element.getAttribute("r:embed") ?? element.getAttribute("embed");
3940
4149
  }
3941
4150
  function setChildText(parent, localName, value) {
3942
4151
  const child = getFirstChild(parent, localName);
@@ -4804,6 +5013,18 @@ function parseSheetState(archive, path, options) {
4804
5013
  options?.defaultFont?.sizePt
4805
5014
  );
4806
5015
  const defaultRowHeight = Number(sheetFormatNode?.getAttribute("defaultRowHeight") ?? 15);
5016
+ const digitWidthPt = measureOfficeDigitWidthPt(options?.defaultFont?.family, options?.defaultFont?.sizePt);
5017
+ const storedColumnPixels = (width) => Math.max(0, Math.floor(
5018
+ (256 * width + Math.floor(128 / digitWidthPt)) / 256 * digitWidthPt
5019
+ ) * (4 / 3));
5020
+ const explicitDefaultWidth = Number(sheetFormatNode?.getAttribute("defaultColWidth") ?? Number.NaN);
5021
+ const baseWidth = Number(sheetFormatNode?.getAttribute("baseColWidth") ?? 8);
5022
+ const officeLayout = {
5023
+ defaultColumnPx: Number.isFinite(explicitDefaultWidth) && explicitDefaultWidth > 0 ? storedColumnPixels(explicitDefaultWidth) : ((Number.isFinite(baseWidth) && baseWidth > 0 ? baseWidth : 8) * digitWidthPt + 5) * (4 / 3),
5024
+ defaultRowPx: (Number.isFinite(defaultRowHeight) && defaultRowHeight > 0 ? defaultRowHeight : 15) * (4 / 3),
5025
+ columns: {},
5026
+ rows: {}
5027
+ };
4807
5028
  const defaultColWidth = Number(
4808
5029
  sheetFormatNode?.getAttribute("defaultColWidth") ?? sheetFormatNode?.getAttribute("baseColWidth") ?? 8.43
4809
5030
  );
@@ -4837,6 +5058,7 @@ function parseSheetState(archive, path, options) {
4837
5058
  const styleId = Number(rowNode.getAttribute("s") ?? Number.NaN);
4838
5059
  if (rowIndex >= 0 && Number.isFinite(height)) {
4839
5060
  rowHeightOverridesPx[rowIndex] = Math.max(MIN_ROW_HEIGHT_PX, Math.round(height * 1.33));
5061
+ officeLayout.rows[rowIndex] = { sourcePx: rowHeightOverridesPx[rowIndex], sizePx: Math.max(0, height * (4 / 3)) };
4840
5062
  }
4841
5063
  if (rowIndex >= 0 && Number.isFinite(styleId)) {
4842
5064
  rowStyleIds[rowIndex] = styleId;
@@ -4875,6 +5097,7 @@ function parseSheetState(archive, path, options) {
4875
5097
  if (Number.isFinite(width)) {
4876
5098
  const widthPx = sheetColumnWidthToPixels(width, columnWidthCharacterWidthPx);
4877
5099
  colWidthOverridesPx[col] = widthPx;
5100
+ officeLayout.columns[col] = { sourcePx: widthPx, sizePx: storedColumnPixels(width) };
4878
5101
  }
4879
5102
  if (Number.isFinite(styleId)) {
4880
5103
  colStyleIds[col] = styleId;
@@ -4891,6 +5114,7 @@ function parseSheetState(archive, path, options) {
4891
5114
  colStyleIds,
4892
5115
  conditionalFormatRules,
4893
5116
  defaultColWidthPx: sheetColumnWidthToPixels(defaultColWidth, columnWidthCharacterWidthPx),
5117
+ officeLayout,
4894
5118
  defaultRowHeightPx: Math.max(MIN_ROW_HEIGHT_PX, Math.round(defaultRowHeight * 1.33)),
4895
5119
  hasHorizontalMerges: false,
4896
5120
  hasVerticalMerges: false,
@@ -6345,7 +6569,7 @@ function appendSheetDrawingReference(sheetDocument, relationshipId) {
6345
6569
  return;
6346
6570
  }
6347
6571
  const drawingNode = sheetDocument.createElementNS(SPREADSHEET_NS, "drawing");
6348
- drawingNode.setAttributeNS(REL_NS, "r:id", relationshipId);
6572
+ drawingNode.setAttributeNS(REL_NS2, "r:id", relationshipId);
6349
6573
  const successorNames = /* @__PURE__ */ new Set([
6350
6574
  "legacyDrawing",
6351
6575
  "legacyDrawingHF",
@@ -7396,6 +7620,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
7396
7620
  colStyleIds: sheetState?.colStyleIds ?? {},
7397
7621
  conditionalFormatRules: sheetState?.conditionalFormatRules ?? [],
7398
7622
  dataValidations: parseWorksheetDataValidations(worksheet),
7623
+ officeLayout: sheetState?.officeLayout,
7399
7624
  defaultColWidthPx,
7400
7625
  defaultRowHeightPx,
7401
7626
  freezePanes: parseWorksheetFreezePanes(worksheet),
@@ -7485,6 +7710,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
7485
7710
  colStyleIds: sheetState?.colStyleIds ?? {},
7486
7711
  conditionalFormatRules: sheetState?.conditionalFormatRules ?? [],
7487
7712
  dataValidations: parseWorksheetDataValidations(worksheet),
7713
+ officeLayout: sheetState?.officeLayout,
7488
7714
  defaultColWidthPx,
7489
7715
  defaultRowHeightPx,
7490
7716
  freezePanes: parseWorksheetFreezePanes(worksheet),
@@ -8010,7 +8236,7 @@ function sanitizeSavedWorkbookBytes(bytes) {
8010
8236
  const archive = unzipSync2(bytes);
8011
8237
  const stylesEntry = archive["xl/styles.xml"];
8012
8238
  if (stylesEntry) {
8013
- const stylesXml = strFromU83(stylesEntry).replace(/&amp;quot;/g, "&quot;").replace(/&amp;apos;/g, "&apos;");
8239
+ const stylesXml = strFromU84(stylesEntry).replace(/&amp;quot;/g, "&quot;").replace(/&amp;apos;/g, "&apos;");
8014
8240
  archive["xl/styles.xml"] = strToU83(stylesXml);
8015
8241
  }
8016
8242
  return zipSync2(archive, { level: 6 });
@@ -8653,7 +8879,7 @@ function useXlsxViewerController(options) {
8653
8879
  return;
8654
8880
  }
8655
8881
  if (imageAssetsRef.current && !effectiveSkipXmlParsing) {
8656
- const chartOriginsById = hydrateWorkbookChartStyles(result.chartsByWorkbookSheetIndex, imageAssetsRef.current);
8882
+ const chartOriginsById = hydrateWorkbookChartStyles(result.chartsByWorkbookSheetIndex, imageAssetsRef.current, result.chartsheets);
8657
8883
  chartAssetsRef.current = { ...result, chartOriginsById };
8658
8884
  }
8659
8885
  setChartsByWorkbookSheetIndex(result.chartsByWorkbookSheetIndex);
@@ -8878,10 +9104,10 @@ function useXlsxViewerController(options) {
8878
9104
  return;
8879
9105
  }
8880
9106
  setImageAssets(workerImageAssets);
8881
- const chartOriginsById = workerImageAssets ? hydrateWorkbookChartStyles(snapshot.chartsByWorkbookSheetIndex, workerImageAssets) : /* @__PURE__ */ new Map();
9107
+ const chartOriginsById = workerImageAssets ? hydrateWorkbookChartStyles(snapshot.chartsByWorkbookSheetIndex, workerImageAssets, snapshot.chartsheets) : /* @__PURE__ */ new Map();
8882
9108
  setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
8883
9109
  setWorkbook(null);
8884
- setSheets(snapshot.sheets);
9110
+ setSheets(snapshot.sheets.map((sheet) => ({ ...sheet, officeLayout: workerImageAssets?.sheetStatesByWorkbookSheetIndex[sheet.workbookSheetIndex]?.officeLayout })));
8885
9111
  setChartsByWorkbookSheetIndex(snapshot.chartsByWorkbookSheetIndex);
8886
9112
  setChartsheets(snapshot.chartsheets);
8887
9113
  setTabs(snapshot.tabs);
@@ -9134,11 +9360,11 @@ function useXlsxViewerController(options) {
9134
9360
  }
9135
9361
  const workerImageAssets = effectiveSkipXmlParsing ? null : parseWorkbookImageAssets(new Uint8Array(deferredBuffer));
9136
9362
  setImageAssets(workerImageAssets);
9137
- const chartOriginsById = workerImageAssets ? hydrateWorkbookChartStyles(snapshot.chartsByWorkbookSheetIndex, workerImageAssets) : /* @__PURE__ */ new Map();
9363
+ const chartOriginsById = workerImageAssets ? hydrateWorkbookChartStyles(snapshot.chartsByWorkbookSheetIndex, workerImageAssets, snapshot.chartsheets) : /* @__PURE__ */ new Map();
9138
9364
  deferredBufferRef.current = null;
9139
9365
  setDeferredLoadFileSize(null);
9140
9366
  setWorkbook(null);
9141
- setSheets(snapshot.sheets);
9367
+ setSheets(snapshot.sheets.map((sheet) => ({ ...sheet, officeLayout: workerImageAssets?.sheetStatesByWorkbookSheetIndex[sheet.workbookSheetIndex]?.officeLayout })));
9142
9368
  setChartsByWorkbookSheetIndex(snapshot.chartsByWorkbookSheetIndex);
9143
9369
  setChartsheets(snapshot.chartsheets);
9144
9370
  setTabs(snapshot.tabs);
@@ -10461,7 +10687,13 @@ function useXlsxViewerController(options) {
10461
10687
  if (!nextChart) {
10462
10688
  return false;
10463
10689
  }
10464
- updateChart(chartId, { series: nextChart.series, renderSource: chart.renderSource });
10690
+ const source = chart.renderSource;
10691
+ const indexedCategoryFormulaChanged = source?.indexedXSeries?.[seriesIndex] && chart.series[seriesIndex]?.categoriesRef?.formula !== nextChart.series[seriesIndex]?.categoriesRef?.formula;
10692
+ updateChart(chartId, {
10693
+ series: nextChart.series,
10694
+ typeGroups: nextChart.typeGroups,
10695
+ renderSource: source?.sourceSeries || indexedCategoryFormulaChanged ? void 0 : source
10696
+ });
10465
10697
  const selectedSeries = nextChart.series[seriesIndex];
10466
10698
  if (selectedSeries) {
10467
10699
  setSelectedChartElement((current) => current && current.chartId === chartId && current.kind !== "chart" ? {