ooxml-core 1.14.0 → 1.16.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 (143) hide show
  1. package/dist/PptxHandler-3A7VEXVK.cjs +13 -0
  2. package/dist/PptxHandler-7POULDRL.mjs +4 -0
  3. package/dist/{PptxHandler-KNBFECUE.mjs → PptxHandler-M35YFCUC.mjs} +2 -2
  4. package/dist/PresentationBuilder-C7NPM7OQ.mjs +4 -0
  5. package/dist/{PresentationBuilder-II7C4A3R.cjs → PresentationBuilder-XVRTITYR.cjs} +6 -5
  6. package/dist/{PresentationBuilder-5DCCFHWJ.mjs → PresentationBuilder-Y6DJK6H2.mjs} +2 -2
  7. package/dist/automation/index.cjs +1198 -1095
  8. package/dist/automation/index.mjs +1198 -1095
  9. package/dist/chunk-5W2QL4SB.cjs +244 -0
  10. package/dist/{chunk-TQE7FFNT.cjs → chunk-AHRFBMLK.cjs} +4070 -2015
  11. package/dist/{chunk-2D4IFQ5M.mjs → chunk-B37EVUMG.mjs} +1 -1
  12. package/dist/{chunk-4WZLFUUA.mjs → chunk-C2Y6SZDN.mjs} +934 -200
  13. package/dist/chunk-CA7KCNL3.mjs +236 -0
  14. package/dist/{chunk-BSUIDT6K.cjs → chunk-DWRJ62KP.cjs} +1 -0
  15. package/dist/{chunk-TNNXOW2O.mjs → chunk-KOX5Y5E5.mjs} +1 -1
  16. package/dist/{chunk-54ASP65T.mjs → chunk-LM6VBPQJ.mjs} +416 -15
  17. package/dist/{chunk-PC4MTLG4.cjs → chunk-OA5V3JJC.cjs} +8 -8
  18. package/dist/{chunk-ORH32TO3.mjs → chunk-OKGQ2X7D.mjs} +3092 -1037
  19. package/dist/{chunk-X7MGZQ6C.cjs → chunk-UGWY72WC.cjs} +396 -254
  20. package/dist/{chunk-XGXIS4PN.mjs → chunk-WBCV52YV.mjs} +3077 -1027
  21. package/dist/{chunk-2EBMHIGJ.mjs → chunk-WEFFRYXN.mjs} +379 -242
  22. package/dist/{chunk-AXF2FC4D.mjs → chunk-WSRCLCMB.mjs} +1 -0
  23. package/dist/{chunk-LMMP67YN.mjs → chunk-XCJRUBGJ.mjs} +1 -1
  24. package/dist/geometry/index.cjs +259 -0
  25. package/dist/geometry/index.d.ts +1 -0
  26. package/dist/geometry/index.d.ts.map +1 -1
  27. package/dist/geometry/index.mjs +255 -1
  28. package/dist/geometry/shape-gallery-catalog.d.ts +32 -0
  29. package/dist/geometry/shape-gallery-catalog.d.ts.map +1 -0
  30. package/dist/index.cjs +371 -112
  31. package/dist/index.mjs +371 -112
  32. package/dist/pptx/automation/index.cjs +4523 -1957
  33. package/dist/pptx/automation/index.d.ts +4 -4
  34. package/dist/pptx/automation/index.mjs +5 -5
  35. package/dist/pptx/chunks/{elements-tK7xnWeS.d.ts → elements-iUzpAeqR.d.ts} +232 -2
  36. package/dist/pptx/chunks/elements-iUzpAeqR.d.ts.map +1 -0
  37. package/dist/pptx/chunks/{index-DS9Y4Ne3.d.ts → index-BWHNCVNC.d.ts} +1673 -1534
  38. package/dist/pptx/chunks/index-BWHNCVNC.d.ts.map +1 -0
  39. package/dist/pptx/chunks/{index-BSpNQuvz.d.ts → index-CiyTR6mm.d.ts} +201 -5
  40. package/dist/pptx/chunks/index-CiyTR6mm.d.ts.map +1 -0
  41. package/dist/pptx/chunks/{text-operations-BdD_UQ11.d.ts → text-operations-CfLVZ7DK.d.ts} +81 -3
  42. package/dist/pptx/chunks/text-operations-CfLVZ7DK.d.ts.map +1 -0
  43. package/dist/pptx/cli/index.cjs +4465 -1899
  44. package/dist/pptx/cli/index.d.ts +1 -1
  45. package/dist/pptx/cli/index.mjs +4 -4
  46. package/dist/pptx/converter/index.cjs +52 -1
  47. package/dist/pptx/converter/index.d.ts +1 -1
  48. package/dist/pptx/converter/index.mjs +2 -2
  49. package/dist/pptx/editor/render/collaboration-live-patch-target.cjs +4 -4
  50. package/dist/pptx/editor/render/collaboration-live-patch-target.mjs +2 -2
  51. package/dist/pptx/editor/render/collaboration-reconcile.cjs +7 -7
  52. package/dist/pptx/editor/render/collaboration-reconcile.mjs +2 -2
  53. package/dist/pptx/editor/render/collaboration-sync.cjs +14 -14
  54. package/dist/pptx/editor/render/collaboration-sync.d.ts.map +1 -1
  55. package/dist/pptx/editor/render/collaboration-sync.mjs +1 -1
  56. package/dist/pptx/editor/render/find-replace.cjs +15 -14
  57. package/dist/pptx/editor/render/find-replace.d.ts +2 -2
  58. package/dist/pptx/editor/render/find-replace.mjs +2 -1
  59. package/dist/pptx/editor/render/slide-operations.cjs +9 -8
  60. package/dist/pptx/editor/render/slide-operations.mjs +3 -2
  61. package/dist/pptx/editor/render/slide-size-rescale.cjs +3 -3
  62. package/dist/pptx/editor/render/slide-size-rescale.d.ts +1 -1
  63. package/dist/pptx/editor/render/slide-size-rescale.d.ts.map +1 -1
  64. package/dist/pptx/editor/render/slide-size-rescale.mjs +3 -3
  65. package/dist/pptx/editor/render/text-runs-style-patch.d.ts +1 -1
  66. package/dist/pptx/editor/render/text-style-scope.d.ts +1 -1
  67. package/dist/pptx/index.cjs +5656 -2290
  68. package/dist/pptx/index.d.ts +5 -5
  69. package/dist/pptx/index.mjs +5 -5
  70. package/dist/teams/ics.d.ts.map +1 -1
  71. package/dist/teams/index.cjs +631 -635
  72. package/dist/teams/index.d.ts +1 -0
  73. package/dist/teams/index.d.ts.map +1 -1
  74. package/dist/teams/index.mjs +616 -636
  75. package/dist/teams/meetings.d.ts +11 -1
  76. package/dist/teams/meetings.d.ts.map +1 -1
  77. package/dist/teams/recurrence-calendar.d.ts +41 -0
  78. package/dist/teams/recurrence-calendar.d.ts.map +1 -0
  79. package/dist/teams/recurrence.d.ts +1 -1
  80. package/dist/teams/recurrence.d.ts.map +1 -1
  81. package/dist/teams/server-session.d.ts +19 -0
  82. package/dist/teams/server-session.d.ts.map +1 -1
  83. package/dist/xlsx/edit/pivots.d.ts.map +1 -1
  84. package/dist/xlsx/index.cjs +1137 -1027
  85. package/dist/xlsx/index.mjs +1136 -1028
  86. package/dist/xlsx/load/index.cjs +593 -652
  87. package/dist/xlsx/load/index.mjs +593 -652
  88. package/dist/xlsx/model-pivots.d.ts +64 -4
  89. package/dist/xlsx/model-pivots.d.ts.map +1 -1
  90. package/dist/xlsx/pivot/aggregate.d.ts +6 -3
  91. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
  92. package/dist/xlsx/pivot/axes.d.ts +5 -0
  93. package/dist/xlsx/pivot/axes.d.ts.map +1 -1
  94. package/dist/xlsx/pivot/captions-locales.d.ts +3 -0
  95. package/dist/xlsx/pivot/captions-locales.d.ts.map +1 -0
  96. package/dist/xlsx/pivot/captions-read.d.ts +14 -0
  97. package/dist/xlsx/pivot/captions-read.d.ts.map +1 -0
  98. package/dist/xlsx/pivot/captions.d.ts +26 -0
  99. package/dist/xlsx/pivot/captions.d.ts.map +1 -0
  100. package/dist/xlsx/pivot/columns.d.ts +9 -3
  101. package/dist/xlsx/pivot/columns.d.ts.map +1 -1
  102. package/dist/xlsx/pivot/data.d.ts +3 -2
  103. package/dist/xlsx/pivot/data.d.ts.map +1 -1
  104. package/dist/xlsx/pivot/date-axes.d.ts +1 -1
  105. package/dist/xlsx/pivot/date-axes.d.ts.map +1 -1
  106. package/dist/xlsx/pivot/date-group-read.d.ts.map +1 -1
  107. package/dist/xlsx/pivot/date-groups.d.ts +8 -3
  108. package/dist/xlsx/pivot/date-groups.d.ts.map +1 -1
  109. package/dist/xlsx/pivot/index.d.ts +2 -1
  110. package/dist/xlsx/pivot/index.d.ts.map +1 -1
  111. package/dist/xlsx/pivot/item-labels.d.ts +12 -0
  112. package/dist/xlsx/pivot/item-labels.d.ts.map +1 -0
  113. package/dist/xlsx/pivot/item-names-read.d.ts +8 -0
  114. package/dist/xlsx/pivot/item-names-read.d.ts.map +1 -0
  115. package/dist/xlsx/pivot/measures.d.ts +2 -8
  116. package/dist/xlsx/pivot/measures.d.ts.map +1 -1
  117. package/dist/xlsx/pivot/nested.d.ts +4 -2
  118. package/dist/xlsx/pivot/nested.d.ts.map +1 -1
  119. package/dist/xlsx/pivot/page-filter-admission.d.ts.map +1 -1
  120. package/dist/xlsx/pivot/page-filter.d.ts +1 -1
  121. package/dist/xlsx/pivot/page-filter.d.ts.map +1 -1
  122. package/dist/xlsx/pivot/read.d.ts.map +1 -1
  123. package/dist/xlsx/pivot/subtotals.d.ts +6 -1
  124. package/dist/xlsx/pivot/subtotals.d.ts.map +1 -1
  125. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
  126. package/dist/xlsx/pivot/values-axis.d.ts +7 -4
  127. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -1
  128. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
  129. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
  130. package/dist/xlsx/ui/index.cjs +1002 -1136
  131. package/dist/xlsx/ui/index.mjs +1002 -1136
  132. package/package.json +1 -1
  133. package/dist/PptxHandler-5YP75BPO.cjs +0 -12
  134. package/dist/PptxHandler-GT5Q66TG.mjs +0 -3
  135. package/dist/PresentationBuilder-CVM6LJ7L.mjs +0 -3
  136. package/dist/pptx/chunks/elements-tK7xnWeS.d.ts.map +0 -1
  137. package/dist/pptx/chunks/index-BSpNQuvz.d.ts.map +0 -1
  138. package/dist/pptx/chunks/index-DS9Y4Ne3.d.ts.map +0 -1
  139. package/dist/pptx/chunks/text-operations-BdD_UQ11.d.ts.map +0 -1
  140. package/dist/xlsx/pivot/hierarchy-first.d.ts +0 -21
  141. package/dist/xlsx/pivot/hierarchy-first.d.ts.map +0 -1
  142. package/dist/xlsx/pivot/hierarchy.d.ts +0 -8
  143. package/dist/xlsx/pivot/hierarchy.d.ts.map +0 -1
@@ -315,7 +315,7 @@ function parseOle2(buffer, options = {}) {
315
315
  fatEntries.push(fatView.getUint32(i2 * 4, true));
316
316
  }
317
317
  }
318
- function followChain(table2, start, label5, needed) {
318
+ function followChain(table2, start, label2, needed) {
319
319
  const ids = [];
320
320
  const visited = /* @__PURE__ */ new Set();
321
321
  let current = start;
@@ -323,26 +323,26 @@ function parseOle2(buffer, options = {}) {
323
323
  if (!strict && needed !== void 0 && ids.length >= needed)
324
324
  return ids;
325
325
  if (visited.has(current)) {
326
- throw new Ole2ParseError(`Circular reference in ${label5} chain at sector ${current}`);
326
+ throw new Ole2ParseError(`Circular reference in ${label2} chain at sector ${current}`);
327
327
  }
328
328
  visited.add(current);
329
329
  ids.push(current);
330
330
  if (table2[current] === void 0)
331
- throw new Ole2ParseError(`Missing ${label5} chain entry`);
331
+ throw new Ole2ParseError(`Missing ${label2} chain entry`);
332
332
  current = table2[current];
333
333
  }
334
334
  if (current !== ENDOFCHAIN) {
335
335
  if (strict || needed === void 0 || ids.length < needed) {
336
- throw new Ole2ParseError(`Invalid ${label5} chain terminator`);
336
+ throw new Ole2ParseError(`Invalid ${label2} chain terminator`);
337
337
  }
338
- warnings.push({ code: "chain-terminator", message: `Accepted ${label5} chain ending in 0x${current.toString(16)}` });
338
+ warnings.push({ code: "chain-terminator", message: `Accepted ${label2} chain ending in 0x${current.toString(16)}` });
339
339
  }
340
340
  return ids;
341
341
  }
342
- function readMetadataChain(startSector, label5) {
342
+ function readMetadataChain(startSector, label2) {
343
343
  if (startSector > MAXREGSECT)
344
344
  return new Uint8Array(0);
345
- const ids = followChain(fatEntries, startSector, label5 === "directory" ? "FAT" : label5);
345
+ const ids = followChain(fatEntries, startSector, label2 === "directory" ? "FAT" : label2);
346
346
  const result2 = new Uint8Array(ids.length * sectorSize);
347
347
  ids.forEach((id, i2) => result2.set(readSector(id), i2 * sectorSize));
348
348
  return result2;
@@ -3255,7 +3255,7 @@ var DEFAULT_XML_LIMITS = {
3255
3255
  maxNodes: 5e6
3256
3256
  };
3257
3257
  var MARKUP_RE = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(\/?)([^\s\/>]+)(?:\s+[^\s=\/>]+\s*=\s*(?:"[^"]*"|'[^']*'))*\s*(\/?)>/g;
3258
- function checkXmlLimits(xml, label5, limits = {}) {
3258
+ function checkXmlLimits(xml, label2, limits = {}) {
3259
3259
  const maxDepth = limits.maxDepth ?? DEFAULT_XML_LIMITS.maxDepth;
3260
3260
  const maxNodes = limits.maxNodes ?? DEFAULT_XML_LIMITS.maxNodes;
3261
3261
  let depth = 0;
@@ -3268,16 +3268,16 @@ function checkXmlLimits(xml, label5, limits = {}) {
3268
3268
  continue;
3269
3269
  }
3270
3270
  nodes++;
3271
- if (nodes > maxNodes) throw new Error(`${label5} XML exceeds the limit of ${maxNodes} elements`);
3271
+ if (nodes > maxNodes) throw new Error(`${label2} XML exceeds the limit of ${maxNodes} elements`);
3272
3272
  if (!selfClosing && ++depth > maxDepth)
3273
- throw new Error(`${label5} XML exceeds the nesting depth limit of ${maxDepth}`);
3273
+ throw new Error(`${label2} XML exceeds the nesting depth limit of ${maxDepth}`);
3274
3274
  }
3275
3275
  }
3276
3276
  function parseXml(xml, options = {}) {
3277
- const label5 = options.label ?? "OOXML";
3277
+ const label2 = options.label ?? "OOXML";
3278
3278
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
3279
- throw new Error(`${label5} XML with DTD or entity declarations is not supported`);
3280
- checkXmlLimits(xml, label5, options.limits);
3279
+ throw new Error(`${label2} XML with DTD or entity declarations is not supported`);
3280
+ checkXmlLimits(xml, label2, options.limits);
3281
3281
  let parseError = "";
3282
3282
  let parsed;
3283
3283
  try {
@@ -3288,12 +3288,12 @@ function parseXml(xml, options = {}) {
3288
3288
  }).parseFromString(xml, "application/xml");
3289
3289
  } catch (error) {
3290
3290
  throw new Error(
3291
- `Invalid ${label5} XML: ${error instanceof Error ? error.message : String(error)}`,
3291
+ `Invalid ${label2} XML: ${error instanceof Error ? error.message : String(error)}`,
3292
3292
  { cause: error }
3293
3293
  );
3294
3294
  }
3295
3295
  if (parseError || !parsed.documentElement)
3296
- throw new Error(`Invalid ${label5} XML: ${parseError || "missing root element"}`);
3296
+ throw new Error(`Invalid ${label2} XML: ${parseError || "missing root element"}`);
3297
3297
  return parsed;
3298
3298
  }
3299
3299
  var buildXml = (node2) => new xmldom.XMLSerializer().serializeToString(node2);
@@ -4403,19 +4403,19 @@ var DIGITAL_SIGNATURE_ORIGIN_REL_TYPE = "http://schemas.openxmlformats.org/packa
4403
4403
  var MAX_ROW = 1048575;
4404
4404
  var MAX_COL = 16383;
4405
4405
  function columnLabel(col) {
4406
- let label5 = "";
4406
+ let label2 = "";
4407
4407
  let n = col + 1;
4408
4408
  while (n > 0) {
4409
4409
  const rem = (n - 1) % 26;
4410
- label5 = String.fromCharCode(65 + rem) + label5;
4410
+ label2 = String.fromCharCode(65 + rem) + label2;
4411
4411
  n = Math.floor((n - 1) / 26);
4412
4412
  }
4413
- return label5;
4413
+ return label2;
4414
4414
  }
4415
- function columnIndex(label5) {
4416
- if (!/^[A-Za-z]{1,3}$/.test(label5)) return -1;
4415
+ function columnIndex(label2) {
4416
+ if (!/^[A-Za-z]{1,3}$/.test(label2)) return -1;
4417
4417
  let n = 0;
4418
- for (const ch of label5.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64);
4418
+ for (const ch of label2.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64);
4419
4419
  return n - 1;
4420
4420
  }
4421
4421
  var formatAddress = (address2) => `${columnLabel(address2.col)}${address2.row + 1}`;
@@ -6725,11 +6725,83 @@ var pivotRowFields = (pivot) => [
6725
6725
  ...pivot.secondRowField ? [pivot.secondRowField] : [],
6726
6726
  ...pivot.secondRowField ? pivot.moreRowFields ?? [] : []
6727
6727
  ];
6728
+ function pivotValuesIndex(pivot) {
6729
+ if (pivot.valuesAxis !== "rows") return -1;
6730
+ const count2 = pivotRowFields(pivot).length;
6731
+ const at = pivot.valuesPosition;
6732
+ if (typeof at === "number") return Math.min(Math.max(Math.trunc(at), 0), count2);
6733
+ return at === "first" ? 0 : at === "between" ? Math.min(1, count2) : count2;
6734
+ }
6728
6735
  var pivotColumnFields = (pivot) => [
6729
6736
  ...pivot.columnField ? [pivot.columnField] : [],
6730
6737
  ...pivot.columnField ? pivot.moreColumnFields ?? [] : []
6731
6738
  ];
6732
6739
 
6740
+ // xlsx/pivot/captions.ts
6741
+ var FUNCTIONS = {
6742
+ sum: "Sum",
6743
+ count: "Count",
6744
+ average: "Average",
6745
+ max: "Max",
6746
+ min: "Min",
6747
+ product: "Product",
6748
+ countNums: "Count",
6749
+ stdDev: "StdDev",
6750
+ stdDevp: "StdDevp",
6751
+ var: "Var",
6752
+ varp: "Varp"
6753
+ };
6754
+ var aggregateNames = () => Object.fromEntries(
6755
+ Object.keys(FUNCTIONS).map((fn) => [
6756
+ fn,
6757
+ `${fn[0].toUpperCase()}${fn.slice(1)} of {0}`
6758
+ ])
6759
+ );
6760
+ var ENGLISH_PIVOT_CAPTIONS = {
6761
+ rowLabels: "Row Labels",
6762
+ columnLabels: "Column Labels",
6763
+ grandTotal: "Grand Total",
6764
+ values: "Values",
6765
+ all: "(All)",
6766
+ blank: "(blank)",
6767
+ subtotal: "{0} Total",
6768
+ measureTotal: "Total {0}",
6769
+ functions: FUNCTIONS,
6770
+ aggregates: aggregateNames()
6771
+ };
6772
+ var fillCaption = (template, ...args) => template.replace(/\{(\d)\}/g, (_match, at) => args[Number(at)] ?? "");
6773
+ function pivotCaptions(pivot) {
6774
+ const own = pivot.captions;
6775
+ if (!own) return ENGLISH_PIVOT_CAPTIONS;
6776
+ return {
6777
+ ...ENGLISH_PIVOT_CAPTIONS,
6778
+ ...Object.fromEntries(Object.entries(own).filter(([, value2]) => typeof value2 === "string")),
6779
+ functions: { ...ENGLISH_PIVOT_CAPTIONS.functions, ...own.functions },
6780
+ aggregates: { ...ENGLISH_PIVOT_CAPTIONS.aggregates, ...own.aggregates }
6781
+ };
6782
+ }
6783
+ function trimmedCaptions(caps) {
6784
+ const out = {};
6785
+ for (const key of [
6786
+ "rowLabels",
6787
+ "columnLabels",
6788
+ "grandTotal",
6789
+ "values",
6790
+ "all",
6791
+ "blank",
6792
+ "subtotal",
6793
+ "measureTotal"
6794
+ ])
6795
+ if (caps[key] !== ENGLISH_PIVOT_CAPTIONS[key]) out[key] = caps[key];
6796
+ for (const key of ["functions", "aggregates"]) {
6797
+ const changed = Object.keys(caps[key]).filter(
6798
+ (fn) => caps[key][fn] !== ENGLISH_PIVOT_CAPTIONS[key][fn]
6799
+ );
6800
+ if (changed.length) out[key] = Object.fromEntries(changed.map((fn) => [fn, caps[key][fn]]));
6801
+ }
6802
+ return Object.keys(out).length ? out : void 0;
6803
+ }
6804
+
6733
6805
  // xlsx/formula/date-serial.ts
6734
6806
  var DAY_MS = 864e5;
6735
6807
  var EPOCH_19002 = Date.UTC(1899, 11, 30);
@@ -6817,7 +6889,7 @@ var LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6817
6889
  var MAX_ITEMS = 1e4;
6818
6890
  var pad4 = (value2, width = 2) => String(value2).padStart(width, "0");
6819
6891
  var dateGroupUnits = (group) => PIVOT_DATE_UNITS.filter((unit) => group.by.includes(unit));
6820
- var dateGroupFieldName = (unit, field) => `${UNIT_TITLES[unit]} (${field})`;
6892
+ var dateGroupFieldName = (unit, field, group) => group?.localized?.[unit]?.name ?? `${UNIT_TITLES[unit]} (${field})`;
6821
6893
  var dateGroupDays = (group) => group.by.length === 1 && group.by[0] === "days" ? group.days ?? 1 : 1;
6822
6894
  function dateGroupRange(group, serials) {
6823
6895
  let min = Infinity;
@@ -6840,7 +6912,7 @@ var secondsOfDay = (serial) => Math.round((serial - Math.floor(serial)) * 86400)
6840
6912
  function dayBuckets(range, days) {
6841
6913
  return Math.max(1, Math.ceil((Math.floor(range.end) - Math.floor(range.start) + 1) / days));
6842
6914
  }
6843
- function dateUnitLabels(unit, range, days, date1904) {
6915
+ function englishDateUnitLabels(unit, range, days, date1904) {
6844
6916
  const labels = [`<${isoDay(range.start, date1904)}`];
6845
6917
  if (unit === "seconds" || unit === "minutes")
6846
6918
  for (let i2 = 0; i2 < 60; i2++) labels.push(`:${pad4(i2)}`);
@@ -6869,6 +6941,11 @@ function dateUnitLabels(unit, range, days, date1904) {
6869
6941
  labels.push(`>${isoDay(range.end, date1904)}`);
6870
6942
  return labels;
6871
6943
  }
6944
+ function dateUnitLabels(unit, range, days, date1904, group) {
6945
+ const english = englishDateUnitLabels(unit, range, days, date1904);
6946
+ const localized = group?.localized?.[unit]?.labels;
6947
+ return localized?.length === english.length ? localized : english;
6948
+ }
6872
6949
  function dateUnitIndex(unit, range, days, date1904, serial, count2) {
6873
6950
  if (serial < range.start) return 0;
6874
6951
  if (serial > range.end) return count2 - 1;
@@ -6892,7 +6969,7 @@ function derivedDateFields(pivot) {
6892
6969
  for (const group of pivot.dateGroups ?? [])
6893
6970
  for (const unit of dateGroupUnits(group))
6894
6971
  derived.push({
6895
- name: dateGroupFieldName(unit, group.field),
6972
+ name: dateGroupFieldName(unit, group.field, group),
6896
6973
  unit,
6897
6974
  group,
6898
6975
  index: databaseFields + derived.length
@@ -6903,7 +6980,7 @@ function countDerived(pivot) {
6903
6980
  let count2 = 0;
6904
6981
  for (const group of pivot.dateGroups ?? [])
6905
6982
  for (const unit of dateGroupUnits(group))
6906
- if (pivot.fields.includes(dateGroupFieldName(unit, group.field))) count2++;
6983
+ if (pivot.fields.includes(dateGroupFieldName(unit, group.field, group))) count2++;
6907
6984
  return count2;
6908
6985
  }
6909
6986
  var pivotAxisFieldNames = (pivot) => [
@@ -6923,7 +7000,7 @@ function derivedDateLabels(pivot, name) {
6923
7000
  if (!entry3) return void 0;
6924
7001
  const [group] = resolveDateGroups({ ...pivot, dateGroups: [entry3.group] });
6925
7002
  const range = { start: group.start, end: group.end };
6926
- return dateUnitLabels(entry3.unit, range, dateGroupDays(group), pivot.date1904 ?? false);
7003
+ return dateUnitLabels(entry3.unit, range, dateGroupDays(group), pivot.date1904 ?? false, group);
6927
7004
  }
6928
7005
  function validateDateGroups(pivot) {
6929
7006
  const groups = pivot.dateGroups;
@@ -6939,18 +7016,16 @@ function validateDateGroups(pivot) {
6939
7016
  seen.add(group.field);
6940
7017
  if (!(pivot.dateFields ?? []).includes(group.field))
6941
7018
  throw new Error("Only fields that contain dates can be grouped by date.");
6942
- if (pivot.pageFilter || pivot.dateFilter)
6943
- throw new Error("Date groups cannot be combined with report filters or timelines.");
6944
7019
  const serials = pivot.records.map((record) => record[index3]);
6945
7020
  if (!serials.length || serials.some((v) => typeof v !== "number" || !Number.isFinite(v)))
6946
7021
  throw new Error("Only fields that contain dates can be grouped by date.");
6947
7022
  const range = dateGroupRange(group, serials);
6948
7023
  if (range.start >= range.end) throw new Error("The date group must end after it starts.");
6949
7024
  for (const unit of dateGroupUnits(group)) {
6950
- const name = dateGroupFieldName(unit, group.field);
7025
+ const name = dateGroupFieldName(unit, group.field, group);
6951
7026
  if (pivot.fields.includes(name))
6952
7027
  throw new Error("A source field already has the name of a date group field.");
6953
- if (dateUnitLabels(unit, range, dateGroupDays(group), pivot.date1904 ?? false).length > MAX_ITEMS)
7028
+ if (dateUnitLabels(unit, range, dateGroupDays(group), pivot.date1904 ?? false, group).length > MAX_ITEMS)
6954
7029
  throw new Error("The date group has too many items.");
6955
7030
  }
6956
7031
  }
@@ -6964,7 +7039,7 @@ function expandDateGroups(pivot) {
6964
7039
  const tables = derived.map((entry3) => {
6965
7040
  const range = { start: entry3.group.start, end: entry3.group.end };
6966
7041
  const days = dateGroupDays(entry3.group);
6967
- const labels = dateUnitLabels(entry3.unit, range, days, date1904);
7042
+ const labels = dateUnitLabels(entry3.unit, range, days, date1904, entry3.group);
6968
7043
  return {
6969
7044
  base: pivot.fields.indexOf(entry3.group.field),
6970
7045
  labels,
@@ -7087,15 +7162,13 @@ function fieldSubtotalFunctions(pivot, field) {
7087
7162
  if (entry3) return PIVOT_SUBTOTAL_ORDER.filter((fn) => entry3.functions.includes(fn));
7088
7163
  return field === pivot.rowField && pivot.subtotals === false ? [] : "auto";
7089
7164
  }
7090
- function validateFieldSubtotals(pivot, rowFields) {
7165
+ function validateFieldSubtotals(pivot, axisFields) {
7091
7166
  const entries = pivot.fieldSubtotals;
7092
7167
  if (entries === void 0) return;
7093
7168
  if (!Array.isArray(entries)) throw new Error("Choose valid field subtotals.");
7094
- if (entries.length && pivot.valuesAxis === "rows")
7095
- throw new Error("Field subtotals require Values on columns.");
7096
7169
  const seen = /* @__PURE__ */ new Set();
7097
7170
  for (const entry3 of entries) {
7098
- if (!entry3 || typeof entry3 !== "object" || !rowFields.includes(entry3.field) || seen.has(entry3.field) || !Array.isArray(entry3.functions) || entry3.functions.some((fn) => !PIVOT_AGGREGATES.includes(fn)) || new Set(entry3.functions).size !== entry3.functions.length)
7171
+ if (!entry3 || typeof entry3 !== "object" || !axisFields.includes(entry3.field) || seen.has(entry3.field) || !Array.isArray(entry3.functions) || entry3.functions.some((fn) => !PIVOT_AGGREGATES.includes(fn)) || new Set(entry3.functions).size !== entry3.functions.length)
7099
7172
  throw new Error("Choose valid field subtotals.");
7100
7173
  seen.add(entry3.field);
7101
7174
  }
@@ -7163,6 +7236,17 @@ function validatePivotItemFilters(pivot) {
7163
7236
  }
7164
7237
  }
7165
7238
 
7239
+ // xlsx/pivot/item-labels.ts
7240
+ var keyOf = (field, item) => `${field}\0${pivotValueKey(item)}`;
7241
+ function pivotItemLabeler(pivot) {
7242
+ const blank = pivotCaptions(pivot).blank;
7243
+ const names = pivot.itemNames?.length ? new Map(pivot.itemNames.map((entry3) => [keyOf(entry3.field, entry3.item), entry3.name])) : void 0;
7244
+ return (field, value2) => names?.get(keyOf(field, value2)) ?? (value2 === null || value2 === "" ? blank : pivotItemLabel(value2));
7245
+ }
7246
+ var pivotItemName = (pivot, field, item) => pivot.itemNames?.find(
7247
+ (entry3) => entry3.field === field && pivotValueKey(entry3.item) === pivotValueKey(item)
7248
+ )?.name;
7249
+
7166
7250
  // xlsx/pivot/page-filter.ts
7167
7251
  function validatePivotPageFilter(pivot) {
7168
7252
  const filter2 = pivot.pageFilter;
@@ -7174,23 +7258,24 @@ function validatePivotPageFilter(pivot) {
7174
7258
  pivot.columnField,
7175
7259
  pivot.valueField,
7176
7260
  ...extras.map((v) => v?.field)
7177
- ].includes(filter2.field) || pivot.valuesAxis === "rows")
7178
- throw new Error("Report filters require Values on columns and a separate source field.");
7261
+ ].includes(filter2.field))
7262
+ throw new Error("Report filters require a separate source field.");
7179
7263
  if (filter2.item !== void 0 && !(filter2.item === null || typeof filter2.item === "string" || typeof filter2.item === "boolean" || typeof filter2.item === "number" && Number.isFinite(filter2.item) || isCellError(filter2.item) && isErrorCode(filter2.item.error) && Object.keys(filter2.item).length === 1))
7180
7264
  throw new Error("Choose a cached literal report filter item.");
7181
7265
  }
7182
7266
  function pivotPageProjection(pivot) {
7183
- return applyPivotGroups(applyPivotItemFilters(pagedProjection(pivot)));
7267
+ const groups = pivot.dateGroups?.length ? { ...pivot, dateGroups: resolveDateGroups(pivot) } : pivot;
7268
+ return applyPivotGroups(applyPivotItemFilters(pagedProjection(groups)));
7184
7269
  }
7185
7270
  function pagedProjection(pivot) {
7186
7271
  const filter2 = pivot.pageFilter;
7187
7272
  if (!filter2) return pivot;
7188
7273
  const labels = /* @__PURE__ */ new Map();
7189
7274
  for (const item of pivotItems(pivot, filter2.field)) {
7190
- const label5 = String(pivotItemLabel(item)).toLowerCase(), key2 = pivotValueKey(item);
7191
- if (label5 === "(all)" || labels.has(label5) && labels.get(label5) !== key2)
7275
+ const label2 = String(pivotItemLabel(item)).toLowerCase(), key2 = pivotValueKey(item);
7276
+ if (label2 === "(all)" || labels.has(label2) && labels.get(label2) !== key2)
7192
7277
  throw new Error("Ambiguous report filter item captions are preserved.");
7193
- labels.set(label5, key2);
7278
+ labels.set(label2, key2);
7194
7279
  }
7195
7280
  if (filter2.item === void 0) return pivot;
7196
7281
  const index3 = pivot.fields.indexOf(filter2.field), key = pivotValueKey(filter2.item);
@@ -7208,7 +7293,7 @@ function prependPivotPage(grid, pivot) {
7208
7293
  values: [
7209
7294
  [
7210
7295
  pivot.pageFilter.field,
7211
- pivot.pageFilter.item === void 0 ? "(All)" : pivotItemLabel(pivot.pageFilter.item),
7296
+ pivot.pageFilter.item === void 0 ? pivotCaptions(pivot).all : pivotItemLabeler(pivot)(pivot.pageFilter.field, pivot.pageFilter.item),
7212
7297
  ...Array(width - 2).fill(null)
7213
7298
  ],
7214
7299
  Array(width).fill(null),
@@ -7305,13 +7390,9 @@ function validatePivotFields(pivot) {
7305
7390
  const columns = pivotColumnFields(pivot);
7306
7391
  if (pivot.moreColumnFields !== void 0 && (!Array.isArray(pivot.moreColumnFields) || pivot.moreColumnFields.length > 0 && !pivot.columnField || pivot.moreColumnFields.length > 62 || pivot.moreColumnFields.some((name) => typeof name !== "string")))
7307
7392
  throw new Error("Choose valid PivotTable column fields.");
7308
- if (pivot.valuesAxis === "rows" && rows.length > 2)
7309
- throw new Error("Values on rows support at most two row fields.");
7310
- if (pivot.valuesAxis === "rows" && columns.length > 1)
7311
- throw new Error("Values on rows support one column field.");
7312
7393
  if (pivot.pageFilter && columns.length > 1)
7313
7394
  throw new Error("Report filters support one column field.");
7314
- validateFieldSubtotals(pivot, rows);
7395
+ validateFieldSubtotals(pivot, [...rows, ...columns]);
7315
7396
  const axisNames = pivotAxisFieldNames(pivot);
7316
7397
  if ((pivot.dateGroups ?? []).some(
7317
7398
  (group) => [...rows, ...columns].some((name) => name === group.field)
@@ -7320,13 +7401,14 @@ function validatePivotFields(pivot) {
7320
7401
  const extras = pivot.additionalValues ?? [];
7321
7402
  if (pivot.valuesAxis !== void 0 && !["columns", "rows"].includes(pivot.valuesAxis))
7322
7403
  throw new Error("Choose a valid Values axis.");
7323
- if (pivot.valuesPosition !== void 0 && !["last", "between", "first"].includes(pivot.valuesPosition))
7404
+ const position = pivot.valuesPosition;
7405
+ if (position !== void 0 && !["last", "between", "first"].includes(position) && !(typeof position === "number" && Number.isInteger(position) && position >= 0))
7324
7406
  throw new Error("Choose a valid Values position.");
7325
- if ((pivot.valuesPosition === "between" || pivot.valuesPosition === "first") && (pivot.valuesAxis !== "rows" || !pivot.secondRowField))
7407
+ if (position !== void 0 && position !== "last" && (pivot.valuesAxis !== "rows" || position === "between" && !pivot.secondRowField || typeof position === "number" && position > rows.length))
7326
7408
  throw new Error("Values before or between fields require two row fields and Values on rows.");
7327
7409
  if (pivot.valuesAxis === "rows" && (!Array.isArray(extras) || !extras.length))
7328
7410
  throw new Error("Values on rows require multiple measures.");
7329
- if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== "Values")
7411
+ if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== pivotCaptions(pivot).values)
7330
7412
  throw new Error("This PivotTable uses unsupported Values header captions.");
7331
7413
  if (!Array.isArray(extras) || extras.length > 15 || extras.some(
7332
7414
  (measure) => !measure || !pivot.fields.includes(measure.field) || !PIVOT_AGGREGATES.includes(measure.aggregate) || typeof measure.caption !== "string" || !measure.caption.trim() || measure.caption.length > 255 || pivot.fields.some((field) => field.toLowerCase() === measure.caption.toLowerCase())
@@ -7340,314 +7422,6 @@ function validatePivotFields(pivot) {
7340
7422
  throw new Error("Choose valid PivotTable fields; row and column fields must differ.");
7341
7423
  }
7342
7424
 
7343
- // xlsx/pivot/measures.ts
7344
- var pivotMeasures = (pivot) => [
7345
- { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
7346
- ...pivot.additionalValues ?? []
7347
- ];
7348
- var DIV0 = { error: "#DIV/0!" };
7349
- function variance(numbers3, sample) {
7350
- const n = numbers3.length;
7351
- if (n < (sample ? 2 : 1)) return DIV0;
7352
- const mean2 = numbers3.reduce((total2, value2) => total2 + value2, 0) / n;
7353
- const squares = numbers3.reduce((total2, value2) => total2 + (value2 - mean2) ** 2, 0);
7354
- return squares / (sample ? n - 1 : n);
7355
- }
7356
- function aggregateValues(records, field, type) {
7357
- if (!records.length) return null;
7358
- const values2 = records.map((record) => record[field] ?? null);
7359
- if (type === "count") return values2.filter((value2) => value2 !== null && value2 !== "").length;
7360
- if (type === "countNums") return values2.filter((value2) => typeof value2 === "number").length;
7361
- const error = values2.find(isCellError);
7362
- if (error) return error;
7363
- const numbers3 = values2.filter((value2) => typeof value2 === "number");
7364
- if (type === "var" || type === "varp" || type === "stdDev" || type === "stdDevp") {
7365
- const result2 = variance(numbers3, type === "var" || type === "stdDev");
7366
- return typeof result2 === "number" && (type === "stdDev" || type === "stdDevp") ? Math.sqrt(result2) : result2;
7367
- }
7368
- if (!numbers3.length) return type === "average" ? DIV0 : 0;
7369
- if (type === "min") return numbers3.reduce((a2, b) => Math.min(a2, b));
7370
- if (type === "max") return numbers3.reduce((a2, b) => Math.max(a2, b));
7371
- if (type === "product") return numbers3.reduce((total2, value2) => total2 * value2, 1);
7372
- const sum3 = numbers3.reduce((total2, value2) => total2 + value2, 0);
7373
- return type === "average" ? sum3 / numbers3.length : sum3;
7374
- }
7375
- var pivotMeasureNumber = (pivot, records, measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), measure.aggregate);
7376
- var pivotNumbers = (pivot, records) => pivotMeasures(pivot).map((measure) => pivotMeasureNumber(pivot, records, measure));
7377
- function pivotHeaderDimensions(pivot, columnItems, rowLabels) {
7378
- return {
7379
- rows: (pivot.columnField ? 2 : 1) + (pivot.pageFilter ? 2 : 0),
7380
- width: rowLabels + (pivot.columnField ? columnItems + 1 : 1)
7381
- };
7382
- }
7383
- function pivotHeaders(pivot, columns, labels, label5) {
7384
- const rowLabels = pivot.layout === "compact" ? ["Row Labels"] : pivot.valuesPosition === "first" ? ["Values", ...labels] : pivot.valuesPosition === "between" ? [labels[0], "Values", labels[1]] : [...labels, "Values"];
7385
- return pivot.columnField ? [
7386
- [
7387
- ...rowLabels.map(() => null),
7388
- pivot.layout === "compact" ? "Column Labels" : pivot.columnField,
7389
- ...columns.map(() => null)
7390
- ],
7391
- [...rowLabels, ...columns.map(label5), "Grand Total"]
7392
- ] : [[...rowLabels, null]];
7393
- }
7394
-
7395
- // xlsx/pivot/hierarchy-first.ts
7396
- function appendFirstPivotValues(pivot, context) {
7397
- const {
7398
- rowItems,
7399
- secondRowItems,
7400
- columnItems,
7401
- children: children2,
7402
- innerIndices,
7403
- groups,
7404
- details,
7405
- buckets,
7406
- width,
7407
- rowLabels,
7408
- top,
7409
- bottom,
7410
- append
7411
- } = context;
7412
- const compact = pivot.layout === "compact";
7413
- const tabular = !pivot.layout || pivot.layout === "tabular";
7414
- const blank = () => Array(width - rowLabels).fill(null);
7415
- pivotMeasures(pivot).forEach((measure, m) => {
7416
- const numbers3 = (keys, records) => [
7417
- ...columnItems.map(
7418
- (column2) => pivotMeasureNumber(
7419
- pivot,
7420
- buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [],
7421
- measure
7422
- )
7423
- ),
7424
- pivotMeasureNumber(pivot, records, measure)
7425
- ];
7426
- if (!tabular)
7427
- append([measure.caption, ...Array(rowLabels - 1).fill(null)], blank(), {
7428
- indices: [m],
7429
- measure: m
7430
- });
7431
- let first2 = true;
7432
- rowItems.forEach((outer, outerIndex) => {
7433
- const key = pivotValueKey(outer);
7434
- const group = groups.get(key) ?? [];
7435
- if (!tabular)
7436
- append(
7437
- compact ? [pivotItemLabel(outer)] : [null, pivotItemLabel(outer), null],
7438
- top ? numbers3([key], group) : blank(),
7439
- { indices: [m, outerIndex], measure: m },
7440
- compact ? 1 : 0
7441
- );
7442
- const innerKeys = [...children2.get(key)].sort(
7443
- (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
7444
- );
7445
- innerKeys.forEach((innerKey, child4) => {
7446
- const innerIndex = innerIndices.get(innerKey);
7447
- append(
7448
- compact ? [pivotItemLabel(secondRowItems[innerIndex])] : [
7449
- tabular && first2 ? measure.caption : null,
7450
- pivot.repeatLabels || tabular && child4 === 0 ? pivotItemLabel(outer) : null,
7451
- pivotItemLabel(secondRowItems[innerIndex])
7452
- ],
7453
- numbers3([key, innerKey], details.get(JSON.stringify([key, innerKey]))),
7454
- { indices: [m, outerIndex, innerIndex], measure: m },
7455
- compact ? 2 : 0
7456
- );
7457
- first2 = false;
7458
- });
7459
- if (bottom)
7460
- append(
7461
- compact ? [`${String(pivotItemLabel(outer))} Total`] : [null, `${String(pivotItemLabel(outer))} Total`, null],
7462
- numbers3([key], group),
7463
- { indices: [m, outerIndex], measure: m, type: "default" },
7464
- compact ? 1 : 0
7465
- );
7466
- });
7467
- });
7468
- }
7469
-
7470
- // xlsx/pivot/hierarchy.ts
7471
- var label = pivotItemLabel;
7472
- function hierarchicalPivotGrid(pivot) {
7473
- const rowItems = pivotItems(pivot, pivot.rowField);
7474
- const secondRowItems = pivotItems(pivot, pivot.secondRowField);
7475
- const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
7476
- const outerField = pivot.fields.indexOf(pivot.rowField);
7477
- const innerField = pivot.fields.indexOf(pivot.secondRowField);
7478
- const columnField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
7479
- const layout3 = pivot.layout ?? "tabular";
7480
- const compact = layout3 === "compact";
7481
- const firstValues = pivot.valuesPosition === "first";
7482
- const between = pivot.valuesPosition === "between";
7483
- const measures = pivotMeasures(pivot);
7484
- const top = firstValues && layout3 !== "tabular" && pivot.subtotals !== false && (pivot.subtotalPosition ?? "top") === "top";
7485
- const bottom = pivot.subtotals !== false && !top;
7486
- const rowLabelColumns = compact ? 1 : 3;
7487
- const groups = /* @__PURE__ */ new Map();
7488
- const details = /* @__PURE__ */ new Map();
7489
- const children2 = /* @__PURE__ */ new Map();
7490
- const innerIndices = new Map(secondRowItems.map((item, index3) => [pivotValueKey(item), index3]));
7491
- const buckets = /* @__PURE__ */ new Map();
7492
- const collect = (map, key, record) => {
7493
- const list = map.get(key);
7494
- if (list) list.push(record);
7495
- else map.set(key, [record]);
7496
- };
7497
- for (const record of pivot.records) {
7498
- const outer = pivotValueKey(record[outerField] ?? null);
7499
- const inner = pivotValueKey(record[innerField] ?? null);
7500
- collect(groups, outer, record);
7501
- collect(details, JSON.stringify([outer, inner]), record);
7502
- if (!children2.has(outer)) children2.set(outer, /* @__PURE__ */ new Set());
7503
- children2.get(outer).add(inner);
7504
- if (pivot.columnField) {
7505
- const column2 = pivotValueKey(record[columnField] ?? null);
7506
- for (const key of [[], [outer], [outer, inner]])
7507
- collect(buckets, JSON.stringify([...key, column2]), record);
7508
- }
7509
- }
7510
- const dimensions = pivotHeaderDimensions(pivot, columnItems.length, rowLabelColumns);
7511
- const rows = (details.size + rowItems.length * Number(bottom) + 1) * measures.length + rowItems.length * Number(layout3 !== "tabular") * (firstValues ? measures.length : 1) + (firstValues ? measures.length : between ? rowItems.length * measures.length : details.size) * Number(layout3 !== "tabular") + dimensions.rows;
7512
- if (rows * dimensions.width > 1e6) throw new Error("The PivotTable result is too large.");
7513
- const labels = compact ? ["Row Labels"] : [pivot.rowField, pivot.secondRowField];
7514
- const values2 = pivotHeaders(pivot, columnItems, labels, label);
7515
- const firstDataRow = values2.length;
7516
- const indents = values2.map(() => 0);
7517
- const rowEntries = [];
7518
- const append = (labels2, numbers4, entry3, indent = 0) => {
7519
- values2.push([...labels2, ...numbers4]);
7520
- rowEntries.push(entry3);
7521
- indents.push(indent);
7522
- };
7523
- const bands = (keys, records) => [
7524
- ...columnItems.map(
7525
- (column2) => pivotNumbers(pivot, buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [])
7526
- ),
7527
- pivotNumbers(pivot, records)
7528
- ];
7529
- const numbers3 = (keys, records) => bands(keys, records).flat();
7530
- const appendMeasures = (labels2, keys, records, indices, type) => {
7531
- const values3 = bands(keys, records);
7532
- measures.forEach(
7533
- (measure, m) => append(
7534
- type ? [
7535
- `${type === "grand" ? "Total" : String(labels2[0])} ${measure.caption}`,
7536
- ...Array(rowLabelColumns - 1).fill(null)
7537
- ] : compact ? [measure.caption] : [
7538
- ...labels2.map(
7539
- (label5) => layout3 === "tabular" && m === 0 || pivot.repeatLabels ? label5 : null
7540
- ),
7541
- measure.caption
7542
- ],
7543
- values3.map((band) => band[m] ?? null),
7544
- { indices: type ? indices : [...indices, m], measure: m, ...type ? { type } : {} },
7545
- compact && !type ? 2 : 0
7546
- )
7547
- );
7548
- };
7549
- if (firstValues)
7550
- appendFirstPivotValues(pivot, {
7551
- rowItems,
7552
- secondRowItems,
7553
- columnItems,
7554
- children: children2,
7555
- innerIndices,
7556
- groups,
7557
- details,
7558
- buckets,
7559
- width: dimensions.width,
7560
- rowLabels: rowLabelColumns,
7561
- top,
7562
- bottom,
7563
- append
7564
- });
7565
- else
7566
- rowItems.forEach((outer, outerIndex) => {
7567
- const key = pivotValueKey(outer);
7568
- if (layout3 !== "tabular")
7569
- append(
7570
- [label(outer), ...Array(rowLabelColumns - 1).fill(null)],
7571
- top ? numbers3([key], groups.get(key) ?? []) : Array(dimensions.width - rowLabelColumns).fill(null),
7572
- { indices: [outerIndex] }
7573
- );
7574
- let first2 = true;
7575
- const innerKeys = [...children2.get(key)].sort(
7576
- (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
7577
- );
7578
- if (between)
7579
- measures.forEach((measure, m) => {
7580
- if (layout3 !== "tabular")
7581
- append(
7582
- compact ? [measure.caption] : [pivot.repeatLabels ? label(outer) : null, measure.caption, null],
7583
- Array(dimensions.width - rowLabelColumns).fill(null),
7584
- { indices: [outerIndex, m], measure: m },
7585
- compact ? 1 : 0
7586
- );
7587
- innerKeys.forEach((innerKey, child4) => {
7588
- const innerIndex = innerIndices.get(innerKey);
7589
- const keys = [key, innerKey];
7590
- const records = details.get(JSON.stringify(keys));
7591
- append(
7592
- compact ? [label(secondRowItems[innerIndex])] : [
7593
- pivot.repeatLabels || layout3 === "tabular" && m === 0 && child4 === 0 ? label(outer) : null,
7594
- layout3 === "tabular" && child4 === 0 ? measure.caption : null,
7595
- label(secondRowItems[innerIndex])
7596
- ],
7597
- [
7598
- ...columnItems.map(
7599
- (column2) => pivotMeasureNumber(
7600
- pivot,
7601
- buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [],
7602
- measure
7603
- )
7604
- ),
7605
- pivotMeasureNumber(pivot, records, measure)
7606
- ],
7607
- { indices: [outerIndex, m, innerIndex], measure: m },
7608
- compact ? 2 : 0
7609
- );
7610
- });
7611
- });
7612
- else
7613
- innerKeys.forEach((innerKey) => {
7614
- const innerIndex = innerIndices.get(innerKey);
7615
- const inner = secondRowItems[innerIndex];
7616
- const keys = [key, innerKey];
7617
- const records = details.get(JSON.stringify(keys));
7618
- if (!records) return;
7619
- if (layout3 !== "tabular")
7620
- append(
7621
- compact ? [label(inner)] : [pivot.repeatLabels ? label(outer) : null, label(inner), null],
7622
- Array(dimensions.width - rowLabelColumns).fill(null),
7623
- { indices: [outerIndex, innerIndex] },
7624
- compact ? 1 : 0
7625
- );
7626
- appendMeasures(
7627
- [pivot.repeatLabels || first2 ? label(outer) : null, label(inner)],
7628
- keys,
7629
- records,
7630
- [outerIndex, innerIndex]
7631
- );
7632
- first2 = false;
7633
- });
7634
- if (bottom)
7635
- appendMeasures([label(outer)], [key], groups.get(key) ?? [], [outerIndex], "default");
7636
- });
7637
- appendMeasures([], [], pivot.records, [0], "grand");
7638
- return {
7639
- values: values2,
7640
- rowItems,
7641
- secondRowItems,
7642
- columnItems,
7643
- rowEntries,
7644
- firstDataRow,
7645
- rowLabelColumns,
7646
- indents,
7647
- firstHeaderRow: 1
7648
- };
7649
- }
7650
-
7651
7425
  // xlsx/write/xml-out.ts
7652
7426
  var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
7653
7427
  var CONTROL = "\0-\b\v\f-" + String.fromCharCode(65534, 65535);
@@ -7687,15 +7461,49 @@ function inlineFragment(xml) {
7687
7461
  return head.includes(MAIN_NS) ? head.replace(MAIN_NS, "") + xml.slice(end) : xml;
7688
7462
  }
7689
7463
 
7464
+ // xlsx/pivot/measures.ts
7465
+ var pivotMeasures = (pivot) => [
7466
+ { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
7467
+ ...pivot.additionalValues ?? []
7468
+ ];
7469
+ var DIV0 = { error: "#DIV/0!" };
7470
+ function variance(numbers3, sample) {
7471
+ const n = numbers3.length;
7472
+ if (n < (sample ? 2 : 1)) return DIV0;
7473
+ const mean2 = numbers3.reduce((total2, value2) => total2 + value2, 0) / n;
7474
+ const squares = numbers3.reduce((total2, value2) => total2 + (value2 - mean2) ** 2, 0);
7475
+ return squares / (sample ? n - 1 : n);
7476
+ }
7477
+ function aggregateValues(records, field, type) {
7478
+ if (!records.length) return null;
7479
+ const values2 = records.map((record) => record[field] ?? null);
7480
+ if (type === "count") return values2.filter((value2) => value2 !== null && value2 !== "").length;
7481
+ if (type === "countNums") return values2.filter((value2) => typeof value2 === "number").length;
7482
+ const error = values2.find(isCellError);
7483
+ if (error) return error;
7484
+ const numbers3 = values2.filter((value2) => typeof value2 === "number");
7485
+ if (type === "var" || type === "varp" || type === "stdDev" || type === "stdDevp") {
7486
+ const result2 = variance(numbers3, type === "var" || type === "stdDev");
7487
+ return typeof result2 === "number" && (type === "stdDev" || type === "stdDevp") ? Math.sqrt(result2) : result2;
7488
+ }
7489
+ if (!numbers3.length) return type === "average" ? DIV0 : 0;
7490
+ if (type === "min") return numbers3.reduce((a2, b) => Math.min(a2, b));
7491
+ if (type === "max") return numbers3.reduce((a2, b) => Math.max(a2, b));
7492
+ if (type === "product") return numbers3.reduce((total2, value2) => total2 * value2, 1);
7493
+ const sum3 = numbers3.reduce((total2, value2) => total2 + value2, 0);
7494
+ return type === "average" ? sum3 / numbers3.length : sum3;
7495
+ }
7496
+ var pivotMeasureNumber = (pivot, records, measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), measure.aggregate);
7497
+
7690
7498
  // xlsx/pivot/columns.ts
7691
7499
  var SEPARATOR = "";
7692
- var label2 = pivotItemLabel;
7693
7500
  var columnKey = (keys, depth) => keys.slice(0, depth).join(SEPARATOR);
7694
7501
  var recordColumnKeys = (record, indices) => indices.map((index3) => pivotValueKey(record[index3] ?? null));
7695
7502
  function pivotColumnEntries(pivot) {
7696
7503
  const names = pivotColumnFields(pivot);
7697
7504
  const items = names.map((name) => pivotItems(pivot, name));
7698
7505
  const entries = [];
7506
+ const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
7699
7507
  if (names.length) {
7700
7508
  const order = items.map(
7701
7509
  (list) => new Map(list.map((item, index3) => [pivotValueKey(item), index3]))
@@ -7730,7 +7538,9 @@ function pivotColumnEntries(pivot) {
7730
7538
  if (level === names.length - 1) entries.push({ kind: "leaf", ...entry3 });
7731
7539
  else {
7732
7540
  visit(child4[1], level + 1, here.path, here.values, here.keys);
7733
- entries.push({ kind: "subtotal", ...entry3 });
7541
+ const own = functions[level];
7542
+ if (own === "auto") entries.push({ kind: "subtotal", ...entry3 });
7543
+ else for (const fn of own) entries.push({ kind: "subtotal", ...entry3, fn });
7734
7544
  }
7735
7545
  }
7736
7546
  };
@@ -7739,26 +7549,31 @@ function pivotColumnEntries(pivot) {
7739
7549
  entries.push({ kind: "grand", path: [], key: "", values: [] });
7740
7550
  return { names, items, entries };
7741
7551
  }
7742
- function pivotColumnDimensions(pivot, columns, labelColumns) {
7743
- const measures = 1 + (pivot.additionalValues?.length ?? 0);
7552
+ function pivotColumnDimensions(pivot, columns, labelColumns, valuesOnRows = false) {
7553
+ const measures = valuesOnRows ? 1 : 1 + (pivot.additionalValues?.length ?? 0);
7744
7554
  const levels = columns.names.length;
7745
7555
  return {
7746
7556
  rows: (levels ? levels + 1 + Number(measures > 1) : 1) + (pivot.pageFilter ? 2 : 0),
7747
7557
  width: labelColumns + (levels ? columns.entries.length : 1) * measures
7748
7558
  };
7749
7559
  }
7750
- function pivotColumnHeaders(pivot, columns, rowLabels) {
7751
- const measures = pivotMeasures(pivot);
7560
+ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
7561
+ const measures = valuesOnRows ? pivotMeasures(pivot).slice(0, 1) : pivotMeasures(pivot);
7752
7562
  const count2 = measures.length;
7753
7563
  const levels = columns.names.length;
7754
- if (!levels) return [[...rowLabels, ...measures.map((measure) => measure.caption)]];
7564
+ if (!levels)
7565
+ return [
7566
+ [...rowLabels, ...valuesOnRows ? [null] : measures.map((measure) => measure.caption)]
7567
+ ];
7755
7568
  const compact = pivot.layout === "compact";
7756
7569
  const labelColumns = rowLabels.length;
7757
7570
  const width = labelColumns + columns.entries.length * count2;
7758
7571
  const rows = levels + 1 + Number(count2 > 1);
7759
7572
  const grid = Array.from({ length: rows }, () => Array(width).fill(null));
7760
- if (count2 === 1) grid[0][0] = pivot.valueCaption;
7761
- const titles = compact ? ["Column Labels"] : [...columns.names, ...count2 > 1 ? ["Values"] : []];
7573
+ if (count2 === 1 && !valuesOnRows) grid[0][0] = pivot.valueCaption;
7574
+ const caps = pivotCaptions(pivot);
7575
+ const labelOf = pivotItemLabeler(pivot);
7576
+ const titles = compact ? [caps.columnLabels] : [...columns.names, ...count2 > 1 ? [caps.values] : []];
7762
7577
  titles.forEach((title, i2) => {
7763
7578
  grid[0][labelColumns + i2] = title;
7764
7579
  });
@@ -7771,16 +7586,17 @@ function pivotColumnHeaders(pivot, columns, rowLabels) {
7771
7586
  if (entry3.kind === "leaf") {
7772
7587
  entry3.path.forEach((_index, level) => {
7773
7588
  const continued = entry3.path.slice(0, level + 1).every((p, i2) => p === previous[i2]);
7774
- if (!continued) grid[1 + level][at] = label2(entry3.values[level]);
7589
+ if (!continued) grid[1 + level][at] = labelOf(columns.names[level], entry3.values[level]);
7775
7590
  });
7776
7591
  previous = entry3.path;
7777
7592
  if (count2 > 1) measures.forEach((measure, m) => grid[rows - 1][at + m] = measure.caption);
7778
7593
  return;
7779
7594
  }
7780
7595
  const row2 = entry3.kind === "grand" ? 1 : entry3.path.length;
7781
- const name = entry3.kind === "grand" ? "" : String(label2(entry3.values.at(-1)));
7596
+ const name = entry3.kind === "grand" ? "" : String(labelOf(columns.names[entry3.path.length - 1], entry3.values.at(-1)));
7782
7597
  measures.forEach((measure, m) => {
7783
- grid[row2][at + m] = count2 === 1 ? entry3.kind === "grand" ? "Grand Total" : `${name} Total` : entry3.kind === "grand" ? `Total ${measure.caption}` : `${name} ${measure.caption}`;
7598
+ const custom = entry3.fn ? caps.functions[entry3.fn] : void 0;
7599
+ grid[row2][at + m] = custom ? count2 === 1 ? `${name} ${custom}` : `${name} ${custom} of ${measure.field}` : count2 === 1 ? entry3.kind === "grand" ? caps.grandTotal : fillCaption(caps.subtotal, name) : entry3.kind === "grand" ? fillCaption(caps.measureTotal, measure.caption) : `${name} ${measure.caption}`;
7784
7600
  });
7785
7601
  });
7786
7602
  return grid;
@@ -7805,7 +7621,7 @@ function pivotColumnItemsXml(entries, measures, remap) {
7805
7621
  const prefix = sharedPrefix(path2, previous);
7806
7622
  const xs = path2.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`);
7807
7623
  out.push(
7808
- `<i${attrs({ t: entry3.kind === "subtotal" ? "default" : void 0, r: prefix || void 0, i: m || void 0 })}>${xs.join("")}</i>`
7624
+ `<i${attrs({ t: entry3.kind === "subtotal" ? entry3.fn ? PIVOT_SUBTOTALS[entry3.fn].item : "default" : void 0, r: prefix || void 0, i: m || void 0 })}>${xs.join("")}</i>`
7809
7625
  );
7810
7626
  previous = path2;
7811
7627
  }
@@ -7813,7 +7629,6 @@ function pivotColumnItemsXml(entries, measures, remap) {
7813
7629
  }
7814
7630
 
7815
7631
  // xlsx/pivot/nested.ts
7816
- var label3 = pivotItemLabel;
7817
7632
  var MAX_CELLS = 1e6;
7818
7633
  var node = (index3, value2) => ({
7819
7634
  index: index3,
@@ -7825,6 +7640,10 @@ var node = (index3, value2) => ({
7825
7640
  function nestedPivotGrid(pivot) {
7826
7641
  const names = pivotRowFields(pivot);
7827
7642
  const depth = names.length;
7643
+ const valuesAt = pivotValuesIndex(pivot);
7644
+ const onRows = valuesAt >= 0;
7645
+ const levels = depth + (onRows ? 1 : 0);
7646
+ const fieldOf = (level) => !onRows || level < valuesAt ? level : level === valuesAt ? -1 : level - 1;
7828
7647
  const axisItems = names.map((name) => pivotItems(pivot, name));
7829
7648
  const itemIndices = axisItems.map(
7830
7649
  (items) => new Map(items.map((item, index3) => [pivotValueKey(item), index3]))
@@ -7836,125 +7655,170 @@ function nestedPivotGrid(pivot) {
7836
7655
  const compact = layout3 === "compact";
7837
7656
  const tabular = layout3 === "tabular";
7838
7657
  const above = !tabular && (pivot.subtotalPosition ?? "top") === "top";
7839
- const labelColumns = compact ? 1 : depth;
7658
+ const labelColumns = compact ? 1 : levels;
7840
7659
  const measures = pivotMeasures(pivot);
7660
+ const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
7661
+ const caps = pivotCaptions(pivot);
7662
+ const labelOf = pivotItemLabeler(pivot);
7841
7663
  const root = node(0, null);
7842
7664
  for (const record of pivot.records) {
7843
7665
  const keys = recordColumnKeys(record, columnFields);
7844
7666
  let current = root;
7845
- for (let level = -1; level < depth; level++) {
7846
- if (level >= 0) {
7847
- const value2 = record[fieldIndices[level]] ?? null;
7667
+ for (let field = -1; field < depth; field++) {
7668
+ if (field >= 0) {
7669
+ const value2 = record[fieldIndices[field]] ?? null;
7848
7670
  const key = pivotValueKey(value2);
7849
7671
  let child4 = current.children.get(key);
7850
7672
  if (!child4) {
7851
- child4 = node(itemIndices[level].get(key), value2);
7673
+ child4 = node(itemIndices[field].get(key), value2);
7852
7674
  current.children.set(key, child4);
7853
7675
  }
7854
7676
  current = child4;
7855
7677
  }
7856
7678
  current.records.push(record);
7857
- for (let width = 1; width <= keys.length; width++) {
7858
- const key = columnKey(keys, width);
7679
+ for (let width2 = 1; width2 <= keys.length; width2++) {
7680
+ const key = columnKey(keys, width2);
7859
7681
  const list = current.columns.get(key);
7860
7682
  if (list) list.push(record);
7861
7683
  else current.columns.set(key, [record]);
7862
7684
  }
7863
7685
  }
7864
7686
  }
7865
- const dimensions = pivotColumnDimensions(pivot, columns, labelColumns);
7866
- const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
7867
- let rows = 1;
7868
- const count2 = (parent, level) => {
7869
- for (const child4 of parent.children.values()) {
7870
- rows++;
7871
- if (level < depth - 1) {
7872
- const f6 = functions[level];
7873
- rows += f6 === "auto" ? 1 : f6.length;
7874
- count2(child4, level + 1);
7875
- }
7876
- }
7877
- };
7878
- count2(root, 0);
7879
- if ((rows + dimensions.rows) * dimensions.width > MAX_CELLS)
7880
- throw new Error("The PivotTable result is too large.");
7881
- const values2 = pivotColumnHeaders(pivot, columns, compact ? ["Row Labels"] : names);
7882
- const firstDataRow = values2.length;
7883
- const indents = values2.map(() => 0);
7687
+ const dimensions = pivotColumnDimensions(pivot, columns, labelColumns, onRows);
7688
+ const rowTitles = names.map((name) => name);
7689
+ if (onRows) rowTitles.splice(valuesAt, 0, caps.values);
7690
+ let values2 = [];
7691
+ let indents = [];
7884
7692
  const rowEntries = [];
7885
- const blanks = () => Array(dimensions.width - labelColumns).fill(null);
7886
- const bands = (group, run2) => columns.entries.flatMap(
7887
- (entry3) => run2(entry3.kind === "grand" ? group.records : group.columns.get(entry3.key) ?? [])
7888
- );
7889
- const numbers3 = (group) => bands(group, (records) => pivotNumbers(pivot, records));
7890
- const subtotalNumbers = (group, fn) => bands(
7891
- group,
7892
- (records) => measures.map((measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), fn))
7893
- );
7894
- const labelCells = (path2, shown, text2) => {
7693
+ let counting = true;
7694
+ let rowCount = 0;
7695
+ const width = dimensions.width - labelColumns;
7696
+ const blanks = () => Array(width).fill(null);
7697
+ const cells = (group, rowFn, measure) => columns.entries.flatMap((entry3) => {
7698
+ const records = entry3.kind === "grand" ? group.records : group.columns.get(entry3.key) ?? [];
7699
+ const picked = measure === void 0 ? measures : [measures[measure]];
7700
+ if (rowFn && entry3.fn && rowFn !== entry3.fn) return picked.map(() => null);
7701
+ const fn = rowFn ?? entry3.fn;
7702
+ return picked.map(
7703
+ (one2) => fn ? aggregateValues(records, pivot.fields.indexOf(one2.field), fn) : pivotMeasureNumber(pivot, records, one2)
7704
+ );
7705
+ });
7706
+ const labelCells = (path2, shown, level, text2) => {
7895
7707
  if (compact) return [text2];
7896
- const cells = Array(depth).fill(null);
7897
- path2.forEach((value2, level) => {
7898
- if (shown[level]) cells[level] = label3(value2);
7708
+ const row2 = Array(levels).fill(null);
7709
+ path2.labels.forEach((value2, at) => {
7710
+ if (shown[at]) row2[at] = value2;
7899
7711
  });
7900
- cells[path2.length] = text2;
7901
- return cells;
7712
+ row2[level] = text2;
7713
+ return row2;
7902
7714
  };
7903
- const push = (cells, numbersOnRow, entry3, indent) => {
7904
- values2.push([...cells, ...numbersOnRow]);
7715
+ const push = (indent, build2) => {
7716
+ if (counting) {
7717
+ if ((++rowCount + dimensions.rows) * dimensions.width > MAX_CELLS)
7718
+ throw new Error("The PivotTable result is too large.");
7719
+ return;
7720
+ }
7721
+ const [cells2, numbers3, entry3] = build2();
7722
+ values2.push([...cells2, ...numbers3]);
7905
7723
  rowEntries.push(entry3);
7906
7724
  indents.push(compact ? indent : 0);
7907
7725
  };
7908
- const emit = (parent, level, path2, indices, firsts) => {
7909
- const last = level === depth - 1;
7910
- const own = functions[level];
7911
- const children2 = [...parent.children.values()].sort((a2, b) => a2.index - b.index);
7726
+ const entryOf = (indices, measure, type) => ({
7727
+ indices,
7728
+ ...measure !== void 0 ? { measure } : {},
7729
+ ...type ? { type } : {}
7730
+ });
7731
+ const walk = (level, group, measure, path2) => {
7732
+ const field = fieldOf(level);
7733
+ const last = level === levels - 1;
7734
+ const repeated = Array.from(
7735
+ { length: level },
7736
+ (_v, k) => !!pivot.repeatLabels && fieldOf(k) >= 0
7737
+ );
7738
+ const leafShown = (firsts) => repeated.map((repeat, k) => repeat || tabular && firsts.slice(k + 1).every(Boolean));
7739
+ if (field < 0) {
7740
+ measures.forEach((one2, m) => {
7741
+ const here = {
7742
+ labels: [...path2.labels, one2.caption],
7743
+ indices: [...path2.indices, m],
7744
+ firsts: [...path2.firsts, m === 0]
7745
+ };
7746
+ if (last)
7747
+ return push(level, () => [
7748
+ labelCells(path2, leafShown(here.firsts), level, one2.caption),
7749
+ cells(group, void 0, m),
7750
+ entryOf(here.indices, m)
7751
+ ]);
7752
+ if (!tabular)
7753
+ push(level, () => [
7754
+ labelCells(path2, repeated, level, one2.caption),
7755
+ blanks(),
7756
+ entryOf(here.indices, m)
7757
+ ]);
7758
+ walk(level + 1, group, m, here);
7759
+ });
7760
+ return;
7761
+ }
7762
+ const own = functions[field];
7763
+ const valuesAbove = !onRows || valuesAt < level;
7764
+ const showsValue = above && own === "auto" && valuesAbove;
7765
+ const children2 = [...group.children.values()].sort((a2, b) => a2.index - b.index);
7912
7766
  children2.forEach((child4, position) => {
7913
- const here = [...path2, child4.value];
7914
- const at = [...indices, child4.index];
7915
- const firstHere = [...firsts, position === 0];
7916
- const repeated = Array(level).fill(!!pivot.repeatLabels);
7917
- if (last) {
7918
- const shown = repeated.map(
7919
- (repeat, k) => repeat || tabular && firstHere.slice(k + 1).every(Boolean)
7920
- );
7921
- push(labelCells(path2, shown, label3(child4.value)), numbers3(child4), { indices: at }, level);
7922
- return;
7923
- }
7767
+ const here = {
7768
+ labels: [...path2.labels, labelOf(names[field], child4.value)],
7769
+ indices: [...path2.indices, child4.index],
7770
+ firsts: [...path2.firsts, position === 0]
7771
+ };
7772
+ const text2 = labelOf(names[field], child4.value);
7773
+ if (last)
7774
+ return push(level, () => [
7775
+ labelCells(path2, leafShown(here.firsts), level, text2),
7776
+ cells(child4, void 0, measure),
7777
+ entryOf(here.indices, measure)
7778
+ ]);
7924
7779
  if (!tabular)
7925
- push(
7926
- labelCells(path2, repeated, label3(child4.value)),
7927
- own === "auto" && above ? numbers3(child4) : blanks(),
7928
- { indices: at },
7929
- level
7930
- );
7931
- emit(child4, level + 1, here, at, firstHere);
7932
- const caption = String(label3(child4.value));
7780
+ push(level, () => [
7781
+ labelCells(path2, repeated, level, text2),
7782
+ showsValue ? cells(child4, void 0, measure) : blanks(),
7783
+ entryOf(here.indices, measure)
7784
+ ]);
7785
+ walk(level + 1, child4, measure, here);
7786
+ if (field === depth - 1) return;
7787
+ const caption = String(text2);
7788
+ const subtotal = (title, fn, one2) => push(level, () => [
7789
+ labelCells(path2, repeated, level, title),
7790
+ cells(child4, fn, one2),
7791
+ entryOf(here.indices, one2, fn ?? "default")
7792
+ ]);
7933
7793
  if (own === "auto") {
7934
- if (!above)
7935
- push(
7936
- labelCells(path2, repeated, `${caption} Total`),
7937
- numbers3(child4),
7938
- { indices: at, type: "default" },
7939
- level
7940
- );
7794
+ if (showsValue) return;
7795
+ if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0, measure);
7796
+ else measures.forEach((one2, m) => subtotal(`${caption} ${one2.caption}`, void 0, m));
7941
7797
  } else
7942
7798
  for (const fn of own)
7943
- push(
7944
- labelCells(path2, repeated, `${caption} ${PIVOT_SUBTOTALS[fn].label}`),
7945
- subtotalNumbers(child4, fn),
7946
- { indices: at, type: fn },
7947
- level
7948
- );
7799
+ if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn, measure);
7800
+ else
7801
+ measures.forEach(
7802
+ (one2, m) => subtotal(`${caption} ${caps.functions[fn]} of ${one2.field}`, fn, m)
7803
+ );
7949
7804
  });
7950
7805
  };
7951
- emit(root, 0, [], [], []);
7952
- push(
7953
- compact ? ["Grand Total"] : ["Grand Total", ...Array(depth - 1).fill(null)],
7954
- numbers3(root),
7955
- { indices: [0], type: "grand" },
7956
- 0
7957
- );
7806
+ const grand = (text2, measure) => push(0, () => [
7807
+ compact ? [text2] : [text2, ...Array(levels - 1).fill(null)],
7808
+ cells(root, void 0, measure),
7809
+ entryOf([0], measure, "grand")
7810
+ ]);
7811
+ const build = () => {
7812
+ walk(0, root, void 0, { labels: [], indices: [], firsts: [] });
7813
+ if (onRows) measures.forEach((one2, m) => grand(fillCaption(caps.measureTotal, one2.caption), m));
7814
+ else grand(caps.grandTotal);
7815
+ };
7816
+ build();
7817
+ counting = false;
7818
+ values2 = pivotColumnHeaders(pivot, columns, compact ? [caps.rowLabels] : rowTitles, onRows);
7819
+ const firstDataRow = values2.length;
7820
+ indents = values2.map(() => 0);
7821
+ build();
7958
7822
  return {
7959
7823
  values: values2,
7960
7824
  rowItems: axisItems[0],
@@ -7966,105 +7830,15 @@ function nestedPivotGrid(pivot) {
7966
7830
  rowEntries,
7967
7831
  firstDataRow,
7968
7832
  rowLabelColumns: labelColumns,
7969
- indents
7833
+ indents,
7834
+ ...onRows ? { firstHeaderRow: 1 } : {}
7970
7835
  };
7971
7836
  }
7972
7837
 
7973
7838
  // xlsx/pivot/aggregate.ts
7974
7839
  function pivotGrid(pivot) {
7975
7840
  validatePivotFields(pivot);
7976
- return prependPivotPage(pivotDataGrid(pivotPageProjection(pivot)), pivot);
7977
- }
7978
- function pivotDataGrid(pivot) {
7979
- if (pivot.valuesAxis !== "rows") return nestedPivotGrid(pivot);
7980
- if (pivot.secondRowField) return hierarchicalPivotGrid(pivot);
7981
- const rowItems = pivotItems(pivot, pivot.rowField);
7982
- const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
7983
- const compact = pivot.layout === "compact";
7984
- const headings = pivot.layout !== void 0 && pivot.layout !== "tabular";
7985
- const dimensions = pivotHeaderDimensions(pivot, columnItems.length, compact ? 1 : 2);
7986
- const dataRows = (rowItems.length + 1) * (1 + (pivot.additionalValues?.length ?? 0)) + (headings ? rowItems.length : 0);
7987
- if ((dataRows + dimensions.rows) * dimensions.width > 1e6)
7988
- throw new Error("The PivotTable result is too large.");
7989
- const label5 = pivotItemLabel;
7990
- const values2 = pivotHeaders(pivot, columnItems, [compact ? "Row Labels" : pivot.rowField], label5);
7991
- const rowField = pivot.fields.indexOf(pivot.rowField);
7992
- const colField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
7993
- const groups = /* @__PURE__ */ new Map();
7994
- const cells = /* @__PURE__ */ new Map();
7995
- const columns = /* @__PURE__ */ new Map();
7996
- const collect = (map, key, record) => {
7997
- const found = map.get(key);
7998
- if (found) found.push(record);
7999
- else map.set(key, [record]);
8000
- };
8001
- for (const record of pivot.records) {
8002
- const key = pivotValueKey(record[rowField] ?? null);
8003
- collect(groups, key, record);
8004
- if (pivot.columnField) {
8005
- const col = pivotValueKey(record[colField] ?? null);
8006
- collect(columns, col, record);
8007
- collect(cells, JSON.stringify([key, col]), record);
8008
- }
8009
- }
8010
- const firstDataRow = values2.length;
8011
- const measures = pivotMeasures(pivot);
8012
- const rowEntries = [];
8013
- const indents = values2.map(() => 0);
8014
- const append = (caption, bands, index3, grand = false) => {
8015
- measures.forEach((measure, m) => {
8016
- values2.push([
8017
- ...compact ? [grand ? `Total ${measure.caption}` : measure.caption] : [
8018
- grand ? `Total ${measure.caption}` : pivot.repeatLabels || !headings && m === 0 ? caption : null,
8019
- grand ? null : measure.caption
8020
- ],
8021
- ...bands.map((band) => band[m] ?? null)
8022
- ]);
8023
- indents.push(compact && !grand ? 1 : 0);
8024
- rowEntries.push({
8025
- indices: grand ? [0] : [index3, m],
8026
- measure: m,
8027
- ...grand ? { type: "grand" } : {}
8028
- });
8029
- });
8030
- };
8031
- rowItems.forEach((item, index3) => {
8032
- const key = pivotValueKey(item);
8033
- if (headings) {
8034
- values2.push([label5(item), ...Array(dimensions.width - 1).fill(null)]);
8035
- rowEntries.push({ indices: [index3] });
8036
- indents.push(0);
8037
- }
8038
- append(
8039
- label5(item),
8040
- [
8041
- ...columnItems.map(
8042
- (col) => pivotNumbers(pivot, cells.get(JSON.stringify([key, pivotValueKey(col)])) ?? [])
8043
- ),
8044
- pivotNumbers(pivot, groups.get(key) ?? [])
8045
- ],
8046
- index3
8047
- );
8048
- });
8049
- append(
8050
- "Grand Total",
8051
- [
8052
- ...columnItems.map((col) => pivotNumbers(pivot, columns.get(pivotValueKey(col)) ?? [])),
8053
- pivotNumbers(pivot, pivot.records)
8054
- ],
8055
- 0,
8056
- true
8057
- );
8058
- return {
8059
- values: values2,
8060
- rowItems,
8061
- columnItems,
8062
- firstDataRow,
8063
- rowLabelColumns: compact ? 1 : 2,
8064
- indents,
8065
- firstHeaderRow: 1,
8066
- rowEntries
8067
- };
7841
+ return prependPivotPage(nestedPivotGrid(pivotPageProjection(pivot)), pivot);
8068
7842
  }
8069
7843
  function pivotTableAt(sheet, at) {
8070
7844
  return sheet.pivotTables?.find((pivot) => rangeContains(pivot.location, at));
@@ -8074,14 +7848,14 @@ function pivotTableAt(sheet, at) {
8074
7848
  var X14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main";
8075
7849
  var LAYOUT = "http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout";
8076
7850
  var TABLE = {
8077
- pivotTableDefinition: "name cacheId dataCaption dataOnRows dataPosition updatedVersion minRefreshableVersion createdVersion applyNumberFormats applyBorderFormats applyFontFormats applyPatternFormats applyAlignmentFormats applyWidthHeightFormats useAutoFormatting itemPrintTitles indent compact compactData outline outlineData multipleFieldFilters rowGrandTotals colGrandTotals",
7851
+ pivotTableDefinition: "name cacheId dataCaption grandTotalCaption rowHeaderCaption colHeaderCaption dataOnRows dataPosition updatedVersion minRefreshableVersion createdVersion applyNumberFormats applyBorderFormats applyFontFormats applyPatternFormats applyAlignmentFormats applyWidthHeightFormats useAutoFormatting itemPrintTitles indent compact compactData outline outlineData multipleFieldFilters rowGrandTotals colGrandTotals",
8078
7852
  location: "ref firstHeaderRow firstDataRow firstDataCol rowPageCount colPageCount",
8079
7853
  pageFields: "count",
8080
7854
  pageField: "fld item hier",
8081
7855
  pivotFields: "count",
8082
7856
  pivotField: "axis dataField compact outline showAll subtotalTop defaultSubtotal numFmtId sumSubtotal countASubtotal avgSubtotal maxSubtotal minSubtotal productSubtotal countSubtotal stdDevSubtotal stdDevPSubtotal varSubtotal varPSubtotal",
8083
7857
  items: "count",
8084
- item: "x t h",
7858
+ item: "x t h n",
8085
7859
  rowFields: "count",
8086
7860
  colFields: "count",
8087
7861
  field: "x",
@@ -8194,6 +7968,121 @@ function assertPivotRecords(records) {
8194
7968
  );
8195
7969
  }
8196
7970
 
7971
+ // xlsx/pivot/captions-read.ts
7972
+ var ATTRIBUTES = {
7973
+ rowHeaderCaption: "rowLabels",
7974
+ colHeaderCaption: "columnLabels",
7975
+ grandTotalCaption: "grandTotal",
7976
+ dataCaption: "values"
7977
+ };
7978
+ function readPivotCaptionAttributes(root) {
7979
+ const out = {};
7980
+ for (const [attribute2, key] of Object.entries(ATTRIBUTES)) {
7981
+ const text2 = att(root, attribute2);
7982
+ if (text2 !== void 0)
7983
+ out[key] = decodeEscapes(text2);
7984
+ }
7985
+ return out;
7986
+ }
7987
+ function aggregateCaptionsOf(pivot) {
7988
+ const out = {};
7989
+ for (const measure of [
7990
+ { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
7991
+ ...pivot.additionalValues ?? []
7992
+ ]) {
7993
+ const at = measure.caption.indexOf(measure.field);
7994
+ if (at < 0 || measure.caption === measure.field) continue;
7995
+ const template = `${measure.caption.slice(0, at)}{0}${measure.caption.slice(at + measure.field.length)}`;
7996
+ if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[measure.aggregate])
7997
+ out[measure.aggregate] = template;
7998
+ }
7999
+ return Object.keys(out).length ? out : void 0;
8000
+ }
8001
+ var MARK = "";
8002
+ var SENTINELS = {
8003
+ rowLabels: `${MARK}R`,
8004
+ columnLabels: `${MARK}C`,
8005
+ grandTotal: `${MARK}G`,
8006
+ values: `${MARK}V`,
8007
+ all: `${MARK}A`,
8008
+ blank: `${MARK}B`,
8009
+ subtotal: `{0}${MARK}S`,
8010
+ measureTotal: `${MARK}M{0}`,
8011
+ functions: Object.fromEntries(
8012
+ Object.keys(ENGLISH_PIVOT_CAPTIONS.functions).map((fn) => [fn, `${MARK}F${fn}`])
8013
+ ),
8014
+ aggregates: ENGLISH_PIVOT_CAPTIONS.aggregates
8015
+ };
8016
+ function templateOf(cached, arg) {
8017
+ if (!arg || !cached.includes(arg)) return void 0;
8018
+ if (cached.startsWith(arg)) return `{0}${cached.slice(arg.length)}`;
8019
+ if (cached.endsWith(arg)) return `${cached.slice(0, -arg.length)}{0}`;
8020
+ const at = cached.indexOf(arg);
8021
+ return `${cached.slice(0, at)}{0}${cached.slice(at + arg.length)}`;
8022
+ }
8023
+ function inferPivotCaptions(pivot, sheet, named2) {
8024
+ const known = pivotCaptions({ captions: named2 });
8025
+ const probe = { ...SENTINELS };
8026
+ for (const key of Object.keys(named2))
8027
+ if (typeof named2[key] === "string")
8028
+ probe[key] = known[key];
8029
+ const grid = pivotGrid({ ...pivot, captions: probe });
8030
+ const found = /* @__PURE__ */ new Map();
8031
+ const set = (key, value2) => {
8032
+ if (value2 === void 0) return;
8033
+ const before = found.get(key);
8034
+ found.set(key, before === void 0 || before === value2 ? value2 : null);
8035
+ };
8036
+ grid.values.forEach(
8037
+ (line2, r) => line2.forEach((expected, c2) => {
8038
+ if (typeof expected !== "string" || !expected.includes(MARK)) return;
8039
+ const cached = getCell(
8040
+ sheet,
8041
+ pivot.location.start.row + r,
8042
+ pivot.location.start.col + c2
8043
+ )?.value;
8044
+ if (typeof cached !== "string") return;
8045
+ const kind = /\u0001([RCGVASMFB])(\w*)/.exec(expected);
8046
+ if (!kind) return;
8047
+ const at = kind.index;
8048
+ switch (kind[1]) {
8049
+ case "R":
8050
+ return set("rowLabels", cached);
8051
+ case "C":
8052
+ return set("columnLabels", cached);
8053
+ case "G":
8054
+ return set("grandTotal", cached);
8055
+ case "V":
8056
+ return set("values", cached);
8057
+ case "A":
8058
+ return set("all", cached);
8059
+ case "B":
8060
+ return set("blank", cached);
8061
+ case "S":
8062
+ return set("subtotal", templateOf(cached, expected.slice(0, at)));
8063
+ case "M":
8064
+ return set("measureTotal", templateOf(cached, expected.slice(at + 2)));
8065
+ case "F": {
8066
+ const item = expected.slice(0, at - 1);
8067
+ const of = / of (.*)$/.exec(expected.slice(at));
8068
+ const word = cached.slice(item.length + 1, of ? cached.length - of[0].length : void 0);
8069
+ if (cached.startsWith(`${item} `) && (!of || cached.endsWith(of[0])))
8070
+ set(`function:${kind[2]}`, word);
8071
+ }
8072
+ }
8073
+ })
8074
+ );
8075
+ const out = pivotCaptions({ captions: named2 });
8076
+ const functions = { ...out.functions };
8077
+ for (const [key, value2] of found) {
8078
+ if (value2 === null) continue;
8079
+ if (key.startsWith("function:")) functions[key.slice(9)] = value2;
8080
+ else out[key] = value2;
8081
+ }
8082
+ out.functions = functions;
8083
+ return trimmedCaptions(out);
8084
+ }
8085
+
8197
8086
  // xlsx/slicer/read-slicers.ts
8198
8087
  var TABLE_SLICER_URI = "{2F2917AC-EB37-4324-AD4E-5DD8C200BD13}";
8199
8088
  var X152 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main";
@@ -8633,7 +8522,7 @@ function readFieldGroups(fields, names) {
8633
8522
  throw new Error("Unsupported pivot field group");
8634
8523
  const labels = children(list, "s", NS.x).map((node2) => decodeEscapes(att(node2, "v") ?? ""));
8635
8524
  const expected = numberGroupLabels({ start, end, by });
8636
- if (elements(list).length !== labels.length || labels.length !== expected.length || labels.some((label5, i2) => label5 !== expected[i2]))
8525
+ if (elements(list).length !== labels.length || labels.length !== expected.length || labels.some((label2, i2) => label2 !== expected[i2]))
8637
8526
  throw new Error("Unsupported pivot group items");
8638
8527
  groups.push({ field: names[index3] ?? "", start, end, by });
8639
8528
  });
@@ -8711,14 +8600,18 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
8711
8600
  const expected = dateGroupRange(group, serials);
8712
8601
  if (!close(expected.start, start) || !close(expected.end, end))
8713
8602
  throw unsupported("stale range");
8603
+ const localized = {};
8714
8604
  for (const entry3 of list) {
8715
- const labels = dateUnitLabels(entry3.unit, expected, dateGroupDays(group), date1904);
8605
+ const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(group), date1904);
8716
8606
  const node2 = first(first(entry3.node, "fieldGroup", NS.x), "groupItems", NS.x);
8717
8607
  const actual = children(node2, "s", NS.x).map((item) => decodeEscapes(att(item, "v") ?? ""));
8718
- if (att(entry3.node, "name") === void 0 || decodeEscapes(att(entry3.node, "name")) !== dateGroupFieldName(entry3.unit, field) || elements(node2).length !== actual.length || actual.length !== labels.length || actual.some((label5, i2) => label5 !== labels[i2]))
8608
+ const name = decodeEscapes(att(entry3.node, "name") ?? "");
8609
+ if (!name || elements(node2).length !== actual.length || actual.length !== labels.length || actual.some((label2) => !label2) || new Set(actual).size !== actual.length)
8719
8610
  throw unsupported("group items");
8611
+ if (name !== dateGroupFieldName(entry3.unit, field) || actual.some((l, i2) => l !== labels[i2]))
8612
+ localized[entry3.unit] = { name, labels: actual };
8720
8613
  }
8721
- groups.push(group);
8614
+ groups.push(Object.keys(localized).length ? { ...group, localized } : group);
8722
8615
  }
8723
8616
  return groups;
8724
8617
  }
@@ -8771,12 +8664,32 @@ function readItemFilters(fields, names, shared) {
8771
8664
  return filters.length ? filters : void 0;
8772
8665
  }
8773
8666
 
8667
+ // xlsx/pivot/item-names-read.ts
8668
+ function readItemNames(tableFields, names, shared) {
8669
+ const out = [];
8670
+ tableFields.forEach((field, index3) => {
8671
+ const list = first(field, "items", NS.x);
8672
+ if (!list || index3 >= names.length) return;
8673
+ for (const item of children(list, "item", NS.x)) {
8674
+ const name = att(item, "n");
8675
+ if (name === void 0) continue;
8676
+ const at = Number(att(item, "x"));
8677
+ const value2 = shared[index3]?.[at];
8678
+ if (att(item, "t") !== void 0 || !Number.isInteger(at) || value2 === void 0)
8679
+ throw new Error("Unsupported pivot item name");
8680
+ out.push({ field: names[index3], item: value2, name: decodeEscapes(name) });
8681
+ }
8682
+ });
8683
+ return out;
8684
+ }
8685
+
8774
8686
  // xlsx/pivot/values-axis.ts
8775
8687
  function remapPivotRowEntries(entries, axes2) {
8776
8688
  return entries.map(
8777
8689
  (entry3) => entry3.type === "grand" ? entry3 : {
8778
8690
  ...entry3,
8779
8691
  indices: entry3.indices.map((item, axis) => {
8692
+ if (axes2[axis] === null) return item;
8780
8693
  const index3 = axes2[axis]?.[item];
8781
8694
  if (index3 === void 0) throw new Error("Invalid report row axis item");
8782
8695
  return index3;
@@ -8795,7 +8708,7 @@ function pivotValueIndex(root, axis) {
8795
8708
  const position = root.getAttribute("dataPosition");
8796
8709
  if (position !== null && (!/^\d+$/.test(position.trim()) || Number(position) !== index3))
8797
8710
  throw new Error("Inconsistent Values axis position");
8798
- if (axis.length === 3 && index3 >= 0 && index3 < 2 && position === null)
8711
+ if (index3 >= 0 && index3 < axis.length - 1 && position === null)
8799
8712
  throw new Error("Missing leading or between-field Values position");
8800
8713
  return index3;
8801
8714
  }
@@ -8810,7 +8723,7 @@ function pivotValueAxisItems(measures) {
8810
8723
  function supportedPivotAxes(rows, columns, measures, valuesOnRows) {
8811
8724
  const index3 = pivotFieldIndex;
8812
8725
  if (valuesOnRows)
8813
- return measures > 1 && (rows.length === 2 || rows.length === 3) && (index3(rows[0]) >= 0 || rows.length === 3) && rows.filter((field) => index3(field) === -2).length === 1 && rows.filter((field) => index3(field) !== -2).every((field) => index3(field) >= 0) && columns.length <= 1 && (!columns.length || index3(columns[0]) >= 0);
8726
+ return measures > 1 && rows.length > 1 && rows.filter((field) => index3(field) === -2).length === 1 && rows.filter((field) => index3(field) !== -2).every((field) => index3(field) >= 0) && columns.every((field) => index3(field) >= 0);
8814
8727
  if (rows.some((field) => !Number.isInteger(index3(field)) || index3(field) < 0)) return false;
8815
8728
  if (measures > 1 && (!columns.length || index3(columns.at(-1)) !== -2)) return false;
8816
8729
  return (measures > 1 ? columns.slice(0, -1) : columns).every(
@@ -8872,6 +8785,9 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8872
8785
  literals(cache2);
8873
8786
  literals(recordRoot);
8874
8787
  const cacheFields = children(first(cache2, "cacheFields", NS.x), "cacheField", NS.x);
8788
+ const all2 = expandDateGroups(pivot).fields;
8789
+ const derived = all2.slice(pivot.fields.length).map((name) => groupLabelsOf(pivot, name) ?? []);
8790
+ const sharedAll = [...shared, ...derived];
8875
8791
  if (pivot.columnField) {
8876
8792
  const column2 = children(first(root, "pivotFields", NS.x), "pivotField", NS.x)[pivot.fields.indexOf(pivot.columnField)];
8877
8793
  const list = first(column2, "extLst", NS.x);
@@ -8890,13 +8806,13 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8890
8806
  ))
8891
8807
  throw new Error("Repeated report column labels are preserved");
8892
8808
  }
8893
- if (integer(first(cache2, "cacheFields", NS.x)?.getAttribute("count") ?? null) !== pivot.fields.length || integer(cache2.getAttribute("recordCount")) !== pivot.records.length || integer(recordRoot.getAttribute("count")) !== pivot.records.length)
8809
+ if (integer(first(cache2, "cacheFields", NS.x)?.getAttribute("count") ?? null) !== all2.length || integer(cache2.getAttribute("recordCount")) !== pivot.records.length || integer(recordRoot.getAttribute("count")) !== pivot.records.length)
8894
8810
  throw new Error("Inconsistent report cache counts");
8895
8811
  for (const name of [...pivotRowFields(pivot), pivot.columnField, pivot.pageFilter.field].filter(
8896
8812
  Boolean
8897
8813
  )) {
8898
- const field = pivot.fields.indexOf(name);
8899
- if (integer(first(cacheFields[field], "sharedItems", NS.x)?.getAttribute("count") ?? null) !== shared[field].length)
8814
+ const field = all2.indexOf(name);
8815
+ if (field < pivot.fields.length && integer(first(cacheFields[field], "sharedItems", NS.x)?.getAttribute("count") ?? null) !== shared[field].length)
8900
8816
  throw new Error("Inconsistent report shared-item counts");
8901
8817
  }
8902
8818
  for (const name of ["rowFields", "colFields"]) {
@@ -8906,7 +8822,7 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8906
8822
  }
8907
8823
  const projected = pivotPageProjection(pivot), fields = children(first(root, "pivotFields", NS.x), "pivotField", NS.x);
8908
8824
  const axisValues = (name, axis) => {
8909
- const f6 = pivot.fields.indexOf(name), node2 = fields[f6], list = first(node2, "items", NS.x), items = children(list, "item", NS.x), count2 = shared[f6].length;
8825
+ const f6 = all2.indexOf(name), node2 = fields[f6], list = first(node2, "items", NS.x), items = children(list, "item", NS.x), count2 = sharedAll[f6].length;
8910
8826
  if (node2.getAttribute("axis") !== axis) throw new Error("Inconsistent report axis field");
8911
8827
  const defaults = node2.getAttribute("defaultSubtotal") !== "0";
8912
8828
  if (!list || integer(list.getAttribute("count")) !== items.length || items.length !== count2 + Number(defaults))
@@ -8915,7 +8831,7 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8915
8831
  const i2 = integer(item.getAttribute("x"));
8916
8832
  if (item.hasAttribute("t") || !Number.isInteger(i2) || i2 >= count2)
8917
8833
  throw new Error("Invalid page-axis cache item");
8918
- return shared[f6][i2];
8834
+ return sharedAll[f6][i2];
8919
8835
  });
8920
8836
  if (new Set(data.map(pivotValueKey)).size !== count2 || defaults && (items.at(-1)?.getAttribute("t") !== "default" || items.at(-1)?.hasAttribute("x")))
8921
8837
  throw new Error("Invalid page-axis default item");
@@ -8930,7 +8846,10 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8930
8846
  };
8931
8847
  const rowAxes = pivotRowFields(pivot).map((name) => axisValues(name, "axisRow")), rowItems = read("rowItems");
8932
8848
  const grid = pivotGrid(pivot);
8933
- const entries = grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, rowAxes) : [
8849
+ const valuesAt = pivotValuesIndex(pivot);
8850
+ const levelAxes = [...rowAxes];
8851
+ if (valuesAt >= 0) levelAxes.splice(valuesAt, 0, null);
8852
+ const entries = grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, levelAxes) : [
8934
8853
  ...rowAxes[0].map((index3) => ({ indices: [index3] })),
8935
8854
  { indices: [0], type: "grand" }
8936
8855
  ];
@@ -8940,11 +8859,11 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8940
8859
  const expected2 = entries[i2];
8941
8860
  const xs = children(item, "x", NS.x).map((x) => integer(x.getAttribute("v"), 0)), prefix = integer(item.getAttribute("r"), 0);
8942
8861
  const type = expected2.type === void 0 || expected2.type === "default" || expected2.type === "grand" ? expected2.type : PIVOT_SUBTOTALS[expected2.type].item;
8943
- if (item.getAttribute("t") !== (type ?? null) || !Number.isInteger(prefix) || prefix < 0 || prefix > previousRow.length || prefix >= expected2.indices.length || expected2.type === "grand" && prefix !== 0 || integer(item.getAttribute("i"), 0) !== 0 || JSON.stringify([...previousRow.slice(0, prefix), ...xs]) !== JSON.stringify(expected2.indices))
8862
+ if (item.getAttribute("t") !== (type ?? null) || !Number.isInteger(prefix) || prefix < 0 || prefix > previousRow.length || prefix >= expected2.indices.length || expected2.type === "grand" && prefix !== 0 || integer(item.getAttribute("i"), 0) !== (expected2.measure ?? 0) || JSON.stringify([...previousRow.slice(0, prefix), ...xs]) !== JSON.stringify(expected2.indices))
8944
8863
  throw new Error("Unmodeled page row item");
8945
8864
  previousRow = expected2.type === "grand" ? [] : expected2.indices;
8946
8865
  });
8947
- const measures = 1 + (pivot.additionalValues?.length ?? 0), columns = pivot.columnField ? axisValues(pivot.columnField, "axisCol") : void 0, expected = [];
8866
+ const measures = valuesAt >= 0 ? 1 : 1 + (pivot.additionalValues?.length ?? 0), columns = pivot.columnField ? axisValues(pivot.columnField, "axisCol") : void 0, expected = [];
8948
8867
  if (columns)
8949
8868
  for (const col of columns)
8950
8869
  for (let m = 0; m < measures; m++) expected.push(measures > 1 ? [col, m] : [col]);
@@ -8986,6 +8905,10 @@ function value(node2, date1904 = false) {
8986
8905
  if (node2.localName === "e" && isErrorCode(v)) return { error: v };
8987
8906
  throw new Error("Unsupported pivot cache item");
8988
8907
  }
8908
+ var namedAggregates = (pivot) => {
8909
+ const aggregates = aggregateCaptionsOf(pivot);
8910
+ return aggregates ? { aggregates } : {};
8911
+ };
8989
8912
  function readOne(workbook, source2, part) {
8990
8913
  const xml = source2.text(part);
8991
8914
  const root = parseXml(xml).documentElement;
@@ -9051,7 +8974,7 @@ function readOne(workbook, source2, part) {
9051
8974
  "dataField",
9052
8975
  NS.x
9053
8976
  );
9054
- if (rowFields.length < 1 || rowsAxis && rowFields.length > 3 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
8977
+ if (rowFields.length < 1 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
9055
8978
  throw new Error("Unsupported pivot layout");
9056
8979
  const valueIndex = pivotValueIndex(root, rowsAxis ? rowFields : colFields);
9057
8980
  const measure = dataFields[0];
@@ -9121,8 +9044,8 @@ function readOne(workbook, source2, part) {
9121
9044
  const col = columnNames[0];
9122
9045
  const moreColumns = columnNames.slice(1);
9123
9046
  const columnDefinitions = columnDefs.map((field) => tableFields[Number(att(field, "x"))]);
9124
- if (fieldSubtotalsOf(columnDefinitions.slice(0, -1), columnNames.slice(0, -1)).length || columnNames.some((name) => !name))
9125
- throw new Error("Column subtotal settings are preserved");
9047
+ if (columnNames.some((name) => !name)) throw new Error("Invalid pivot column fields");
9048
+ const columnSubtotals = fieldSubtotalsOf(columnDefinitions, columnNames);
9126
9049
  const data = names[Number(att(measure, "fld"))];
9127
9050
  const location = parseRange(att(first(root, "location", NS.x), "ref") ?? "");
9128
9051
  if (!row2 || !data || !location || hasColumn && !col || realRows.length === 2 && !second)
@@ -9132,6 +9055,7 @@ function readOne(workbook, source2, part) {
9132
9055
  location.start.row -= 2;
9133
9056
  }
9134
9057
  const itemFilters = readItemFilters(tableFields, names, shared);
9058
+ const itemNames = readItemNames(tableFields, names, shared);
9135
9059
  const slicerCacheId = readSlicerCacheId(cache2);
9136
9060
  const fieldGroups = readFieldGroups(fields, names);
9137
9061
  const dateFields = readDateFields(fields, names);
@@ -9163,11 +9087,14 @@ function readOne(workbook, source2, part) {
9163
9087
  ]);
9164
9088
  if (dateFields.some((field) => onAxis.has(field)))
9165
9089
  throw new Error("Date fields used as rows, columns or values are preserved");
9166
- if ([...realRows, ...columnDefs].some((field) => pivotFieldIndex(field) >= databaseCount) && (pageFilter || dateFilter || itemFilters || slicerCacheId !== void 0))
9167
- throw new Error("Date groups with filters are preserved");
9090
+ const fieldSubtotals = [
9091
+ ...subtotalSettings.filter((entry4) => entry4.field !== row2 || entry4.functions.length),
9092
+ ...columnSubtotals
9093
+ ];
9168
9094
  const pivot = {
9169
9095
  ...pageFilter ? { pageFilter } : {},
9170
9096
  ...itemFilters ? { itemFilters } : {},
9097
+ ...itemNames.length ? { itemNames } : {},
9171
9098
  ...fieldGroups.length ? { fieldGroups } : {},
9172
9099
  ...dateFields.length ? { dateFields } : {},
9173
9100
  ...dateGroups.length ? { dateGroups } : {},
@@ -9179,13 +9106,11 @@ function readOne(workbook, source2, part) {
9179
9106
  rowField: row2,
9180
9107
  layout: layout3,
9181
9108
  ...rowsAxis ? { valuesAxis: "rows" } : {},
9182
- ...rowsAxis && realRows.length === 2 && valueIndex < 2 ? { valuesPosition: valueIndex === 0 ? "first" : "between" } : {},
9183
- subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
9184
- ...subtotalSettings.some((entry4) => entry4.field !== row2 || entry4.functions.length) ? {
9185
- fieldSubtotals: subtotalSettings.filter(
9186
- (entry4) => entry4.field !== row2 || entry4.functions.length
9187
- )
9109
+ ...rowsAxis && valueIndex < realRows.length ? {
9110
+ valuesPosition: valueIndex === 0 ? "first" : valueIndex === 1 && realRows.length === 2 ? "between" : valueIndex
9188
9111
  } : {},
9112
+ subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
9113
+ ...fieldSubtotals.length ? { fieldSubtotals } : {},
9189
9114
  ...more.length ? { moreRowFields: more } : {},
9190
9115
  ...second ? { secondRowField: second, subtotals: subtotal, repeatLabels: repeat[0] ?? false } : {
9191
9116
  ...subtotal ? {} : { subtotals: false },
@@ -9212,6 +9137,12 @@ function readOne(workbook, source2, part) {
9212
9137
  ...col ? { columnField: col } : {},
9213
9138
  ...moreColumns.length ? { moreColumnFields: moreColumns } : {}
9214
9139
  };
9140
+ const captions = trimmedCaptions(
9141
+ pivotCaptions({
9142
+ captions: { ...readPivotCaptionAttributes(root), ...namedAggregates(pivot) }
9143
+ })
9144
+ );
9145
+ if (captions) pivot.captions = captions;
9215
9146
  if (pageFilter && moreColumns.length) throw new Error("Report filters support one column field");
9216
9147
  assertPageAxisItems(root, pivot, shared, cache2, recordRoot);
9217
9148
  return pivot;
@@ -9239,6 +9170,12 @@ function readPivotTables(workbook, source2, warn, slicers) {
9239
9170
  if (slicers.blocked.has(pivotKey(sheet.sheetId, name)) || cache2 && (caches2.get(cache2) ?? 0) > 1)
9240
9171
  throw new Error("Shared pivot cache or unsupported slicer connection");
9241
9172
  const pivot = readOne(workbook, source2, part);
9173
+ const inferred = inferPivotCaptions(pivot, sheet, {
9174
+ ...readPivotCaptionAttributes(parseXml(pivot.sourceXml).documentElement),
9175
+ ...namedAggregates(pivot)
9176
+ });
9177
+ if (inferred) pivot.captions = inferred;
9178
+ else delete pivot.captions;
9242
9179
  const grid = pivotGrid(pivot);
9243
9180
  if (grid.values.length !== pivot.location.end.row - pivot.location.start.row + 1 || grid.values[0].length !== pivot.location.end.col - pivot.location.start.col + 1 || grid.values.some(
9244
9181
  (line2, r) => line2.some(
@@ -9999,7 +9936,7 @@ function mergeSpacedAreas(tokens2) {
9999
9936
  }
10000
9937
  return out;
10001
9938
  }
10002
- function templateOf(formula) {
9939
+ function templateOf2(formula) {
10003
9940
  const cached = templates.get(formula);
10004
9941
  if (cached !== void 0) return cached;
10005
9942
  const raw2 = safeTokens(formula);
@@ -10029,7 +9966,7 @@ function templateOf(formula) {
10029
9966
  return template;
10030
9967
  }
10031
9968
  function rewriteTemplate(formula, rewrite2) {
10032
- const template = templateOf(formula);
9969
+ const template = templateOf2(formula);
10033
9970
  if (!template) return formula;
10034
9971
  let next;
10035
9972
  for (let i2 = 0; i2 < template.length; i2++) {
@@ -10611,8 +10548,8 @@ function parseDiagramDataModel(source2, part) {
10611
10548
  "CONNECTION_ENDPOINT_MISSING",
10612
10549
  `dgm:cxn ${attribute2} references missing point: ${id}.`
10613
10550
  );
10614
- const label5 = connectionLabel(connection, transitionText);
10615
- connections.push(label5 ? { ...connection, label: label5 } : connection);
10551
+ const label2 = connectionLabel(connection, transitionText);
10552
+ connections.push(label2 ? { ...connection, label: label2 } : connection);
10616
10553
  if ((!connection.type || connection.type === "parOf") && !parentById.has(connection.destId))
10617
10554
  parentById.set(connection.destId, connection.sourceId);
10618
10555
  }
@@ -10651,14 +10588,14 @@ function colorList(container2) {
10651
10588
  }
10652
10589
  function parseDiagramColors(source2) {
10653
10590
  const root = rootOf2(source2);
10654
- const labels = children(root, "styleLbl", NS.dgm).map((label5) => ({
10655
- name: stringAttribute(label5, "name") ?? "",
10656
- fill: colorList(first(label5, "fillClrLst", NS.dgm)),
10657
- line: colorList(first(label5, "linClrLst", NS.dgm)),
10658
- effect: colorList(first(label5, "effectClrLst", NS.dgm)),
10659
- textLine: colorList(first(label5, "txLinClrLst", NS.dgm)),
10660
- textFill: colorList(first(label5, "txFillClrLst", NS.dgm)),
10661
- textEffect: colorList(first(label5, "txEffectClrLst", NS.dgm))
10591
+ const labels = children(root, "styleLbl", NS.dgm).map((label2) => ({
10592
+ name: stringAttribute(label2, "name") ?? "",
10593
+ fill: colorList(first(label2, "fillClrLst", NS.dgm)),
10594
+ line: colorList(first(label2, "linClrLst", NS.dgm)),
10595
+ effect: colorList(first(label2, "effectClrLst", NS.dgm)),
10596
+ textLine: colorList(first(label2, "txLinClrLst", NS.dgm)),
10597
+ textFill: colorList(first(label2, "txFillClrLst", NS.dgm)),
10598
+ textEffect: colorList(first(label2, "txEffectClrLst", NS.dgm))
10662
10599
  }));
10663
10600
  return { ...parseDefinitionHeader(root), labels };
10664
10601
  }
@@ -10691,16 +10628,16 @@ function parseStyleReferences(style2) {
10691
10628
  var hasContent = (element2) => Boolean(element2 && (element2.attributes.length > 0 || elements(element2).length > 0));
10692
10629
  function parseDiagramQuickStyle(source2) {
10693
10630
  const root = rootOf2(source2);
10694
- const labels = children(root, "styleLbl", NS.dgm).map((label5) => ({
10695
- name: stringAttribute(label5, "name") ?? "",
10696
- ...parseStyleReferences(first(label5, "style", NS.dgm)),
10697
- hasScene3d: Boolean(first(label5, "scene3d", NS.dgm)),
10698
- hasShape3d: hasContent(first(label5, "sp3d", NS.dgm))
10631
+ const labels = children(root, "styleLbl", NS.dgm).map((label2) => ({
10632
+ name: stringAttribute(label2, "name") ?? "",
10633
+ ...parseStyleReferences(first(label2, "style", NS.dgm)),
10634
+ hasScene3d: Boolean(first(label2, "scene3d", NS.dgm)),
10635
+ hasShape3d: hasContent(first(label2, "sp3d", NS.dgm))
10699
10636
  }));
10700
10637
  return {
10701
10638
  ...parseDefinitionHeader(root),
10702
10639
  labels,
10703
- has3d: labels.some((label5) => label5.hasShape3d)
10640
+ has3d: labels.some((label2) => label2.hasShape3d)
10704
10641
  };
10705
10642
  }
10706
10643
  function parseDiagramLayoutSummary(source2) {
@@ -12377,10 +12314,10 @@ function parseDisplayUnits(context, element2) {
12377
12314
  if (!element2) return void 0;
12378
12315
  reportUnmodelled(context, element2, DISPLAY_UNITS);
12379
12316
  const labelElement = cChild(element2, "dispUnitsLbl");
12380
- let label5;
12317
+ let label2;
12381
12318
  if (labelElement) {
12382
12319
  reportUnmodelled(context, labelElement, DISPLAY_UNITS_LABEL);
12383
- label5 = assignDefined(
12320
+ label2 = assignDefined(
12384
12321
  {},
12385
12322
  {
12386
12323
  layout: manualLayout(labelElement),
@@ -12395,7 +12332,7 @@ function parseDisplayUnits(context, element2) {
12395
12332
  {
12396
12333
  builtInUnit: cVal(element2, "builtInUnit"),
12397
12334
  customUnit: cNumber(context, element2, "custUnit"),
12398
- label: label5,
12335
+ label: label2,
12399
12336
  extLst: extensionList(element2)
12400
12337
  }
12401
12338
  );
@@ -13991,8 +13928,8 @@ function parseTable(xml, partName) {
13991
13928
  if (id !== void 0 && Number.isInteger(id) && id >= 0) column2.sourceId = id;
13992
13929
  const fn = att(node2, "totalsRowFunction");
13993
13930
  if (fn && fn !== "none") column2.totalsRowFunction = fn;
13994
- const label5 = att(node2, "totalsRowLabel");
13995
- if (label5 !== void 0) column2.totalsRowLabel = label5;
13931
+ const label2 = att(node2, "totalsRowLabel");
13932
+ if (label2 !== void 0) column2.totalsRowLabel = label2;
13996
13933
  const calculated = xFirst(node2, "calculatedColumnFormula");
13997
13934
  if (calculated) column2.calculatedColumnFormula = stripFuturePrefixes(xText(calculated));
13998
13935
  return column2;
@@ -14876,10 +14813,10 @@ function titleXml(context, title) {
14876
14813
  function labelOptionsXml(context, options) {
14877
14814
  return numberFormatXml(options.numberFormat) + shapePropertiesXml(context, options.spPr) + textBodyXml(context, options.txPr) + valXml("dLblPos", options.position) + valXml("showLegendKey", options.showLegendKey) + valXml("showVal", options.showValue) + valXml("showCatName", options.showCategoryName) + valXml("showSerName", options.showSeriesName) + valXml("showPercent", options.showPercent) + valXml("showBubbleSize", options.showBubbleSize) + (options.separator === void 0 ? "" : textElement("separator", options.separator));
14878
14815
  }
14879
- function labelXml(context, label5) {
14816
+ function labelXml(context, label2) {
14880
14817
  return elementXml(
14881
14818
  "dLbl",
14882
- valXml("idx", label5.index) + valXml("delete", label5.deleted) + layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + labelOptionsXml(context, label5) + raw(context, label5.extLst)
14819
+ valXml("idx", label2.index) + valXml("delete", label2.deleted) + layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + labelOptionsXml(context, label2) + raw(context, label2.extLst)
14883
14820
  );
14884
14821
  }
14885
14822
  function dataLabelsXml(context, labels) {
@@ -14887,7 +14824,7 @@ function dataLabelsXml(context, labels) {
14887
14824
  const leaderLines = labels.leaderLines ? elementXml("leaderLines", shapePropertiesXml(context, labels.leaderLines.spPr)) : "";
14888
14825
  return elementXml(
14889
14826
  "dLbls",
14890
- labels.labels.map((label5) => labelXml(context, label5)).join("") + valXml("delete", labels.deleted) + labelOptionsXml(context, labels) + valXml("showLeaderLines", labels.showLeaderLines) + leaderLines + raw(context, labels.extLst)
14827
+ labels.labels.map((label2) => labelXml(context, label2)).join("") + valXml("delete", labels.deleted) + labelOptionsXml(context, labels) + valXml("showLeaderLines", labels.showLeaderLines) + leaderLines + raw(context, labels.extLst)
14891
14828
  );
14892
14829
  }
14893
14830
 
@@ -14908,12 +14845,12 @@ function dataTableXml(context, table2) {
14908
14845
  }
14909
14846
  function displayUnitsXml(context, units) {
14910
14847
  if (!units) return "";
14911
- const label5 = units.label;
14848
+ const label2 = units.label;
14912
14849
  return elementXml(
14913
14850
  "dispUnits",
14914
- valXml("custUnit", units.customUnit) + (units.customUnit === void 0 ? valXml("builtInUnit", units.builtInUnit) : "") + (label5 ? elementXml(
14851
+ valXml("custUnit", units.customUnit) + (units.customUnit === void 0 ? valXml("builtInUnit", units.builtInUnit) : "") + (label2 ? elementXml(
14915
14852
  "dispUnitsLbl",
14916
- layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + shapePropertiesXml(context, label5.spPr) + textBodyXml(context, label5.txPr)
14853
+ layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + shapePropertiesXml(context, label2.spPr) + textBodyXml(context, label2.txPr)
14917
14854
  ) : "") + raw(context, units.extLst)
14918
14855
  );
14919
14856
  }
@@ -14938,11 +14875,11 @@ function axisXml(context, axis) {
14938
14875
  }
14939
14876
 
14940
14877
  // chart/write-analysis.ts
14941
- function trendlineLabelXml(context, label5) {
14942
- if (!label5) return "";
14878
+ function trendlineLabelXml(context, label2) {
14879
+ if (!label2) return "";
14943
14880
  return elementXml(
14944
14881
  "trendlineLbl",
14945
- layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + numberFormatXml(label5.numberFormat) + shapePropertiesXml(context, label5.spPr) + textBodyXml(context, label5.txPr) + raw(context, label5.extLst)
14882
+ layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + numberFormatXml(label2.numberFormat) + shapePropertiesXml(context, label2.spPr) + textBodyXml(context, label2.txPr) + raw(context, label2.extLst)
14946
14883
  );
14947
14884
  }
14948
14885
  function trendlineXml(context, trendline) {
@@ -16959,14 +16896,14 @@ function unique(args, ctx) {
16959
16896
  const byCol = args.length > 1 && args[1] !== null && toBool(ctx.toScalar(args[1] ?? null));
16960
16897
  const once = args.length > 2 && args[2] !== null && toBool(ctx.toScalar(args[2] ?? null));
16961
16898
  if (byCol) m = transpose(m);
16962
- const keyOf2 = (row2) => JSON.stringify(
16899
+ const keyOf3 = (row2) => JSON.stringify(
16963
16900
  row2.map(
16964
16901
  (v) => isError(v) ? `#${v.error}` : typeof v === "string" ? `s${v.toLowerCase()}` : v
16965
16902
  )
16966
16903
  );
16967
16904
  const counts = /* @__PURE__ */ new Map();
16968
16905
  for (const row2 of m.data) {
16969
- const key = keyOf2(row2);
16906
+ const key = keyOf3(row2);
16970
16907
  const entry3 = counts.get(key);
16971
16908
  if (entry3) entry3.count++;
16972
16909
  else counts.set(key, { row: row2, count: 1 });
@@ -17251,11 +17188,11 @@ function gammaLn(z) {
17251
17188
 
17252
17189
  // xlsx/formula/functions/database.ts
17253
17190
  var C3 = "Database";
17254
- var label4 = (value2) => value2 === null ? "" : typeof value2 === "string" ? value2 : String(value2);
17191
+ var label = (value2) => value2 === null ? "" : typeof value2 === "string" ? value2 : String(value2);
17255
17192
  function tableOf(ctx, value2) {
17256
17193
  const [head, ...records] = ctx.toMatrix(value2 ?? null).data;
17257
17194
  if (!head || records.length === 0) fail(ERR.VALUE);
17258
- return { headers: head.map((v) => label4(v).toLowerCase()), records };
17195
+ return { headers: head.map((v) => label(v).toLowerCase()), records };
17259
17196
  }
17260
17197
  function fieldIndex(table2, field) {
17261
17198
  const value2 = scalar2(field);
@@ -17265,7 +17202,7 @@ function fieldIndex(table2, field) {
17265
17202
  if (index4 < 0 || index4 >= table2.headers.length) fail(ERR.VALUE);
17266
17203
  return index4;
17267
17204
  }
17268
- const index3 = table2.headers.indexOf(label4(value2).toLowerCase());
17205
+ const index3 = table2.headers.indexOf(label(value2).toLowerCase());
17269
17206
  if (index3 < 0) fail(ERR.VALUE);
17270
17207
  return index3;
17271
17208
  }
@@ -17274,7 +17211,7 @@ function recordFilter(table2, criteria) {
17274
17211
  if (!head || rows.length === 0) fail(ERR.VALUE);
17275
17212
  const columns = head.map((name) => {
17276
17213
  if (name === null || name === "") return -1;
17277
- return table2.headers.indexOf(label4(name).toLowerCase());
17214
+ return table2.headers.indexOf(label(name).toLowerCase());
17278
17215
  });
17279
17216
  const alternatives = rows.map(
17280
17217
  (row2) => row2.flatMap((cell, c2) => {
@@ -24489,7 +24426,7 @@ function headerMode(args, i2, ctx, firstRow) {
24489
24426
  if (mode === 1 || mode === 3) return true;
24490
24427
  return fail(ERR.VALUE);
24491
24428
  }
24492
- var keyOf = (values2) => JSON.stringify(values2);
24429
+ var keyOf2 = (values2) => JSON.stringify(values2);
24493
24430
  var plain2 = (v) => v === void 0 || isError(v) ? null : v;
24494
24431
  function compareBy(keys, rows) {
24495
24432
  return (a2, b) => {
@@ -24529,7 +24466,7 @@ function groupby(args, ctx) {
24529
24466
  if (rows.length === 0) fail(ERR.CALC);
24530
24467
  const groups = /* @__PURE__ */ new Map();
24531
24468
  for (const r of rows) {
24532
- const key = keyOf(keysM.data[r]);
24469
+ const key = keyOf2(keysM.data[r]);
24533
24470
  const found = groups.get(key);
24534
24471
  if (found) found.push(r);
24535
24472
  else groups.set(key, [r]);
@@ -24596,8 +24533,8 @@ function pivotby(args, ctx) {
24596
24533
  const colKeys = /* @__PURE__ */ new Map();
24597
24534
  for (const r of used) {
24598
24535
  for (const [map, key] of [
24599
- [rowKeys, keyOf(rowsM.data[r])],
24600
- [colKeys, keyOf(colsM.data[r])]
24536
+ [rowKeys, keyOf2(rowsM.data[r])],
24537
+ [colKeys, keyOf2(colsM.data[r])]
24601
24538
  ]) {
24602
24539
  const found = map.get(key);
24603
24540
  if (found) found.push(r);
@@ -27395,15 +27332,15 @@ function derivedFields(pivot, date1904) {
27395
27332
  function derivedFieldXml(pivot, entry3, date1904) {
27396
27333
  const range = { start: entry3.group.start, end: entry3.group.end };
27397
27334
  const days = dateGroupDays(entry3.group);
27398
- const labels = dateUnitLabels(entry3.unit, range, days, date1904);
27335
+ const labels = dateUnitLabels(entry3.unit, range, days, date1904, entry3.group);
27399
27336
  const base = pivot.fields.indexOf(entry3.group.field);
27400
- return `<cacheField${attrs({ name: encodeEscapes(entry3.name), numFmtId: 0, databaseField: false })}><fieldGroup base="${base}"><rangePr${attrs({ autoStart: entry3.autoStart ? void 0 : false, autoEnd: entry3.autoEnd ? void 0 : false, groupBy: entry3.unit, startDate: serialToIso(range.start, date1904), endDate: serialToIso(range.end, date1904), groupInterval: days > 1 ? days : void 0 })}/><groupItems count="${labels.length}">${labels.map((label5) => `<s v="${escapeAttr3(label5)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
27337
+ return `<cacheField${attrs({ name: encodeEscapes(entry3.name), numFmtId: 0, databaseField: false })}><fieldGroup base="${base}"><rangePr${attrs({ autoStart: entry3.autoStart ? void 0 : false, autoEnd: entry3.autoEnd ? void 0 : false, groupBy: entry3.unit, startDate: serialToIso(range.start, date1904), endDate: serialToIso(range.end, date1904), groupInterval: days > 1 ? days : void 0 })}/><groupItems count="${labels.length}">${labels.map((label2) => `<s v="${escapeAttr3(label2)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
27401
27338
  }
27402
27339
  function groupXml2(pivot, name, index3) {
27403
27340
  const group = groupOf(pivot, name);
27404
27341
  if (!group) return "";
27405
27342
  const labels = numberGroupLabels(group);
27406
- return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${group.start}" endNum="${group.end}" groupInterval="${group.by}"/><groupItems count="${labels.length}">${labels.map((label5) => `<s v="${escapeAttr3(label5)}"/>`).join("")}</groupItems></fieldGroup>`;
27343
+ return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${group.start}" endNum="${group.end}" groupInterval="${group.by}"/><groupItems count="${labels.length}">${labels.map((label2) => `<s v="${escapeAttr3(label2)}"/>`).join("")}</groupItems></fieldGroup>`;
27407
27344
  }
27408
27345
  function slicerExt(pivot) {
27409
27346
  if (pivot.slicerCacheId === void 0) return "";
@@ -27424,8 +27361,6 @@ function pivotTableXml(source2, cacheId, cache2) {
27424
27361
  const pivot = expandDateGroups(source2);
27425
27362
  const rowNames = pivotRowFields(pivot);
27426
27363
  const rowIdx = rowNames.map((name) => pivot.fields.indexOf(name));
27427
- const row2 = rowIdx[0];
27428
- const second = rowIdx[1] ?? -1;
27429
27364
  const page = pivot.pageFilter ? pivot.fields.indexOf(pivot.pageFilter.field) : -1;
27430
27365
  const pageItems = page >= 0 ? pivotItems(pivot, pivot.pageFilter.field) : [];
27431
27366
  const filtered2 = filteredFields(pivot);
@@ -27453,7 +27388,10 @@ function pivotTableXml(source2, cacheId, cache2) {
27453
27388
  const columnIndicesFull = columnNames.map(
27454
27389
  (_name, k) => itemIndices(visibleColumns[k], columnItemsFull[k])
27455
27390
  );
27456
- const rowEntries = anyFull && grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, rowIndicesFull) : grid.rowEntries;
27391
+ const valuesAt = pivotValuesIndex(pivot);
27392
+ const levelAxes = [...rowIndicesFull];
27393
+ if (valuesAt >= 0) levelAxes.splice(valuesAt, 0, null);
27394
+ const rowEntries = anyFull && grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, levelAxes) : grid.rowEntries;
27457
27395
  const pageOffset = page >= 0 ? 2 : 0;
27458
27396
  const col = columnIdx[0] ?? -1;
27459
27397
  const measures = pivotMeasures(pivot);
@@ -27462,13 +27400,17 @@ function pivotTableXml(source2, cacheId, cache2) {
27462
27400
  const compact = pivot.layout === "compact";
27463
27401
  const outline = pivot.layout === "compact" || pivot.layout === "outline";
27464
27402
  const top = (pivot.subtotalPosition ?? (outline ? "top" : "bottom")) === "top";
27403
+ const named2 = (field, item) => {
27404
+ const text2 = pivotItemName(pivot, field, item);
27405
+ return text2 === void 0 ? "" : attrs({ n: encodeEscapes(text2) });
27406
+ };
27465
27407
  const fields = pivot.fields.map((name, index3) => {
27466
27408
  const isDate = pivot.dateFields?.includes(name) ?? false;
27467
27409
  const at = rowIdx.indexOf(index3);
27468
27410
  const colAt = columnIdx.indexOf(index3);
27469
27411
  const items2 = index3 === page ? pageItems : at >= 0 ? rowItemsFull[at] : colAt >= 0 ? columnItemsFull[colAt] : groupLabelsOf(pivot, name) ?? (filtered2.has(name) || isDate ? pivotItems(pivot, name) : void 0);
27470
27412
  const hidden = hiddenItemKeys(pivot, name);
27471
- const functions = at >= 0 ? fieldSubtotalFunctions(pivot, name) : "auto";
27413
+ const functions = at >= 0 || colAt >= 0 ? fieldSubtotalFunctions(pivot, name) : "auto";
27472
27414
  const automatic = functions === "auto";
27473
27415
  const custom = automatic ? [] : functions;
27474
27416
  const repeated = pivot.repeatLabels && at >= 0 ? `<extLst><ext uri="{2946ED86-A175-432a-8AC1-64E0C546D7DE}"><x14:pivotField xmlns:x14="${X143}" fillDownLabels="1"/></ext></extLst>` : "";
@@ -27476,37 +27418,27 @@ function pivotTableXml(source2, cacheId, cache2) {
27476
27418
  custom.map((fn) => [PIVOT_SUBTOTALS[fn].attr, true])
27477
27419
  );
27478
27420
  const entries = automatic ? '<item t="default"/>' : custom.map((fn) => `<item t="${PIVOT_SUBTOTALS[fn].item}"/>`).join("");
27479
- return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((measure) => pivot.fields.indexOf(measure.field) === index3) ? true : void 0, compact, outline, showAll: false, subtotalTop: at >= 0 ? top : void 0, numFmtId: isDate ? 14 : void 0, defaultSubtotal: automatic ? void 0 : false, ...flags })}>${items2 ? `<items count="${items2.length + (automatic ? 1 : custom.length)}">${items2.map((item) => `<item${hidden.has(pivotValueKey(item)) ? ' h="1"' : ""} x="${itemX(index3, item)}"/>`).join("")}${entries}</items>` : ""}${repeated}</pivotField>`;
27421
+ return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((measure) => pivot.fields.indexOf(measure.field) === index3) ? true : void 0, compact, outline, showAll: false, subtotalTop: at >= 0 ? top : void 0, numFmtId: isDate ? 14 : void 0, defaultSubtotal: automatic ? void 0 : false, ...flags })}>${items2 ? `<items count="${items2.length + (automatic ? 1 : custom.length)}">${items2.map((item) => `<item${hidden.has(pivotValueKey(item)) ? ' h="1"' : ""}${named2(name, item)} x="${itemX(index3, item)}"/>`).join("")}${entries}</items>` : ""}${repeated}</pivotField>`;
27480
27422
  }).join("");
27481
27423
  const items = (count2, indices) => Array.from({ length: count2 }, (_v, i2) => `<i><x v="${indices?.[i2] ?? i2}"/></i>`).join("") + '<i t="grand"><x/></i>';
27482
27424
  const header = grid.firstHeaderRow !== void 0 ? grid.firstHeaderRow - pageOffset : col >= 0 ? 1 : grid.firstDataRow - pageOffset - 1;
27483
- const rowIndices = rowsAxis && pivot.valuesPosition === "first" ? [-2, row2, second] : rowsAxis && pivot.valuesPosition === "between" ? [row2, -2, second] : [...rowIdx, ...rowsAxis ? [-2] : []];
27425
+ const rowIndices = [...rowIdx];
27426
+ if (valuesAt >= 0) rowIndices.splice(valuesAt, 0, -2);
27484
27427
  let previous = [];
27485
27428
  const rowItems = rowEntries?.map((entry3) => {
27486
27429
  let prefix = 0;
27487
27430
  const type = entry3.type === void 0 || entry3.type === "default" || entry3.type === "grand" ? entry3.type : PIVOT_SUBTOTALS[entry3.type].item;
27488
- if (rowsAxis) {
27489
- if (entry3.type === "default" && pivot.valuesPosition === "first") prefix = 1;
27490
- else if (!entry3.type)
27491
- while (prefix < entry3.indices.length - 1 && entry3.indices[prefix] === previous[prefix])
27492
- prefix++;
27493
- previous = entry3.type && !(entry3.type === "default" && pivot.valuesPosition === "first") ? [] : entry3.indices;
27494
- } else {
27495
- if (entry3.type !== "grand") prefix = sharedPrefix(entry3.indices, previous);
27496
- previous = entry3.type === "grand" ? [] : entry3.indices;
27497
- }
27431
+ if (entry3.type !== "grand") prefix = sharedPrefix(entry3.indices, previous);
27432
+ previous = entry3.type === "grand" ? [] : entry3.indices;
27498
27433
  return `<i${attrs({ t: type, r: prefix || void 0, i: entry3.measure || void 0 })}>${entry3.indices.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`).join("")}</i>`;
27499
27434
  }).join("") ?? items(grid.rowItems.length, rowIndicesFull[0]);
27500
27435
  let body = `<location${attrs({ ref: formatRange({ ...pivot.location, start: { ...pivot.location.start, row: pivot.location.start.row + pageOffset } }), firstHeaderRow: header, firstDataRow: grid.firstDataRow - pageOffset, rowPageCount: page >= 0 ? 1 : void 0, colPageCount: page >= 0 ? 1 : void 0, firstDataCol: grid.rowLabelColumns ?? 1 })}/><pivotFields count="${pivot.fields.length}">${fields}</pivotFields><rowFields count="${rowIndices.length}">${rowIndices.map((index3) => `<field x="${index3}"/>`).join("")}</rowFields><rowItems count="${grid.rowEntries?.length ?? grid.rowItems.length + 1}">${rowItems}</rowItems>`;
27501
- if (!rowsAxis && col >= 0 && grid.columnEntries) {
27502
- const fieldsOnColumns = [...columnIdx, ...multiple ? [-2] : []];
27503
- body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, measures.length, (level, index3) => columnIndicesFull[level][index3])}`;
27436
+ if (col >= 0 && grid.columnEntries) {
27437
+ const fieldsOnColumns = [...columnIdx, ...multiple && !rowsAxis ? [-2] : []];
27438
+ body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, rowsAxis ? 1 : measures.length, (level, index3) => columnIndicesFull[level][index3])}`;
27504
27439
  } else if (multiple && !rowsAxis)
27505
27440
  body += `<colFields count="1"><field x="-2"/></colFields>${pivotValueAxisItems(measures.length)}`;
27506
- else if (col >= 0)
27507
- body += `<colFields count="1"><field x="${col}"/></colFields><colItems count="${grid.columnItems.length + 1}">${items(grid.columnItems.length, columnIndicesFull[0])}</colItems>`;
27508
- else
27509
- body += rowsAxis ? '<colItems count="1"><i/></colItems>' : page >= 0 ? '<colItems count="1"><i/></colItems>' : '<colItems count="1"><i><x/></i></colItems>';
27441
+ else body += '<colItems count="1"><i/></colItems>';
27510
27442
  if (page >= 0)
27511
27443
  body += `<pageFields count="1"><pageField${attrs({ fld: page, hier: -1, item: pivot.pageFilter.item !== void 0 ? pageItems.findIndex((item) => pivotValueKey(item) === pivotValueKey(pivot.pageFilter.item)) : void 0 })}/></pageFields>`;
27512
27444
  body += `<dataFields count="${measures.length}">${measures.map((measure) => `<dataField${attrs({ name: encodeEscapes(measure.caption), fld: pivot.fields.indexOf(measure.field), subtotal: measure.aggregate, baseField: 0, baseItem: 0 })}/>`).join("")}</dataFields>`;
@@ -27516,9 +27448,17 @@ function pivotTableXml(source2, cacheId, cache2) {
27516
27448
  const root = doc.documentElement;
27517
27449
  root.setAttribute("name", pivot.name);
27518
27450
  root.setAttribute("cacheId", String(cacheId));
27451
+ const caps = pivotCaptions(pivot);
27452
+ root.setAttribute("dataCaption", caps.values);
27453
+ for (const [attribute2, key] of [
27454
+ ["rowHeaderCaption", "rowLabels"],
27455
+ ["colHeaderCaption", "columnLabels"],
27456
+ ["grandTotalCaption", "grandTotal"]
27457
+ ])
27458
+ if (caps[key] !== ENGLISH_PIVOT_CAPTIONS[key] || root.hasAttribute(attribute2))
27459
+ root.setAttribute(attribute2, caps[key]);
27519
27460
  root.setAttribute("dataOnRows", rowsAxis ? "1" : "0");
27520
- if (rowsAxis && (pivot.valuesPosition === "between" || pivot.valuesPosition === "first"))
27521
- root.setAttribute("dataPosition", pivot.valuesPosition === "first" ? "0" : "1");
27461
+ if (rowsAxis && valuesAt < rowIdx.length) root.setAttribute("dataPosition", String(valuesAt));
27522
27462
  else root.removeAttribute("dataPosition");
27523
27463
  root.setAttribute("compact", compact ? "1" : "0");
27524
27464
  root.setAttribute("compactData", compact ? "1" : "0");
@@ -27584,7 +27524,8 @@ function pivotTableXml(source2, cacheId, cache2) {
27584
27524
  }
27585
27525
  function dateFilterXml(pivot, filter2) {
27586
27526
  const x15 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main";
27587
- return `<filters count="1"><filter${attrs({ fld: pivot.fields.indexOf(filter2.field), type: "dateBetween", evalOrder: -1, id: 1, name: filter2.field })}><autoFilter ref="A1"><filterColumn colId="0"><customFilters and="1"><customFilter operator="greaterThanOrEqual" val="${Math.floor(filter2.start)}"/><customFilter operator="lessThanOrEqual" val="${Math.floor(filter2.end)}"/></customFilters></filterColumn></autoFilter><extLst><ext uri="{0605FD5F-26C8-4aeb-8148-2DB25E43C511}" xmlns:x15="${x15}"><x15:pivotFilter useWholeDay="1"/></ext></extLst></filter></filters>`;
27527
+ const id = Number(/<filter [^>]*\bid="(\d+)"/.exec(pivot.sourceXml ?? "")?.[1] ?? 1);
27528
+ return `<filters count="1"><filter${attrs({ fld: pivot.fields.indexOf(filter2.field), type: "dateBetween", evalOrder: -1, id, name: filter2.field })}><autoFilter ref="A1"><filterColumn colId="0"><customFilters and="1"><customFilter operator="greaterThanOrEqual" val="${Math.floor(filter2.start)}"/><customFilter operator="lessThanOrEqual" val="${Math.floor(filter2.end)}"/></customFilters></filterColumn></autoFilter><extLst><ext uri="{0605FD5F-26C8-4aeb-8148-2DB25E43C511}" xmlns:x15="${x15}"><x15:pivotFilter useWholeDay="1"/></ext></extLst></filter></filters>`;
27588
27529
  }
27589
27530
 
27590
27531
  // xlsx/pivot/write.ts
@@ -30322,9 +30263,9 @@ function parseSheet(bound, records, start, globals) {
30322
30263
  default: {
30323
30264
  if (opcode === 157)
30324
30265
  hasAutoFilter = true;
30325
- const label5 = UNSUPPORTED[opcode];
30326
- if (label5)
30327
- addUnique(sheet.unsupported, label5);
30266
+ const label2 = UNSUPPORTED[opcode];
30267
+ if (label2)
30268
+ addUnique(sheet.unsupported, label2);
30328
30269
  }
30329
30270
  }
30330
30271
  }