@rowsncolumns/toolkit 24.5.4 → 24.5.6

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 (77) hide show
  1. package/dist/cjs/autofilter-condition.js +6 -2
  2. package/dist/cjs/excel-parser/helpers.d.ts +9 -1
  3. package/dist/cjs/excel-parser/helpers.d.ts.map +1 -1
  4. package/dist/cjs/excel-parser/helpers.js +70 -16
  5. package/dist/cjs/excel-parser/interface.d.ts +9 -1
  6. package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
  7. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  8. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +61 -6
  9. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  10. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +13 -2
  11. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +8 -1
  12. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  13. package/dist/cjs/excel-parser/plugins/xlsx/index.js +159 -26
  14. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  15. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  16. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +25 -14
  17. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -1
  18. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.js +19 -15
  19. package/dist/cjs/excel-parser/types.d.ts +5 -1
  20. package/dist/cjs/excel-parser/types.d.ts.map +1 -1
  21. package/dist/cjs/excel-parser/workbook.d.ts +1 -0
  22. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
  23. package/dist/cjs/excel-parser/workbook.js +4 -0
  24. package/dist/cjs/excel-parser/worker.js +3 -0
  25. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
  26. package/dist/cjs/exporter/xlsx/chart-builder.js +167 -53
  27. package/dist/cjs/exporter/xlsx/future-functions.d.ts +6 -7
  28. package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -1
  29. package/dist/cjs/exporter/xlsx/future-functions.js +5 -261
  30. package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -1
  31. package/dist/cjs/exporter/xlsx/style-builder.js +62 -19
  32. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +10 -2
  33. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  34. package/dist/cjs/exporter/xlsx/xlsx-export.js +404 -158
  35. package/dist/cjs/helpers/excel-formula-prefixes.d.ts +51 -0
  36. package/dist/cjs/helpers/excel-formula-prefixes.d.ts.map +1 -0
  37. package/dist/cjs/helpers/excel-formula-prefixes.js +548 -0
  38. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  39. package/dist/esm/autofilter-condition.js +6 -2
  40. package/dist/esm/excel-parser/helpers.d.ts +9 -1
  41. package/dist/esm/excel-parser/helpers.d.ts.map +1 -1
  42. package/dist/esm/excel-parser/helpers.js +65 -3
  43. package/dist/esm/excel-parser/interface.d.ts +9 -1
  44. package/dist/esm/excel-parser/interface.d.ts.map +1 -1
  45. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  46. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +42 -1
  47. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  48. package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +11 -2
  49. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +8 -1
  50. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  51. package/dist/esm/excel-parser/plugins/xlsx/index.js +109 -4
  52. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  53. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  54. package/dist/esm/excel-parser/plugins/xlsx/styles.js +20 -8
  55. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -1
  56. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.js +13 -9
  57. package/dist/esm/excel-parser/types.d.ts +5 -1
  58. package/dist/esm/excel-parser/types.d.ts.map +1 -1
  59. package/dist/esm/excel-parser/workbook.d.ts +1 -0
  60. package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
  61. package/dist/esm/excel-parser/workbook.js +3 -0
  62. package/dist/esm/excel-parser/worker.js +3 -0
  63. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
  64. package/dist/esm/exporter/xlsx/chart-builder.js +80 -0
  65. package/dist/esm/exporter/xlsx/future-functions.d.ts +6 -7
  66. package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -1
  67. package/dist/esm/exporter/xlsx/future-functions.js +5 -261
  68. package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -1
  69. package/dist/esm/exporter/xlsx/style-builder.js +56 -18
  70. package/dist/esm/exporter/xlsx/xlsx-export.d.ts +10 -2
  71. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  72. package/dist/esm/exporter/xlsx/xlsx-export.js +338 -106
  73. package/dist/esm/helpers/excel-formula-prefixes.d.ts +51 -0
  74. package/dist/esm/helpers/excel-formula-prefixes.d.ts.map +1 -0
  75. package/dist/esm/helpers/excel-formula-prefixes.js +531 -0
  76. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  77. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
1
  import { __assign, __awaiter, __generator, __read, __spreadArray, __values } from "tslib";
2
- import { cellRangeToAddress, cellToAddress, escapeCharacters, getCellEffectiveFormat, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredFormat, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, sortSheetsByIndex, } from "@rowsncolumns/utils";
2
+ import { cellRangeToAddress, cellToAddress, escapeCharacters, getCellEffectiveFormat, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredFormat, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, sortSheetsByIndex, conditionOperandToFormulaText, } from "@rowsncolumns/utils";
3
3
  import { zipSync } from "fflate";
4
4
  import { omitInvalidDataValidationError } from "../invalid-data-validation";
5
5
  import { buildAutoFilterCriteriaXml } from "../../autofilter-condition";
@@ -31,10 +31,10 @@ var pixelToPoints = function (px) {
31
31
  return Math.max(1, Number(((px * 72) / 96).toFixed(2)));
32
32
  };
33
33
  export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
34
- var sortedSheets, sharedStrings, personRegistry, styleBuilder, customTableStyleRecords, customTableStyleNames, exportableTables, tableIdMap, preparedTables, chartCount, embedsBySheet, textBoxesBySheet, shapesBySheet, formControlsBySheet, ctrlProps, chartsBySheet, remappedSlicers, slicersBySheet, workbookSheetNames, sheetNameById, dataValidationsById, globalSlicerIndex, slicerCacheEntries, slicerEntries, globalPivotIndex, pivotCacheEntries, pivotCacheRelsEntries, pivotTableEntries, pivotTableRelsEntries, pivotSourceNameById, _loop_1, pivotTables_1, pivotTables_1_1, p, resolvePivotSourceName, pivotsByTargetSheet, pivotTables_2, pivotTables_2_1, p, sid, list, workbookPivotCacheRefs, worksheetCount, chartsheetCount, worksheetEntries, _d, workbookRelationshipsXml, sheetRelationshipIds, slicerCacheRelationshipIds, pivotCacheRelationshipIds, externalLinkRelationshipIds, workbookXml, sharedStringsXml, rootRelationshipsXml, appXml, coreXml, tablePartFiles, preparedTables_1, preparedTables_1_1, table, rows, tableXml, stylesXml, themeXml, files, worksheetEntries_1, worksheetEntries_1_1, entry, personsXml, globalImageIndex, globalChartIndex, drawingSheets, imageExtensions, chartEntries, chartExEntries, globalChartExIndex, worksheetEntries_2, worksheetEntries_2_1, entry, placements, textBoxesForSheet, shapesForSheet, chartsForSheet, slicersForSheet, drawingParts, _e, _f, media, _g, _h, chartEntry, _j, _k, chartExEntry, e_1_1, chartEntries_1, chartEntries_1_1, chartEntry, chartExEntries_1, chartExEntries_1_1, chartExEntry, slicerCacheEntries_1, slicerCacheEntries_1_1, slicerCacheEntry, slicerEntries_1, slicerEntries_1_1, slicerEntry, pivotCacheEntries_1, pivotCacheEntries_1_1, cacheEntry, pivotCacheRelsEntries_1, pivotCacheRelsEntries_1_1, cacheRels, pivotTableEntries_1, pivotTableEntries_1_1, tableEntry, pivotTableRelsEntries_1, pivotTableRelsEntries_1_1, tableRels, i, link, linkPath, relsPath, commentsSheets, hasVmlDrawings, _l, _m, part, threadedCommentsSheets, contentTypesXml, zipBytes;
34
+ var sortedSheets, sharedStrings, personRegistry, styleBuilder, customTableStyleRecords, customTableStyleNames, exportableTables, tableIdMap, preparedTables, chartCount, embedsBySheet, textBoxesBySheet, shapesBySheet, formControlsBySheet, ctrlProps, chartsBySheet, remappedSlicers, slicersBySheet, workbookSheetNames, sheetNameById, dataValidationsById, globalSlicerIndex, slicerCacheEntries, slicerEntries, globalPivotIndex, pivotCacheEntries, pivotCacheRelsEntries, pivotTableEntries, pivotTableRelsEntries, pivotSourceNameById, _loop_1, pivotTables_1, pivotTables_1_1, p, resolvePivotSourceName, pivotsByTargetSheet, pivotTables_2, pivotTables_2_1, p, sid, list, workbookPivotCacheRefs, worksheetCount, chartsheetCount, worksheetEntries, hasDynamicArrays, _d, workbookRelationshipsXml, sheetRelationshipIds, slicerCacheRelationshipIds, pivotCacheRelationshipIds, externalLinkRelationshipIds, workbookXml, sharedStringsXml, rootRelationshipsXml, appXml, coreXml, tablePartFiles, preparedTables_1, preparedTables_1_1, table, rows, tableXml, stylesXml, themeXml, files, worksheetEntries_1, worksheetEntries_1_1, entry, personsXml, globalImageIndex, globalChartIndex, drawingSheets, imageExtensions, chartEntries, chartExEntries, globalChartExIndex, worksheetEntries_2, worksheetEntries_2_1, entry, placements, textBoxesForSheet, shapesForSheet, chartsForSheet, slicersForSheet, drawingParts, _e, _f, media, _g, _h, chartEntry, _j, _k, chartExEntry, e_1_1, chartEntries_1, chartEntries_1_1, chartEntry, chartExEntries_1, chartExEntries_1_1, chartExEntry, slicerCacheEntries_1, slicerCacheEntries_1_1, slicerCacheEntry, slicerEntries_1, slicerEntries_1_1, slicerEntry, pivotCacheEntries_1, pivotCacheEntries_1_1, cacheEntry, pivotCacheRelsEntries_1, pivotCacheRelsEntries_1_1, cacheRels, pivotTableEntries_1, pivotTableEntries_1_1, tableEntry, pivotTableRelsEntries_1, pivotTableRelsEntries_1_1, tableRels, i, link, linkPath, relsPath, commentsSheets, hasVmlDrawings, _l, _m, part, threadedCommentsSheets, contentTypesXml, zipBytes;
35
35
  var e_2, _o, e_3, _p, e_4, _q, e_5, _s, e_1, _t, e_6, _u, e_7, _v, e_8, _w, e_9, _x, e_10, _y, e_11, _z, e_12, _0, e_13, _1, e_14, _2, e_15, _3, e_16, _4, e_17, _5;
36
36
  var _6, _7, _8, _9, _10, _11, _12, _13, _14;
37
- var _conditionalFormats = _b.conditionalFormats, _dataValidations = _b.dataValidations, sheets = _b.sheets, sheetData = _b.sheetData, sourceSharedStrings = _b.sharedStrings, _15 = _b.tables, _tables = _15 === void 0 ? [] : _15, cellXfs = _b.cellXfs, theme = _b.theme, defaultFont = _b.defaultFont, _16 = _b.embeds, embeds = _16 === void 0 ? [] : _16, _17 = _b.charts, charts = _17 === void 0 ? [] : _17, _18 = _b.slicers, slicers = _18 === void 0 ? [] : _18, _19 = _b.pivotTables, pivotTables = _19 === void 0 ? [] : _19, _20 = _b.externalLinks, externalLinks = _20 === void 0 ? [] : _20, _21 = _b.namedRanges, namedRanges = _21 === void 0 ? [] : _21, _22 = _b.protectedRanges, protectedRanges = _22 === void 0 ? [] : _22, namedCellStyles = _b.namedCellStyles, customTableStyles = _b.customTableStyles, iterativeCalculationOptions = _b.iterativeCalculationOptions, ignoreFormulaPatterns = _b.ignoreFormulaPatterns, citations = _b.citations, comments = _b.comments, password = _b.password, locale = _b.locale, _23 = _b.use1904, use1904 = _23 === void 0 ? false : _23, properties = _b.properties, powerQuery = _b.powerQuery;
37
+ var _conditionalFormats = _b.conditionalFormats, _dataValidations = _b.dataValidations, sheets = _b.sheets, sheetData = _b.sheetData, sourceSharedStrings = _b.sharedStrings, _15 = _b.tables, _tables = _15 === void 0 ? [] : _15, cellXfs = _b.cellXfs, theme = _b.theme, defaultFont = _b.defaultFont, _16 = _b.embeds, embeds = _16 === void 0 ? [] : _16, _17 = _b.charts, charts = _17 === void 0 ? [] : _17, _18 = _b.slicers, slicers = _18 === void 0 ? [] : _18, _19 = _b.pivotTables, pivotTables = _19 === void 0 ? [] : _19, _20 = _b.externalLinks, externalLinks = _20 === void 0 ? [] : _20, _21 = _b.namedRanges, namedRanges = _21 === void 0 ? [] : _21, _22 = _b.protectedRanges, protectedRanges = _22 === void 0 ? [] : _22, namedCellStyles = _b.namedCellStyles, customTableStyles = _b.customTableStyles, iterativeCalculationOptions = _b.iterativeCalculationOptions, workbookProtection = _b.workbookProtection, ignoreFormulaPatterns = _b.ignoreFormulaPatterns, citations = _b.citations, comments = _b.comments, password = _b.password, locale = _b.locale, _23 = _b.use1904, use1904 = _23 === void 0 ? false : _23, properties = _b.properties, powerQuery = _b.powerQuery;
38
38
  return __generator(this, function (_24) {
39
39
  switch (_24.label) {
40
40
  case 0:
@@ -411,13 +411,15 @@ export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void
411
411
  commentsXml: result.commentsXml,
412
412
  vmlDrawingXml: result.vmlDrawingXml,
413
413
  threadedCommentsXml: result.threadedCommentsXml,
414
+ hasDynamicArrays: result.hasDynamicArrays,
414
415
  };
415
416
  });
417
+ hasDynamicArrays = worksheetEntries.some(function (entry) { return entry.hasDynamicArrays; });
416
418
  _d = buildWorkbookRelationships(worksheetEntries.map(function (entry) { return ({
417
419
  chartsheet: entry.isChartsheet,
418
420
  target: entry.path.replace(/^xl\//, ""),
419
- }); }), slicerCacheEntries.length, externalLinks.length, pivotCacheEntries.length, !personRegistry.isEmpty()), workbookRelationshipsXml = _d.xml, sheetRelationshipIds = _d.sheetRelationshipIds, slicerCacheRelationshipIds = _d.slicerCacheRelationshipIds, pivotCacheRelationshipIds = _d.pivotCacheRelationshipIds, externalLinkRelationshipIds = _d.externalLinkRelationshipIds;
420
- workbookXml = buildWorkbookXml(sortedSheets, sheetRelationshipIds, workbookSheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelationshipIds, use1904, externalLinkRelationshipIds, pivotCacheRelationshipIds);
421
+ }); }), slicerCacheEntries.length, externalLinks.length, pivotCacheEntries.length, !personRegistry.isEmpty(), hasDynamicArrays), workbookRelationshipsXml = _d.xml, sheetRelationshipIds = _d.sheetRelationshipIds, slicerCacheRelationshipIds = _d.slicerCacheRelationshipIds, pivotCacheRelationshipIds = _d.pivotCacheRelationshipIds, externalLinkRelationshipIds = _d.externalLinkRelationshipIds;
422
+ workbookXml = buildWorkbookXml(sortedSheets, sheetRelationshipIds, workbookSheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelationshipIds, use1904, externalLinkRelationshipIds, pivotCacheRelationshipIds, workbookProtection);
421
423
  sharedStringsXml = buildSharedStringsXml(sharedStrings);
422
424
  rootRelationshipsXml = buildRootRelationshipsXml();
423
425
  appXml = buildAppXml(workbookSheetNames, sortedSheets.map(function (sheet) { return sheet.type === "chartsheet"; }), properties);
@@ -452,6 +454,9 @@ export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void
452
454
  "xl/styles.xml": encodeXml(stylesXml),
453
455
  "xl/theme/theme1.xml": encodeXml(themeXml),
454
456
  };
457
+ if (hasDynamicArrays) {
458
+ files["xl/metadata.xml"] = encodeXml(DYNAMIC_ARRAY_METADATA_XML);
459
+ }
455
460
  try {
456
461
  for (worksheetEntries_1 = __values(worksheetEntries), worksheetEntries_1_1 = worksheetEntries_1.next(); !worksheetEntries_1_1.done; worksheetEntries_1_1 = worksheetEntries_1.next()) {
457
462
  entry = worksheetEntries_1_1.value;
@@ -744,6 +749,7 @@ export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void
744
749
  externalLinkCount: externalLinks.length,
745
750
  hasVmlDrawings: hasVmlDrawings,
746
751
  ctrlPropCount: ctrlProps.parts.length,
752
+ hasSheetMetadata: hasDynamicArrays,
747
753
  });
748
754
  files["[Content_Types].xml"] = encodeXml(contentTypesXml);
749
755
  // Preserved Power Query machinery (DataMashup customXml, connections.xml, queryTable parts) is
@@ -882,11 +888,12 @@ export var normalizeSqrefMembers = function (refs) {
882
888
  return out;
883
889
  };
884
890
  var DataValidationCollector = /** @class */ (function () {
885
- function DataValidationCollector() {
891
+ function DataValidationCollector(locale) {
892
+ this.locale = locale;
886
893
  this.entries = new Map();
887
894
  }
888
895
  DataValidationCollector.prototype.add = function (address, rule) {
889
- var config = convertDataValidationRule(rule);
896
+ var config = convertDataValidationRule(rule, this.locale);
890
897
  if (!config)
891
898
  return;
892
899
  var key = getDataValidationKey(config);
@@ -1040,7 +1047,7 @@ var buildWorksheetXml = function (_a) {
1040
1047
  var defaultRowHeightPx = getDefaultRowHeightPx(sheet);
1041
1048
  var rowXmlChunks = [];
1042
1049
  var collectedImages = [];
1043
- var dataValidationCollector = new DataValidationCollector();
1050
+ var dataValidationCollector = new DataValidationCollector(locale);
1044
1051
  var hyperlinkEntries = [];
1045
1052
  var commentsCollector = new CommentsCollector();
1046
1053
  var threadedCommentsCollector = new ThreadedCommentsCollector(comments, personRegistry !== null && personRegistry !== void 0 ? personRegistry : new PersonRegistry());
@@ -1119,6 +1126,8 @@ var buildWorksheetXml = function (_a) {
1119
1126
  // see `<f t="shared" si="N"/>` with no corresponding leader and read the
1120
1127
  // cell as having no formula at all.
1121
1128
  var validSharedFormulaLeaders = new Set();
1129
+ // Any `cm="1"` anchor on this sheet makes the workbook carry xl/metadata.xml.
1130
+ var hasDynamicArrays = false;
1122
1131
  for (var rowIndex = 1; rowIndex < maxRows; rowIndex++) {
1123
1132
  var row = rows[rowIndex];
1124
1133
  var rowValues = row === null || row === void 0 ? void 0 : row.values;
@@ -1163,6 +1172,9 @@ var buildWorksheetXml = function (_a) {
1163
1172
  sheets: sheets,
1164
1173
  locale: locale,
1165
1174
  validSharedFormulaLeaders: validSharedFormulaLeaders,
1175
+ onDynamicArray: function () {
1176
+ hasDynamicArrays = true;
1177
+ },
1166
1178
  onImage: function (image) {
1167
1179
  collectedImages.push(image);
1168
1180
  drawingContext.ensureRel();
@@ -1212,6 +1224,7 @@ var buildWorksheetXml = function (_a) {
1212
1224
  sheetId: sheet.sheetId,
1213
1225
  conditionalFormats: conditionalFormats,
1214
1226
  styleBuilder: styleBuilder,
1227
+ locale: locale,
1215
1228
  });
1216
1229
  var tablePartsXml = buildTablePartsXml(tables, relationships);
1217
1230
  var drawingXml = drawingContext.hasDrawing()
@@ -1317,6 +1330,7 @@ var buildWorksheetXml = function (_a) {
1317
1330
  commentsXml: commentsXml,
1318
1331
  vmlDrawingXml: vmlDrawingXml,
1319
1332
  threadedCommentsXml: threadedCommentsXml,
1333
+ hasDynamicArrays: hasDynamicArrays,
1320
1334
  };
1321
1335
  };
1322
1336
  /**
@@ -1340,6 +1354,7 @@ var buildChartsheetXml = function (_a) {
1340
1354
  commentsXml: undefined,
1341
1355
  vmlDrawingXml: undefined,
1342
1356
  threadedCommentsXml: undefined,
1357
+ hasDynamicArrays: false,
1343
1358
  };
1344
1359
  };
1345
1360
  /**
@@ -1549,7 +1564,7 @@ var normalizeXlsxSourceListFormula1 = function (formula1) {
1549
1564
  return trimmed;
1550
1565
  return "\"".concat(escapeFormulaText(trimmed), "\"");
1551
1566
  };
1552
- var convertDataValidationRule = function (rule) {
1567
+ var convertDataValidationRule = function (rule, locale) {
1553
1568
  var _a, _b, _d, _e, _f, _g;
1554
1569
  if (!rule)
1555
1570
  return undefined;
@@ -1592,7 +1607,7 @@ var convertDataValidationRule = function (rule) {
1592
1607
  rejectedListSource = normalizeXlsxSourceListFormula1(src.formula1);
1593
1608
  }
1594
1609
  }
1595
- var synthesized = convertDataValidationCondition(rule, baseConfig);
1610
+ var synthesized = convertDataValidationCondition(rule, baseConfig, locale);
1596
1611
  if (synthesized)
1597
1612
  return synthesized;
1598
1613
  // A rejected `list` source with no usable condition is still kept — its
@@ -1606,7 +1621,7 @@ var convertDataValidationRule = function (rule) {
1606
1621
  // The condition-based synthesizer: the Excel config for a rule that has no
1607
1622
  // replayable `xlsxSource` (UI-authored, edited after import, or rejected by
1608
1623
  // the round-trip guard above).
1609
- var convertDataValidationCondition = function (rule, baseConfig) {
1624
+ var convertDataValidationCondition = function (rule, baseConfig, locale) {
1610
1625
  var _a, _b, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _s, _t, _u, _v, _w, _x, _y, _z;
1611
1626
  if (!((_a = rule.condition) === null || _a === void 0 ? void 0 : _a.type)) {
1612
1627
  // Prompt-only DV (no validation rule, just an input-message tooltip
@@ -1619,10 +1634,9 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1619
1634
  }
1620
1635
  var condition = rule.condition;
1621
1636
  var values = (_b = condition.values) !== null && _b !== void 0 ? _b : [];
1637
+ // OOXML `<formula1>` carries the formula text WITHOUT a leading `=` — Excel
1638
+ // never writes one (the xlsxSource replay path strips it the same way).
1622
1639
  var currentCell = 'INDIRECT("RC",FALSE)';
1623
- var ensureFormula = function (value) {
1624
- return value.startsWith("=") ? value : "=".concat(value);
1625
- };
1626
1640
  var ifErrorWrap = function (formula) { return "IFERROR(".concat(formula, ",TRUE)"); };
1627
1641
  if (condition.type === "ONE_OF_LIST") {
1628
1642
  var entries = values
@@ -1639,62 +1653,61 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1639
1653
  .filter(function (value) { return typeof value === "string"; });
1640
1654
  if (!references.length)
1641
1655
  return undefined;
1642
- var formula1 = references.join(",");
1643
- return __assign({ type: "list", formula1: formula1.startsWith("=") ? formula1 : "=".concat(formula1), showDropDown: rule.displayStyle === "plain" ? true : undefined }, baseConfig);
1656
+ return __assign({ type: "list", formula1: stripLeadingEquals(references.join(",")), showDropDown: rule.displayStyle === "plain" ? true : undefined }, baseConfig);
1644
1657
  }
1645
1658
  if (condition.type === "CUSTOM_FORMULA") {
1646
1659
  var raw = (_e = (_d = values[0]) === null || _d === void 0 ? void 0 : _d.userEnteredValue) !== null && _e !== void 0 ? _e : "";
1647
1660
  if (!raw)
1648
1661
  return undefined;
1649
- return __assign({ type: "custom", formula1: ensureFormula(raw) }, baseConfig);
1662
+ return __assign({ type: "custom", formula1: stripLeadingEquals(raw) }, baseConfig);
1650
1663
  }
1651
1664
  if (condition.type === "BOOLEAN") {
1652
- return __assign({ type: "custom", formula1: "=OR(".concat(currentCell, "=TRUE,").concat(currentCell, "=FALSE)") }, baseConfig);
1665
+ return __assign({ type: "custom", formula1: "OR(".concat(currentCell, "=TRUE,").concat(currentCell, "=FALSE)") }, baseConfig);
1653
1666
  }
1654
1667
  if (condition.type === "BLANK") {
1655
- return __assign({ type: "custom", formula1: "=".concat(currentCell, "=\"\"") }, baseConfig);
1668
+ return __assign({ type: "custom", formula1: "".concat(currentCell, "=\"\"") }, baseConfig);
1656
1669
  }
1657
1670
  if (condition.type === "NOT_BLANK") {
1658
- return __assign({ type: "custom", formula1: "=".concat(currentCell, "<>\"\"") }, baseConfig);
1671
+ return __assign({ type: "custom", formula1: "".concat(currentCell, "<>\"\"") }, baseConfig);
1659
1672
  }
1660
1673
  if (condition.type === "TEXT_EQ" || condition.type === "TEXT_NOT_EQ") {
1661
1674
  var raw = (_g = (_f = values[0]) === null || _f === void 0 ? void 0 : _f.userEnteredValue) !== null && _g !== void 0 ? _g : "";
1662
1675
  if (!raw)
1663
1676
  return undefined;
1664
1677
  var op = condition.type === "TEXT_EQ" ? "=" : "<>";
1665
- return __assign({ type: "custom", formula1: "=".concat(currentCell).concat(op, "\"").concat(escapeFormulaText(raw), "\"") }, baseConfig);
1678
+ return __assign({ type: "custom", formula1: "".concat(currentCell).concat(op, "\"").concat(escapeFormulaText(raw), "\"") }, baseConfig);
1666
1679
  }
1667
1680
  if (condition.type === "TEXT_CONTAINS") {
1668
1681
  var raw = (_j = (_h = values[0]) === null || _h === void 0 ? void 0 : _h.userEnteredValue) !== null && _j !== void 0 ? _j : "";
1669
1682
  if (!raw)
1670
1683
  return undefined;
1671
- return __assign({ type: "custom", formula1: "=ISNUMBER(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1684
+ return __assign({ type: "custom", formula1: "ISNUMBER(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1672
1685
  }
1673
1686
  if (condition.type === "TEXT_NOT_CONTAINS") {
1674
1687
  var raw = (_l = (_k = values[0]) === null || _k === void 0 ? void 0 : _k.userEnteredValue) !== null && _l !== void 0 ? _l : "";
1675
1688
  if (!raw)
1676
1689
  return undefined;
1677
- return __assign({ type: "custom", formula1: "=ISERROR(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1690
+ return __assign({ type: "custom", formula1: "ISERROR(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1678
1691
  }
1679
1692
  if (condition.type === "TEXT_STARTS_WITH") {
1680
1693
  var raw = (_o = (_m = values[0]) === null || _m === void 0 ? void 0 : _m.userEnteredValue) !== null && _o !== void 0 ? _o : "";
1681
1694
  if (!raw)
1682
1695
  return undefined;
1683
1696
  var text = escapeFormulaText(raw);
1684
- return __assign({ type: "custom", formula1: "=LEFT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1697
+ return __assign({ type: "custom", formula1: "LEFT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1685
1698
  }
1686
1699
  if (condition.type === "TEXT_ENDS_WITH") {
1687
1700
  var raw = (_q = (_p = values[0]) === null || _p === void 0 ? void 0 : _p.userEnteredValue) !== null && _q !== void 0 ? _q : "";
1688
1701
  if (!raw)
1689
1702
  return undefined;
1690
1703
  var text = escapeFormulaText(raw);
1691
- return __assign({ type: "custom", formula1: "=RIGHT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1704
+ return __assign({ type: "custom", formula1: "RIGHT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1692
1705
  }
1693
1706
  if (condition.type === "TEXT_IS_EMAIL") {
1694
- return __assign({ type: "custom", formula1: "=AND(ISNUMBER(SEARCH(\"@\",".concat(currentCell, ")),ISNUMBER(SEARCH(\".\",").concat(currentCell, ")))") }, baseConfig);
1707
+ return __assign({ type: "custom", formula1: "AND(ISNUMBER(SEARCH(\"@\",".concat(currentCell, ")),ISNUMBER(SEARCH(\".\",").concat(currentCell, ")))") }, baseConfig);
1695
1708
  }
1696
1709
  if (condition.type === "TEXT_IS_URL") {
1697
- return __assign({ type: "custom", formula1: "=OR(LEFT(".concat(currentCell, ",7)=\"http://\",LEFT(").concat(currentCell, ",8)=\"https://\")") }, baseConfig);
1710
+ return __assign({ type: "custom", formula1: "OR(LEFT(".concat(currentCell, ",7)=\"http://\",LEFT(").concat(currentCell, ",8)=\"https://\")") }, baseConfig);
1698
1711
  }
1699
1712
  if (condition.type === "NUMBER_BETWEEN" ||
1700
1713
  condition.type === "NUMBER_NOT_BETWEEN" ||
@@ -1718,9 +1731,12 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1718
1731
  NUMBER_LESS: "lessThan",
1719
1732
  NUMBER_LESS_THAN_EQ: "lessThanOrEqual",
1720
1733
  };
1721
- return __assign({ type: "decimal", operator: operatorMap[condition.type], formula1: first, formula2: condition.type === "NUMBER_BETWEEN" ||
1734
+ // Bounds are written the way Excel stores them: typed literals normalized
1735
+ // (`50%` → `0.5`, a typed date → its serial), formulas without their `=`,
1736
+ // references / names / function calls verbatim.
1737
+ return __assign({ type: "decimal", operator: operatorMap[condition.type], formula1: conditionOperandToFormulaText(first, locale), formula2: condition.type === "NUMBER_BETWEEN" ||
1722
1738
  condition.type === "NUMBER_NOT_BETWEEN"
1723
- ? second
1739
+ ? conditionOperandToFormulaText(second, locale)
1724
1740
  : undefined }, baseConfig);
1725
1741
  }
1726
1742
  if (condition.type === "NUMBER_GREATER_THAN_PREVIOUS" ||
@@ -1734,7 +1750,7 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1734
1750
  NUMBER_LESS_THAN_EQ_PREVIOUS: "<=",
1735
1751
  };
1736
1752
  var op = opMap[condition.type];
1737
- return __assign({ type: "custom", formula1: "=".concat(ifErrorWrap("".concat(currentCell).concat(op, "INDIRECT(\"R[-1]C\",FALSE)"))) }, baseConfig);
1753
+ return __assign({ type: "custom", formula1: "".concat(ifErrorWrap("".concat(currentCell).concat(op, "INDIRECT(\"R[-1]C\",FALSE)"))) }, baseConfig);
1738
1754
  }
1739
1755
  if (condition.type === "DATE_EQ" ||
1740
1756
  condition.type === "DATE_NOT_EQ" ||
@@ -1758,13 +1774,13 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1758
1774
  DATE_BETWEEN: "between",
1759
1775
  DATE_NOT_BETWEEN: "notBetween",
1760
1776
  };
1761
- return __assign({ type: "date", operator: operatorMap[condition.type], formula1: first, formula2: condition.type === "DATE_BETWEEN" ||
1777
+ return __assign({ type: "date", operator: operatorMap[condition.type], formula1: conditionOperandToFormulaText(first, locale), formula2: condition.type === "DATE_BETWEEN" ||
1762
1778
  condition.type === "DATE_NOT_BETWEEN"
1763
- ? second
1779
+ ? conditionOperandToFormulaText(second, locale)
1764
1780
  : undefined }, baseConfig);
1765
1781
  }
1766
1782
  if (condition.type === "DATE_IS_VALID") {
1767
- return __assign({ type: "custom", formula1: "=ISNUMBER(".concat(currentCell, ")") }, baseConfig);
1783
+ return __assign({ type: "custom", formula1: "ISNUMBER(".concat(currentCell, ")") }, baseConfig);
1768
1784
  }
1769
1785
  return undefined;
1770
1786
  };
@@ -1845,7 +1861,7 @@ var resolveCellDataValidation = function (cell, map) {
1845
1861
  };
1846
1862
  var buildWorksheetRow = function (_a) {
1847
1863
  var _b, _d;
1848
- var rowNumber = _a.rowNumber, row = _a.row, rowMetadata = _a.rowMetadata, defaultRowHeightPx = _a.defaultRowHeightPx, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders;
1864
+ var rowNumber = _a.rowNumber, row = _a.row, rowMetadata = _a.rowMetadata, defaultRowHeightPx = _a.defaultRowHeightPx, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders, onDynamicArray = _a.onDynamicArray;
1849
1865
  var values = (_b = row === null || row === void 0 ? void 0 : row.values) !== null && _b !== void 0 ? _b : [];
1850
1866
  var cellXmlChunks = [];
1851
1867
  var minColumn = Number.POSITIVE_INFINITY;
@@ -1874,6 +1890,7 @@ var buildWorksheetRow = function (_a) {
1874
1890
  sheets: sheets,
1875
1891
  locale: locale,
1876
1892
  validSharedFormulaLeaders: validSharedFormulaLeaders,
1893
+ onDynamicArray: onDynamicArray,
1877
1894
  });
1878
1895
  if (!cellXml)
1879
1896
  continue;
@@ -1946,8 +1963,8 @@ var buildWorksheetRow = function (_a) {
1946
1963
  };
1947
1964
  var buildCellXml = function (_a) {
1948
1965
  var e_33, _b;
1949
- var _d, _e, _f, _g, _h, _j, _k, _l;
1950
- var rowNumber = _a.rowNumber, columnIndex = _a.columnIndex, cell = _a.cell, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders;
1966
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m;
1967
+ var rowNumber = _a.rowNumber, columnIndex = _a.columnIndex, cell = _a.cell, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders, onDynamicArray = _a.onDynamicArray;
1951
1968
  var normalizedCell = cell;
1952
1969
  if (!normalizedCell)
1953
1970
  return undefined;
@@ -2091,12 +2108,25 @@ var buildCellXml = function (_a) {
2091
2108
  }
2092
2109
  var xmlParts = [];
2093
2110
  var typeAttr = "";
2111
+ var dynamicArrayAttr = "";
2094
2112
  if (exportedFormulaValue) {
2095
2113
  // Array formula anchor: emit <f t="array" ref="..."/>. Spilled cells in
2096
2114
  // the range carry no `ue` formula (they're populated by the calculator
2097
2115
  // as side-effects of the anchor's evaluation), so they never reach this
2098
- // branch and correctly emit only <v>.
2099
- var arrayRef = normalizedCell.af;
2116
+ // branch and correctly emit only <v>. `af` is stamped by the calculator
2117
+ // on every spilling anchor and captured from `<f t="array" ref>` on
2118
+ // import; a bare array constant (`={1,2;3,4}`) that never went through
2119
+ // the calculator still gets its range from the constant's own shape.
2120
+ var arrayRef = (_m = normalizedCell.af) !== null && _m !== void 0 ? _m : arrayConstantSpillRef(exportedFormulaValue, rowNumber, columnIndex);
2121
+ // Excel distinguishes the two kinds of `<f t="array">`: a dynamic array
2122
+ // carries `cm="1"` on the `<c>` (pointing at the XLDAPR record in
2123
+ // xl/metadata.xml) and re-opens as a spilling formula; without `cm` Excel
2124
+ // reads a legacy Ctrl+Shift+Enter array (`{=…}`). Only an anchor imported
2125
+ // as a CSE array (`cse`) is written back that way.
2126
+ if (arrayRef && !(normalizedCell.af && normalizedCell.cse)) {
2127
+ dynamicArrayAttr = " cm=\"1\"";
2128
+ onDynamicArray === null || onDynamicArray === void 0 ? void 0 : onDynamicArray();
2129
+ }
2100
2130
  // Shared formula: emit `<f t="shared" si="N" ref="A1:A10">FORMULA</f>`
2101
2131
  // on the leader cell (carries both `si` and `ref`) and
2102
2132
  // `<f t="shared" si="N"/>` on followers (carries only `si` — no formula
@@ -2181,7 +2211,7 @@ var buildCellXml = function (_a) {
2181
2211
  }
2182
2212
  return "<c r=\"".concat(address, "\"").concat(styleAttr, "/>");
2183
2213
  }
2184
- return "<c r=\"".concat(address, "\"").concat(typeAttr).concat(styleAttr, ">").concat(xmlParts.join(""), "</c>");
2214
+ return "<c r=\"".concat(address, "\"").concat(typeAttr).concat(styleAttr).concat(dynamicArrayAttr, ">").concat(xmlParts.join(""), "</c>");
2185
2215
  };
2186
2216
  var normalizeHyperlinkValue = function (hyperlink) {
2187
2217
  if (!hyperlink) {
@@ -2267,6 +2297,56 @@ function stripFormula(formula) {
2267
2297
  var trimmed = formula.startsWith("=") ? formula.slice(1) : formula;
2268
2298
  return sanitizeFormulaText(trimmed);
2269
2299
  }
2300
+ /**
2301
+ * The A1 range an array constant spills over from its anchor: `={1,2;3,4}` at
2302
+ * B3 → `B3:C4`. `undefined` for anything that is not exactly one array
2303
+ * constant (a constant nested in a larger expression, a malformed literal).
2304
+ * Separators inside string elements are skipped.
2305
+ */
2306
+ function arrayConstantSpillRef(formula, rowNumber, columnIndex) {
2307
+ var e_34, _a;
2308
+ var body = (formula.startsWith("=") ? formula.slice(1) : formula).trim();
2309
+ if (!body.startsWith("{") || !body.endsWith("}"))
2310
+ return undefined;
2311
+ var rows = 1;
2312
+ var columns = 1;
2313
+ var inString = false;
2314
+ try {
2315
+ for (var _b = __values(body.slice(1, -1)), _d = _b.next(); !_d.done; _d = _b.next()) {
2316
+ var char = _d.value;
2317
+ if (char === '"') {
2318
+ inString = !inString;
2319
+ }
2320
+ else if (inString) {
2321
+ continue;
2322
+ }
2323
+ else if (char === "{" || char === "}") {
2324
+ return undefined;
2325
+ }
2326
+ else if (char === "," && rows === 1) {
2327
+ columns++;
2328
+ }
2329
+ else if (char === ";") {
2330
+ rows++;
2331
+ }
2332
+ }
2333
+ }
2334
+ catch (e_34_1) { e_34 = { error: e_34_1 }; }
2335
+ finally {
2336
+ try {
2337
+ if (_d && !_d.done && (_a = _b.return)) _a.call(_b);
2338
+ }
2339
+ finally { if (e_34) throw e_34.error; }
2340
+ }
2341
+ if (inString)
2342
+ return undefined;
2343
+ return cellRangeToAddress(undefined, {
2344
+ startRowIndex: rowNumber,
2345
+ startColumnIndex: columnIndex,
2346
+ endRowIndex: rowNumber + rows - 1,
2347
+ endColumnIndex: columnIndex + columns - 1,
2348
+ });
2349
+ }
2270
2350
  function hasPropertyReference(formula) {
2271
2351
  if (!formula)
2272
2352
  return false;
@@ -2284,7 +2364,7 @@ function isValidExcelDateSerial(value) {
2284
2364
  return value >= MIN_EXCEL_DATE_SERIAL && value <= MAX_EXCEL_DATE_SERIAL;
2285
2365
  }
2286
2366
  function rewriteTableNamesInFormula(formula, tableNameMap) {
2287
- var e_34, _a;
2367
+ var e_35, _a;
2288
2368
  if (!(tableNameMap === null || tableNameMap === void 0 ? void 0 : tableNameMap.size))
2289
2369
  return formula;
2290
2370
  var normalized = formula;
@@ -2299,12 +2379,12 @@ function rewriteTableNamesInFormula(formula, tableNameMap) {
2299
2379
  normalized = normalized.replace(new RegExp("".concat(escaped, "(?=\\[)"), "g"), exportedName);
2300
2380
  }
2301
2381
  }
2302
- catch (e_34_1) { e_34 = { error: e_34_1 }; }
2382
+ catch (e_35_1) { e_35 = { error: e_35_1 }; }
2303
2383
  finally {
2304
2384
  try {
2305
2385
  if (tableNameMap_1_1 && !tableNameMap_1_1.done && (_a = tableNameMap_1.return)) _a.call(tableNameMap_1);
2306
2386
  }
2307
- finally { if (e_34) throw e_34.error; }
2387
+ finally { if (e_35) throw e_35.error; }
2308
2388
  }
2309
2389
  return normalized;
2310
2390
  }
@@ -2400,6 +2480,30 @@ function rewriteStructuredReferenceFormula(formula, tableNameMap, tables, rowNum
2400
2480
  var qualified = prefixUnqualifiedStructuredReferences(normalized, table.name);
2401
2481
  return normalizeThisRowStructuredReferences(qualified, table.name);
2402
2482
  }
2483
+ /**
2484
+ * `xl/metadata.xml` for a workbook with dynamic-array anchors — one XLDAPR
2485
+ * (dynamic array properties) record every `cm="1"` cell points at, exactly as
2486
+ * Excel 365 writes it. `fDynamic="1"` marks the anchor as a spilling formula;
2487
+ * `fCollapsed="0"` says the spill is shown expanded.
2488
+ */
2489
+ var DYNAMIC_ARRAY_METADATA_XML = "".concat(XML_DECLARATION, "<metadata xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:xda=\"http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray\"><metadataTypes count=\"1\"><metadataType name=\"XLDAPR\" minSupportedVersion=\"120000\" copy=\"1\" pasteAll=\"1\" pasteValues=\"1\" merge=\"1\" splitFirst=\"1\" rowColShift=\"1\" clearFormats=\"1\" clearComments=\"1\" assign=\"1\" coerce=\"1\" cellMeta=\"1\"/></metadataTypes><futureMetadata name=\"XLDAPR\" count=\"1\"><bk><extLst><ext uri=\"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}\"><xda:dynamicArrayProperties fDynamic=\"1\" fCollapsed=\"0\"/></ext></extLst></bk></futureMetadata><cellMetadata count=\"1\"><bk><rc t=\"1\" v=\"0\"/></bk></cellMetadata></metadata>");
2490
+ /**
2491
+ * A defined-name expression that is a formula rather than a constant: a
2492
+ * function call, an operator expression, a reference. Constants (`123`,
2493
+ * `"text"`, `TRUE`) are written verbatim.
2494
+ */
2495
+ function isAFormulaExpression(expression) {
2496
+ var trimmed = expression.trim();
2497
+ if (!trimmed)
2498
+ return false;
2499
+ if (/^"(?:[^"]|"")*"$/.test(trimmed))
2500
+ return false;
2501
+ if (/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?%?$/i.test(trimmed))
2502
+ return false;
2503
+ if (/^(?:TRUE|FALSE)$/i.test(trimmed))
2504
+ return false;
2505
+ return true;
2506
+ }
2403
2507
  function sanitizeFormulaText(formula) {
2404
2508
  var normalized = sanitizeXmlText(formula);
2405
2509
  // `@x` is persisted as `_xlfn.SINGLE(x)`; encoding first lets the
@@ -2707,7 +2811,7 @@ var buildRichRunProperties = function (format) {
2707
2811
  * style flag, but that's a cell-style concern, not a sharedString one.
2708
2812
  */
2709
2813
  var buildRichTextRuns = function (text, runs) {
2710
- var e_35, _a;
2814
+ var e_36, _a;
2711
2815
  var sorted = __spreadArray([], __read(runs), false).sort(function (a, b) { return a.startIndex - b.startIndex; });
2712
2816
  var out = [];
2713
2817
  var cursor = 0;
@@ -2740,12 +2844,12 @@ var buildRichTextRuns = function (text, runs) {
2740
2844
  cursor = end;
2741
2845
  }
2742
2846
  }
2743
- catch (e_35_1) { e_35 = { error: e_35_1 }; }
2847
+ catch (e_36_1) { e_36 = { error: e_36_1 }; }
2744
2848
  finally {
2745
2849
  try {
2746
2850
  if (sorted_2_1 && !sorted_2_1.done && (_a = sorted_2.return)) _a.call(sorted_2);
2747
2851
  }
2748
- finally { if (e_35) throw e_35.error; }
2852
+ finally { if (e_36) throw e_36.error; }
2749
2853
  }
2750
2854
  if (cursor < text.length) {
2751
2855
  emit(text.slice(cursor), "");
@@ -2766,7 +2870,7 @@ var buildSharedStringsXml = function (sharedStrings) {
2766
2870
  return "".concat(XML_DECLARATION, "<sst xmlns=\"").concat(WORKSHEET_NS, "\" count=\"").concat(sharedStrings.totalCount, "\" uniqueCount=\"").concat(sharedStrings.entries.length, "\">").concat(entries, "</sst>");
2767
2871
  };
2768
2872
  var buildTableNameMap = function (tables) {
2769
- var e_36, _a;
2873
+ var e_37, _a;
2770
2874
  var _b;
2771
2875
  var map = new Map();
2772
2876
  try {
@@ -2778,12 +2882,12 @@ var buildTableNameMap = function (tables) {
2778
2882
  map.set(tableTitle, table.name);
2779
2883
  }
2780
2884
  }
2781
- catch (e_36_1) { e_36 = { error: e_36_1 }; }
2885
+ catch (e_37_1) { e_37 = { error: e_37_1 }; }
2782
2886
  finally {
2783
2887
  try {
2784
2888
  if (tables_1_1 && !tables_1_1.done && (_a = tables_1.return)) _a.call(tables_1);
2785
2889
  }
2786
- finally { if (e_36) throw e_36.error; }
2890
+ finally { if (e_37) throw e_37.error; }
2787
2891
  }
2788
2892
  return map;
2789
2893
  };
@@ -2791,7 +2895,7 @@ var buildTableNameMap = function (tables) {
2791
2895
  // whose box intersects another table on the same sheet. Drop both before
2792
2896
  // emitting so the workbook opens without "We found a problem" recovery prompts.
2793
2897
  var filterExportableTables = function (tables) {
2794
- var e_37, _a;
2898
+ var e_38, _a;
2795
2899
  var _b;
2796
2900
  var isValidBox = function (range) {
2797
2901
  if (!range)
@@ -2834,12 +2938,12 @@ var filterExportableTables = function (tables) {
2834
2938
  _loop_5(table);
2835
2939
  }
2836
2940
  }
2837
- catch (e_37_1) { e_37 = { error: e_37_1 }; }
2941
+ catch (e_38_1) { e_38 = { error: e_38_1 }; }
2838
2942
  finally {
2839
2943
  try {
2840
2944
  if (tables_2_1 && !tables_2_1.done && (_a = tables_2.return)) _a.call(tables_2);
2841
2945
  }
2842
- finally { if (e_37) throw e_37.error; }
2946
+ finally { if (e_38) throw e_38.error; }
2843
2947
  }
2844
2948
  return result;
2845
2949
  };
@@ -3003,11 +3107,17 @@ var buildTableXml = function (table, rows, sourceSharedStrings, styleBuilder, cu
3003
3107
  .filter(function (idx) { var _a, _b; return ((_b = (_a = table.columns) === null || _a === void 0 ? void 0 : _a[idx]) === null || _b === void 0 ? void 0 : _b.filterButton) === false; }));
3004
3108
  var autoFilter = headerRowCount > 0 && table.filterButton !== false
3005
3109
  ? (function () {
3006
- var _a, _b, _d;
3110
+ var _a, _b, _d, _e;
3007
3111
  var filterColumns = buildFilterColumnsXml((_a = table.filterSpecs) !== null && _a !== void 0 ? _a : [], table.range, rows, (_b = table.headerRow) !== null && _b !== void 0 ? _b : true, (_d = table.totalRow) !== null && _d !== void 0 ? _d : false, styleBuilder, hiddenButtonColumns);
3112
+ // Excel's table `<autoFilter ref>` spans the header and data rows
3113
+ // only — a ref that reaches into the totals row makes Excel repair
3114
+ // the table (the totals row is never filtered or sorted).
3115
+ var filterRef = totalsRowCount > 0
3116
+ ? ((_e = gridRangeToRef(__assign(__assign({}, table.range), { endRowIndex: table.range.endRowIndex - totalsRowCount }))) !== null && _e !== void 0 ? _e : rangeRef)
3117
+ : rangeRef;
3008
3118
  return filterColumns
3009
- ? "<autoFilter ref=\"".concat(rangeRef, "\">").concat(filterColumns, "</autoFilter>")
3010
- : "<autoFilter ref=\"".concat(rangeRef, "\"/>");
3119
+ ? "<autoFilter ref=\"".concat(filterRef, "\">").concat(filterColumns, "</autoFilter>")
3120
+ : "<autoFilter ref=\"".concat(filterRef, "\"/>");
3011
3121
  })()
3012
3122
  : "";
3013
3123
  var sortState = buildTableSortStateXml(table, headerRowCount, totalsRowCount, styleBuilder);
@@ -3122,7 +3232,7 @@ var SHEET_PROTECTION_FLAG_ATTRS = [
3122
3232
  * Excel's schema default applies). Mirrors `rnc-export`'s `sheet_protection_xml`.
3123
3233
  */
3124
3234
  var buildSheetProtectionElementXml = function (protection) {
3125
- var e_38, _a;
3235
+ var e_39, _a;
3126
3236
  var attrs = [];
3127
3237
  if (protection.algorithmName) {
3128
3238
  attrs.push("algorithmName=\"".concat(escapeXmlAttr(protection.algorithmName), "\""));
@@ -3148,12 +3258,12 @@ var buildSheetProtectionElementXml = function (protection) {
3148
3258
  }
3149
3259
  }
3150
3260
  }
3151
- catch (e_38_1) { e_38 = { error: e_38_1 }; }
3261
+ catch (e_39_1) { e_39 = { error: e_39_1 }; }
3152
3262
  finally {
3153
3263
  try {
3154
3264
  if (SHEET_PROTECTION_FLAG_ATTRS_1_1 && !SHEET_PROTECTION_FLAG_ATTRS_1_1.done && (_a = SHEET_PROTECTION_FLAG_ATTRS_1.return)) _a.call(SHEET_PROTECTION_FLAG_ATTRS_1);
3155
3265
  }
3156
- finally { if (e_38) throw e_38.error; }
3266
+ finally { if (e_39) throw e_39.error; }
3157
3267
  }
3158
3268
  return attrs.length ? "<sheetProtection ".concat(attrs.join(" "), "/>") : "";
3159
3269
  };
@@ -3165,7 +3275,7 @@ var buildSheetProtectionElementXml = function (protection) {
3165
3275
  * is the range's id, synthesized as `Range{n}` when absent (schema requires it).
3166
3276
  */
3167
3277
  var buildSheetProtectionXml = function (sheet, protectedRanges) {
3168
- var e_39, _a;
3278
+ var e_40, _a;
3169
3279
  var protectionXml = sheet.sheetProtection
3170
3280
  ? buildSheetProtectionElementXml(sheet.sheetProtection)
3171
3281
  : "";
@@ -3206,12 +3316,12 @@ var buildSheetProtectionXml = function (sheet, protectedRanges) {
3206
3316
  rangeItems.push("<protectedRange sqref=\"".concat(escapeXmlAttr(sqref), "\" name=\"").concat(escapeXmlAttr(name_1), "\"").concat(securityDescriptor, "/>"));
3207
3317
  }
3208
3318
  }
3209
- catch (e_39_1) { e_39 = { error: e_39_1 }; }
3319
+ catch (e_40_1) { e_40 = { error: e_40_1 }; }
3210
3320
  finally {
3211
3321
  try {
3212
3322
  if (_d && !_d.done && (_a = _b.return)) _a.call(_b);
3213
3323
  }
3214
- finally { if (e_39) throw e_39.error; }
3324
+ finally { if (e_40) throw e_40.error; }
3215
3325
  }
3216
3326
  var rangesXml = rangeItems.length
3217
3327
  ? "<protectedRanges>".concat(rangeItems.join(""), "</protectedRanges>")
@@ -3344,7 +3454,7 @@ var buildPrintSettingsXml = function (print) {
3344
3454
  var buildFilterColumnsXml = function (filterSpecs, range, rows, headerRow, totalRow, styleBuilder,
3345
3455
  /** Table-relative column ids whose header hides its filter button. */
3346
3456
  hiddenButtonColumns) {
3347
- var e_40, _a;
3457
+ var e_41, _a;
3348
3458
  if (headerRow === void 0) { headerRow = true; }
3349
3459
  if (totalRow === void 0) { totalRow = false; }
3350
3460
  var entries = new Map();
@@ -3356,12 +3466,12 @@ hiddenButtonColumns) {
3356
3466
  entries.set(spec.columnIndex, xml);
3357
3467
  }
3358
3468
  }
3359
- catch (e_40_1) { e_40 = { error: e_40_1 }; }
3469
+ catch (e_41_1) { e_41 = { error: e_41_1 }; }
3360
3470
  finally {
3361
3471
  try {
3362
3472
  if (_d && !_d.done && (_a = _b.return)) _a.call(_b);
3363
3473
  }
3364
- finally { if (e_40) throw e_40.error; }
3474
+ finally { if (e_41) throw e_41.error; }
3365
3475
  }
3366
3476
  // `hiddenButton="1"` rides the column's criteria element when it has one,
3367
3477
  // else a bare `<filterColumn/>` carries it.
@@ -3382,55 +3492,99 @@ hiddenButtonColumns) {
3382
3492
  })
3383
3493
  .join("");
3384
3494
  };
3495
+ /**
3496
+ * One `<filterColumn colId=…>`, or `""` when the criteria have no autoFilter
3497
+ * representation. `CT_FilterColumn` is a CHOICE of exactly one of `filters` /
3498
+ * `top10` / `customFilters` / `dynamicFilter` / `colorFilter` / `iconFilter` —
3499
+ * a second child is a schema violation Excel repairs — so the first
3500
+ * representable criterion wins: colorFilter, iconFilter, condition(s), then
3501
+ * the value list (`<filters>`: the checked values, `blank="1"` for the
3502
+ * "(Blanks)" entry, and Excel's `<dateGroupItem>` date-tree entries). The
3503
+ * Rust exporter (`rnc-export` `filter_column_xml`) uses the same precedence.
3504
+ */
3385
3505
  var buildFilterColumnXml = function (spec, range, rows, headerRow, totalRow, styleBuilder) {
3386
3506
  var _a, _b, _d, _e, _f;
3387
3507
  if (headerRow === void 0) { headerRow = true; }
3388
3508
  if (totalRow === void 0) { totalRow = false; }
3389
- var parts = [];
3390
- // <colorFilter dxfId="N" cellColor="1|0"/> — Excel matches against the
3391
- // dxf table. We register the color as a dxf and emit the resulting id.
3392
- var colorFilter = (_a = spec.filterCriteria) === null || _a === void 0 ? void 0 : _a.colorFilter;
3393
- if (colorFilter && styleBuilder) {
3394
- var dxfId = colorFilter.mode === "cellColor"
3395
- ? styleBuilder.registerDifferentialFormat({
3396
- backgroundColor: colorFilter.color,
3397
- })
3398
- : styleBuilder.registerDifferentialFormat({
3399
- textFormat: { color: colorFilter.color },
3400
- });
3401
- if (typeof dxfId === "number") {
3402
- var cellColorAttr = colorFilter.mode === "cellColor" ? "1" : "0";
3403
- parts.push("<colorFilter dxfId=\"".concat(dxfId, "\" cellColor=\"").concat(cellColorAttr, "\"/>"));
3404
- }
3405
- }
3406
- // <iconFilter iconSet="…" iconId="…"/>
3407
- var iconFilter = (_b = spec.filterCriteria) === null || _b === void 0 ? void 0 : _b.iconFilter;
3408
- if (iconFilter === null || iconFilter === void 0 ? void 0 : iconFilter.iconSet) {
3409
- parts.push("<iconFilter iconSet=\"".concat(escapeXmlAttr(iconFilter.iconSet), "\" iconId=\"").concat((_d = iconFilter.iconId) !== null && _d !== void 0 ? _d : 0, "\"/>"));
3410
- }
3411
- // A condition filter (greater-than / contains / between / relative-date /
3412
- // above-average …) takes precedence over a value-list and is emitted as
3413
- // <customFilters> or <dynamicFilter>. Falls back to the value list when the
3414
- // condition has no AutoFilter representation.
3415
- var conditionXml = spec.filterCriteria
3509
+ var child = (_f = (_e = (_b = buildColorFilterXml((_a = spec.filterCriteria) === null || _a === void 0 ? void 0 : _a.colorFilter, styleBuilder)) !== null && _b !== void 0 ? _b : buildIconFilterXml((_d = spec.filterCriteria) === null || _d === void 0 ? void 0 : _d.iconFilter)) !== null && _e !== void 0 ? _e : (spec.filterCriteria
3416
3510
  ? buildAutoFilterCriteriaXml(spec.filterCriteria)
3417
- : null;
3418
- if (conditionXml) {
3419
- parts.push(conditionXml);
3420
- }
3421
- else {
3422
- // <filters><filter val=…/></filters>
3423
- var values = (_f = (_e = spec.filterCriteria) === null || _e === void 0 ? void 0 : _e.visibleValues) !== null && _f !== void 0 ? _f : getFilterVisibleValues(spec, range, rows, headerRow, totalRow);
3424
- if (values === null || values === void 0 ? void 0 : values.length) {
3425
- var filters = values
3426
- .map(function (value) { return "<filter val=\"".concat(escapeXmlAttr(value), "\"/>"); })
3427
- .join("");
3428
- parts.push("<filters>".concat(filters, "</filters>"));
3429
- }
3430
- }
3431
- if (!parts.length)
3511
+ : null)) !== null && _f !== void 0 ? _f : buildFilterValueListXml(spec, range, rows, headerRow, totalRow);
3512
+ if (!child)
3432
3513
  return "";
3433
- return "<filterColumn colId=\"".concat(spec.columnIndex, "\">").concat(parts.join(""), "</filterColumn>");
3514
+ return "<filterColumn colId=\"".concat(spec.columnIndex, "\">").concat(child, "</filterColumn>");
3515
+ };
3516
+ /**
3517
+ * `<colorFilter dxfId="N" cellColor="1|0"/>` — Excel matches against the dxf
3518
+ * table; the color is registered as a dxf and referenced by id.
3519
+ */
3520
+ var buildColorFilterXml = function (colorFilter, styleBuilder) {
3521
+ if (!colorFilter || !styleBuilder)
3522
+ return null;
3523
+ var dxfId = colorFilter.mode === "cellColor"
3524
+ ? styleBuilder.registerDifferentialFormat({
3525
+ backgroundColor: colorFilter.color,
3526
+ })
3527
+ : styleBuilder.registerDifferentialFormat({
3528
+ textFormat: { color: colorFilter.color },
3529
+ });
3530
+ if (typeof dxfId !== "number")
3531
+ return null;
3532
+ var cellColorAttr = colorFilter.mode === "cellColor" ? "1" : "0";
3533
+ return "<colorFilter dxfId=\"".concat(dxfId, "\" cellColor=\"").concat(cellColorAttr, "\"/>");
3534
+ };
3535
+ /** `<iconFilter iconSet="…" iconId="…"/>`. */
3536
+ var buildIconFilterXml = function (iconFilter) {
3537
+ var _a;
3538
+ if (!(iconFilter === null || iconFilter === void 0 ? void 0 : iconFilter.iconSet))
3539
+ return null;
3540
+ return "<iconFilter iconSet=\"".concat(escapeXmlAttr(iconFilter.iconSet), "\" iconId=\"").concat((_a = iconFilter.iconId) !== null && _a !== void 0 ? _a : 0, "\"/>");
3541
+ };
3542
+ /**
3543
+ * `<filters>` — the checked values (`blank="1"` for the engine's "(Blanks)"
3544
+ * sentinel; Excel never writes it as a `<filter val>`) plus the date-grouped
3545
+ * `<dateGroupItem>` entries. Without explicit `visibleValues` the list is
3546
+ * derived from the column's cells (every value visible).
3547
+ */
3548
+ var buildFilterValueListXml = function (spec, range, rows, headerRow, totalRow) {
3549
+ var _a, _b, _d, _e;
3550
+ var dateGroups = (_b = (_a = spec.filterCriteria) === null || _a === void 0 ? void 0 : _a.dateGroups) !== null && _b !== void 0 ? _b : [];
3551
+ var values = (_e = (_d = spec.filterCriteria) === null || _d === void 0 ? void 0 : _d.visibleValues) !== null && _e !== void 0 ? _e : (dateGroups.length
3552
+ ? []
3553
+ : getFilterVisibleValues(spec, range, rows, headerRow, totalRow));
3554
+ if (!values.length && !dateGroups.length)
3555
+ return null;
3556
+ var showBlanks = values.includes(BLANK_LABEL);
3557
+ var filters = values
3558
+ .filter(function (value) { return value !== BLANK_LABEL; })
3559
+ .map(function (value) { return "<filter val=\"".concat(escapeXmlAttr(value), "\"/>"); })
3560
+ .join("");
3561
+ var groups = dateGroups
3562
+ .map(function (group) {
3563
+ var e_42, _a;
3564
+ var _b;
3565
+ var attrs = ["year=\"".concat(group.year, "\"")];
3566
+ try {
3567
+ for (var _d = __values(["month", "day", "hour", "minute", "second"]), _e = _d.next(); !_e.done; _e = _d.next()) {
3568
+ var name_2 = _e.value;
3569
+ var value = group[name_2];
3570
+ if (value !== undefined && value !== null) {
3571
+ attrs.push("".concat(name_2, "=\"").concat(value, "\""));
3572
+ }
3573
+ }
3574
+ }
3575
+ catch (e_42_1) { e_42 = { error: e_42_1 }; }
3576
+ finally {
3577
+ try {
3578
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
3579
+ }
3580
+ finally { if (e_42) throw e_42.error; }
3581
+ }
3582
+ attrs.push("dateTimeGrouping=\"".concat(escapeXmlAttr((_b = group.dateTimeGrouping) !== null && _b !== void 0 ? _b : "day"), "\""));
3583
+ return "<dateGroupItem ".concat(attrs.join(" "), "/>");
3584
+ })
3585
+ .join("");
3586
+ var blankAttr = showBlanks ? " blank=\"1\"" : "";
3587
+ return "<filters".concat(blankAttr, ">").concat(filters).concat(groups, "</filters>");
3434
3588
  };
3435
3589
  var gridRangeToRef = function (range) {
3436
3590
  if (!range)
@@ -3698,7 +3852,7 @@ var groupChartsBySheet = function (charts) {
3698
3852
  return result;
3699
3853
  };
3700
3854
  var groupSlicersBySheet = function (slicers) {
3701
- var e_41, _a;
3855
+ var e_43, _a;
3702
3856
  var _b, _d, _e, _f, _g, _h;
3703
3857
  var result = new Map();
3704
3858
  try {
@@ -3721,19 +3875,19 @@ var groupSlicersBySheet = function (slicers) {
3721
3875
  result.set(slicer.position.sheetId, list);
3722
3876
  }
3723
3877
  }
3724
- catch (e_41_1) { e_41 = { error: e_41_1 }; }
3878
+ catch (e_43_1) { e_43 = { error: e_43_1 }; }
3725
3879
  finally {
3726
3880
  try {
3727
3881
  if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
3728
3882
  }
3729
- finally { if (e_41) throw e_41.error; }
3883
+ finally { if (e_43) throw e_43.error; }
3730
3884
  }
3731
3885
  return result;
3732
3886
  };
3733
3887
  var buildConditionalFormattingXml = function (_a) {
3734
- var e_42, _b;
3888
+ var e_44, _b;
3735
3889
  var _d, _e, _f;
3736
- var conditionalFormats = _a.conditionalFormats, sheetId = _a.sheetId, styleBuilder = _a.styleBuilder;
3890
+ var conditionalFormats = _a.conditionalFormats, sheetId = _a.sheetId, styleBuilder = _a.styleBuilder, locale = _a.locale;
3737
3891
  if (!(conditionalFormats === null || conditionalFormats === void 0 ? void 0 : conditionalFormats.length)) {
3738
3892
  return "";
3739
3893
  }
@@ -3785,6 +3939,7 @@ var buildConditionalFormattingXml = function (_a) {
3785
3939
  styleBuilder: styleBuilder,
3786
3940
  priority: basePriority,
3787
3941
  baseCellAddress: baseCellAddress,
3942
+ locale: locale,
3788
3943
  });
3789
3944
  if (!(cfRulesXml === null || cfRulesXml === void 0 ? void 0 : cfRulesXml.length))
3790
3945
  continue;
@@ -3795,12 +3950,12 @@ var buildConditionalFormattingXml = function (_a) {
3795
3950
  parts.push("<conditionalFormatting sqref=\"".concat(sqrefParts.join(" "), "\">").concat(ruleXmlEntries.join(""), "</conditionalFormatting>"));
3796
3951
  }
3797
3952
  }
3798
- catch (e_42_1) { e_42 = { error: e_42_1 }; }
3953
+ catch (e_44_1) { e_44 = { error: e_44_1 }; }
3799
3954
  finally {
3800
3955
  try {
3801
3956
  if (orderedRules_1_1 && !orderedRules_1_1.done && (_b = orderedRules_1.return)) _b.call(orderedRules_1);
3802
3957
  }
3803
- finally { if (e_42) throw e_42.error; }
3958
+ finally { if (e_44) throw e_44.error; }
3804
3959
  }
3805
3960
  return parts.join("");
3806
3961
  };
@@ -3900,7 +4055,7 @@ var buildXlsxSourceCfRuleXml = function (rule, styleBuilder, priority) {
3900
4055
  };
3901
4056
  var buildConditionalFormattingRuleXml = function (_a) {
3902
4057
  var _b;
3903
- var rule = _a.rule, styleBuilder = _a.styleBuilder, priority = _a.priority, baseCellAddress = _a.baseCellAddress;
4058
+ var rule = _a.rule, styleBuilder = _a.styleBuilder, priority = _a.priority, baseCellAddress = _a.baseCellAddress, locale = _a.locale;
3904
4059
  // Round-trip via xlsxSource when present (imported rules). Falls through
3905
4060
  // to synthesizer for rules without source metadata (UI-created).
3906
4061
  if ((_b = rule.xlsxSource) === null || _b === void 0 ? void 0 : _b.type) {
@@ -4038,8 +4193,11 @@ var buildConditionalFormattingRuleXml = function (_a) {
4038
4193
  NUMBER_LESS_THAN_EQ: "lessThanOrEqual",
4039
4194
  };
4040
4195
  var operator = operatorMap[condition.type];
4041
- var first = stripFormula(firstRaw);
4042
- var second = stripFormula(secondRaw);
4196
+ // Typed literals are written the way Excel stores them (`50%` → `0.5`,
4197
+ // a typed date → its serial); formulas lose their `=`; references, names
4198
+ // and function calls are written verbatim.
4199
+ var first = conditionOperandToFormulaText(stripFormula(firstRaw), locale);
4200
+ var second = conditionOperandToFormulaText(stripFormula(secondRaw), locale);
4043
4201
  if ((operator === "between" || operator === "notBetween") && !secondRaw) {
4044
4202
  return undefined;
4045
4203
  }
@@ -4069,17 +4227,12 @@ var buildConditionalFormattingRuleXml = function (_a) {
4069
4227
  DATE_BETWEEN: "between",
4070
4228
  DATE_NOT_BETWEEN: "notBetween",
4071
4229
  };
4230
+ // A typed date (`2024-01-05`, `1/5/2024` in the document locale) is
4231
+ // exported as its serial — what Excel itself stores; the bare text would
4232
+ // be the arithmetic 2024-01-05 = 2022. Formulas lose their `=`;
4233
+ // references and function calls are written verbatim.
4072
4234
  var normalizeDateValue = function (raw) {
4073
- var trimmed = raw.trim();
4074
- if (!trimmed)
4075
- return "";
4076
- if (trimmed.startsWith("=")) {
4077
- return stripFormula(trimmed);
4078
- }
4079
- if (!isNaN(Number(trimmed))) {
4080
- return trimmed;
4081
- }
4082
- return "DATEVALUE(\"".concat(escapeFormulaText(trimmed), "\")");
4235
+ return conditionOperandToFormulaText(stripFormula(raw), locale);
4083
4236
  };
4084
4237
  var first = normalizeDateValue(firstRaw);
4085
4238
  var second = normalizeDateValue(secondRaw);
@@ -4296,8 +4449,8 @@ var buildConditionalFormattingRuleXml = function (_a) {
4296
4449
  return rules.length ? rules : undefined;
4297
4450
  };
4298
4451
  var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
4299
- var anchors, relationships, media, imageIndex, chartIndex, chartExIndex, pictureId, frameId, chartEntries, chartExEntries, orderedAnchors, orderOf, charts_1, charts_1_1, placement, chartExXml, relId_1, chartXml, relId, slicers_1, slicers_1_1, placement, textBoxes_1, textBoxes_1_1, placement, shapes_1, shapes_1_1, placement, placements_1, placements_1_1, placement, dataUrl, buffer, mediaPath, relId, e_43_1, orderedAnchors_1, orderedAnchors_1_1, entry, drawingXml;
4300
- var e_44, _d, e_45, _e, e_46, _f, e_47, _g, e_43, _h, e_48, _j;
4452
+ var anchors, relationships, media, imageIndex, chartIndex, chartExIndex, pictureId, frameId, chartEntries, chartExEntries, orderedAnchors, orderOf, charts_1, charts_1_1, placement, chartExXml, relId_1, chartXml, relId, slicers_1, slicers_1_1, placement, textBoxes_1, textBoxes_1_1, placement, shapes_1, shapes_1_1, placement, placements_1, placements_1_1, placement, dataUrl, buffer, mediaPath, relId, e_45_1, orderedAnchors_1, orderedAnchors_1_1, entry, drawingXml;
4453
+ var e_46, _d, e_47, _e, e_48, _f, e_49, _g, e_45, _h, e_50, _j;
4301
4454
  var placements = _b.placements, textBoxes = _b.textBoxes, _k = _b.shapes, shapes = _k === void 0 ? [] : _k, startImageIndex = _b.startImageIndex, startChartIndex = _b.startChartIndex, _l = _b.startChartExIndex, startChartExIndex = _l === void 0 ? 1 : _l, charts = _b.charts, slicers = _b.slicers, sheet = _b.sheet, sheetNameById = _b.sheetNameById, resolvePivotSourceName = _b.resolvePivotSourceName;
4302
4455
  return __generator(this, function (_m) {
4303
4456
  switch (_m.label) {
@@ -4369,12 +4522,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4369
4522
  frameId += 1;
4370
4523
  }
4371
4524
  }
4372
- catch (e_44_1) { e_44 = { error: e_44_1 }; }
4525
+ catch (e_46_1) { e_46 = { error: e_46_1 }; }
4373
4526
  finally {
4374
4527
  try {
4375
4528
  if (charts_1_1 && !charts_1_1.done && (_d = charts_1.return)) _d.call(charts_1);
4376
4529
  }
4377
- finally { if (e_44) throw e_44.error; }
4530
+ finally { if (e_46) throw e_46.error; }
4378
4531
  }
4379
4532
  try {
4380
4533
  for (slicers_1 = __values(slicers), slicers_1_1 = slicers_1.next(); !slicers_1_1.done; slicers_1_1 = slicers_1.next()) {
@@ -4387,12 +4540,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4387
4540
  frameId += 1;
4388
4541
  }
4389
4542
  }
4390
- catch (e_45_1) { e_45 = { error: e_45_1 }; }
4543
+ catch (e_47_1) { e_47 = { error: e_47_1 }; }
4391
4544
  finally {
4392
4545
  try {
4393
4546
  if (slicers_1_1 && !slicers_1_1.done && (_e = slicers_1.return)) _e.call(slicers_1);
4394
4547
  }
4395
- finally { if (e_45) throw e_45.error; }
4548
+ finally { if (e_47) throw e_47.error; }
4396
4549
  }
4397
4550
  try {
4398
4551
  for (textBoxes_1 = __values(textBoxes), textBoxes_1_1 = textBoxes_1.next(); !textBoxes_1_1.done; textBoxes_1_1 = textBoxes_1.next()) {
@@ -4408,12 +4561,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4408
4561
  frameId += 1;
4409
4562
  }
4410
4563
  }
4411
- catch (e_46_1) { e_46 = { error: e_46_1 }; }
4564
+ catch (e_48_1) { e_48 = { error: e_48_1 }; }
4412
4565
  finally {
4413
4566
  try {
4414
4567
  if (textBoxes_1_1 && !textBoxes_1_1.done && (_f = textBoxes_1.return)) _f.call(textBoxes_1);
4415
4568
  }
4416
- finally { if (e_46) throw e_46.error; }
4569
+ finally { if (e_48) throw e_48.error; }
4417
4570
  }
4418
4571
  try {
4419
4572
  for (shapes_1 = __values(shapes), shapes_1_1 = shapes_1.next(); !shapes_1_1.done; shapes_1_1 = shapes_1.next()) {
@@ -4429,12 +4582,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4429
4582
  frameId += 1;
4430
4583
  }
4431
4584
  }
4432
- catch (e_47_1) { e_47 = { error: e_47_1 }; }
4585
+ catch (e_49_1) { e_49 = { error: e_49_1 }; }
4433
4586
  finally {
4434
4587
  try {
4435
4588
  if (shapes_1_1 && !shapes_1_1.done && (_g = shapes_1.return)) _g.call(shapes_1);
4436
4589
  }
4437
- finally { if (e_47) throw e_47.error; }
4590
+ finally { if (e_49) throw e_49.error; }
4438
4591
  }
4439
4592
  _m.label = 1;
4440
4593
  case 1:
@@ -4476,14 +4629,14 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4476
4629
  return [3 /*break*/, 2];
4477
4630
  case 5: return [3 /*break*/, 8];
4478
4631
  case 6:
4479
- e_43_1 = _m.sent();
4480
- e_43 = { error: e_43_1 };
4632
+ e_45_1 = _m.sent();
4633
+ e_45 = { error: e_45_1 };
4481
4634
  return [3 /*break*/, 8];
4482
4635
  case 7:
4483
4636
  try {
4484
4637
  if (placements_1_1 && !placements_1_1.done && (_h = placements_1.return)) _h.call(placements_1);
4485
4638
  }
4486
- finally { if (e_43) throw e_43.error; }
4639
+ finally { if (e_45) throw e_45.error; }
4487
4640
  return [7 /*endfinally*/];
4488
4641
  case 8:
4489
4642
  orderedAnchors.sort(function (a, b) { return a.order - b.order; });
@@ -4493,12 +4646,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4493
4646
  anchors.push(entry.xml);
4494
4647
  }
4495
4648
  }
4496
- catch (e_48_1) { e_48 = { error: e_48_1 }; }
4649
+ catch (e_50_1) { e_50 = { error: e_50_1 }; }
4497
4650
  finally {
4498
4651
  try {
4499
4652
  if (orderedAnchors_1_1 && !orderedAnchors_1_1.done && (_j = orderedAnchors_1.return)) _j.call(orderedAnchors_1);
4500
4653
  }
4501
- finally { if (e_48) throw e_48.error; }
4654
+ finally { if (e_50) throw e_50.error; }
4502
4655
  }
4503
4656
  drawingXml = "".concat(XML_DECLARATION, "<xdr:wsDr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"").concat(REL_NS, "\">").concat(anchors.join(""), "</xdr:wsDr>");
4504
4657
  return [2 /*return*/, {
@@ -4869,7 +5022,7 @@ var buildTextWithTabs = function (text, rPrXml) {
4869
5022
  .join("");
4870
5023
  };
4871
5024
  var buildTextBodyXml = function (spec) {
4872
- var e_49, _a;
5025
+ var e_51, _a;
4873
5026
  var richText = spec.richText || [];
4874
5027
  var plainText = spec.text || "";
4875
5028
  // Build vertical alignment and wrap attributes
@@ -4910,12 +5063,12 @@ var buildTextBodyXml = function (spec) {
4910
5063
  }
4911
5064
  }
4912
5065
  }
4913
- catch (e_49_1) { e_49 = { error: e_49_1 }; }
5066
+ catch (e_51_1) { e_51 = { error: e_51_1 }; }
4914
5067
  finally {
4915
5068
  try {
4916
5069
  if (richText_1_1 && !richText_1_1.done && (_a = richText_1.return)) _a.call(richText_1);
4917
5070
  }
4918
- finally { if (e_49) throw e_49.error; }
5071
+ finally { if (e_51) throw e_51.error; }
4919
5072
  }
4920
5073
  paragraphsXml = paragraphs
4921
5074
  .filter(function (runs) { return runs.length > 0; })
@@ -5343,7 +5496,7 @@ var buildCalcPrXml = function (iterativeCalculationOptions) {
5343
5496
  }
5344
5497
  return "<calcPr ".concat(attrs.join(" "), "/>");
5345
5498
  };
5346
- var buildWorkbookXml = function (sheets, sheetRelIds, sheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelIds, use1904, externalLinkRelIds, pivotCacheRelIds) {
5499
+ var buildWorkbookXml = function (sheets, sheetRelIds, sheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelIds, use1904, externalLinkRelIds, pivotCacheRelIds, workbookProtection) {
5347
5500
  if (slicerCacheRelIds === void 0) { slicerCacheRelIds = []; }
5348
5501
  if (use1904 === void 0) { use1904 = false; }
5349
5502
  if (externalLinkRelIds === void 0) { externalLinkRelIds = []; }
@@ -5412,10 +5565,57 @@ var buildWorkbookXml = function (sheets, sheetRelIds, sheetNames, namedRanges, i
5412
5565
  var workbookPrXml = use1904
5413
5566
  ? "<workbookPr date1904=\"1\"/>"
5414
5567
  : "<workbookPr/>";
5415
- return "".concat(XML_DECLARATION, "<workbook xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:r=\"").concat(REL_NS, "\">").concat(workbookPrXml).concat(calcPrXml, "<bookViews><workbookView activeTab=\"0\" firstSheet=\"0\"/></bookViews><sheets>").concat(sheetEntries, "</sheets>").concat(definedNamesXml).concat(externalReferencesXml).concat(pivotCachesXml).concat(slicerCachesXml, "</workbook>");
5568
+ // `CT_Workbook` puts `<workbookProtection>` right after `<workbookPr>`.
5569
+ var workbookProtectionXml = buildWorkbookProtectionXml(workbookProtection);
5570
+ return "".concat(XML_DECLARATION, "<workbook xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:r=\"").concat(REL_NS, "\">").concat(workbookPrXml).concat(workbookProtectionXml).concat(calcPrXml, "<bookViews><workbookView activeTab=\"0\" firstSheet=\"0\"/></bookViews><sheets>").concat(sheetEntries, "</sheets>").concat(definedNamesXml).concat(externalReferencesXml).concat(pivotCachesXml).concat(slicerCachesXml, "</workbook>");
5571
+ };
5572
+ /**
5573
+ * `<workbookProtection …/>` from the `workbookProtection` export prop: the
5574
+ * agile hash quartets first, then the legacy password hashes, then the lock
5575
+ * flags — Excel's own attribute order — writing only what the model carries
5576
+ * (flags as `"1"` / `"0"`), so an imported element round-trips verbatim. An
5577
+ * absent model or one with no attribute at all writes nothing. Twin of
5578
+ * `rnc-export`'s `workbook_protection_xml`.
5579
+ */
5580
+ var buildWorkbookProtectionXml = function (protection) {
5581
+ if (!protection)
5582
+ return "";
5583
+ var attrs = [];
5584
+ var text = function (name) {
5585
+ var value = protection[name];
5586
+ if (typeof value === "string" && value) {
5587
+ attrs.push("".concat(name, "=\"").concat(escapeXmlAttr(value), "\""));
5588
+ }
5589
+ };
5590
+ var count = function (name) {
5591
+ var value = protection[name];
5592
+ if (typeof value === "number" && Number.isFinite(value)) {
5593
+ attrs.push("".concat(name, "=\"").concat(Math.trunc(value), "\""));
5594
+ }
5595
+ };
5596
+ var flag = function (name) {
5597
+ var value = protection[name];
5598
+ if (typeof value === "boolean") {
5599
+ attrs.push("".concat(name, "=\"").concat(value ? 1 : 0, "\""));
5600
+ }
5601
+ };
5602
+ text("workbookAlgorithmName");
5603
+ text("workbookHashValue");
5604
+ text("workbookSaltValue");
5605
+ count("workbookSpinCount");
5606
+ text("revisionsAlgorithmName");
5607
+ text("revisionsHashValue");
5608
+ text("revisionsSaltValue");
5609
+ count("revisionsSpinCount");
5610
+ text("workbookPassword");
5611
+ text("revisionsPassword");
5612
+ flag("lockStructure");
5613
+ flag("lockWindows");
5614
+ flag("lockRevision");
5615
+ return attrs.length ? "<workbookProtection ".concat(attrs.join(" "), "/>") : "";
5416
5616
  };
5417
5617
  var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5418
- var e_50, _a, e_51, _b;
5618
+ var e_52, _a, e_53, _b;
5419
5619
  var _d, _e, _f;
5420
5620
  if (printScopes === void 0) { printScopes = []; }
5421
5621
  var entries = [];
@@ -5445,12 +5645,12 @@ var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5445
5645
  ], false));
5446
5646
  }
5447
5647
  }
5448
- catch (e_50_1) { e_50 = { error: e_50_1 }; }
5648
+ catch (e_52_1) { e_52 = { error: e_52_1 }; }
5449
5649
  finally {
5450
5650
  try {
5451
5651
  if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
5452
5652
  }
5453
- finally { if (e_50) throw e_50.error; }
5653
+ finally { if (e_52) throw e_52.error; }
5454
5654
  }
5455
5655
  printScopes.forEach(function (_a, index) {
5456
5656
  var _b;
@@ -5471,12 +5671,35 @@ var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5471
5671
  entries.push("<definedName name=\"".concat(PRINT_TITLES_NAME, "\" localSheetId=\"").concat(index, "\">").concat(escapeXmlText(titles), "</definedName>"));
5472
5672
  }
5473
5673
  });
5674
+ // A sheet-scoped name (`scopeSheetId`) is written with `localSheetId` = the
5675
+ // sheet's position in `<sheets>`; a scope that names no exported sheet
5676
+ // falls back to workbook scope. Excel allows one entry per (name, scope)
5677
+ // pair and repairs the workbook when a pair repeats, so a duplicate (two
5678
+ // scoped `LocalRange`s that both lost their scope, or a multi-area name
5679
+ // imported as one range per area) is written once.
5680
+ var localSheetIdAttr = function (namedRange) {
5681
+ var scope = namedRange.scopeSheetId;
5682
+ if (scope === undefined || scope === null)
5683
+ return "";
5684
+ var sheetName = sheetNameById.get(scope);
5685
+ var index = sheetName ? sheetIndexByName.get(sheetName) : undefined;
5686
+ return index == null ? "" : " localSheetId=\"".concat(index, "\"");
5687
+ };
5688
+ var seenNameScopes = new Set();
5689
+ var claimNameScope = function (name, localSheetId) {
5690
+ var key = "".concat(name.toLowerCase(), "|").concat(localSheetId);
5691
+ if (seenNameScopes.has(key))
5692
+ return false;
5693
+ seenNameScopes.add(key);
5694
+ return true;
5695
+ };
5474
5696
  try {
5475
5697
  for (var _j = __values(namedRanges !== null && namedRanges !== void 0 ? namedRanges : []), _k = _j.next(); !_k.done; _k = _j.next()) {
5476
5698
  var namedRange = _k.value;
5477
5699
  if (!(namedRange === null || namedRange === void 0 ? void 0 : namedRange.name) || isBuiltinPrintName(namedRange.name))
5478
5700
  continue;
5479
5701
  var hiddenAttr = namedRange.hidden ? " hidden=\"1\"" : "";
5702
+ var scopeAttr = localSheetIdAttr(namedRange);
5480
5703
  if ((_f = namedRange.range) === null || _f === void 0 ? void 0 : _f.sheetId) {
5481
5704
  var sheetName = sheetNameById.get(namedRange.range.sheetId);
5482
5705
  if (!sheetName)
@@ -5484,26 +5707,42 @@ var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5484
5707
  var ref = cellRangeToAddress(undefined, namedRange.range);
5485
5708
  if (!ref)
5486
5709
  continue;
5710
+ if (!claimNameScope(namedRange.name, scopeAttr))
5711
+ continue;
5487
5712
  var address = "".concat(escapeSheetName(sheetName), "!").concat(toAbsoluteRef(ref));
5488
- entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(hiddenAttr, ">").concat(escapeXmlText(address), "</definedName>"));
5713
+ entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(scopeAttr).concat(hiddenAttr, ">").concat(escapeXmlText(address), "</definedName>"));
5489
5714
  continue;
5490
5715
  }
5716
+ // A constant name reaches us as text (`"Hello"`, `0.2`) or, when the
5717
+ // XML layer coerced it, as a number / boolean — both are the same
5718
+ // `<definedName>` body in Excel.
5491
5719
  var rawValue = namedRange.value;
5492
- if (typeof rawValue !== "string")
5720
+ var valueText = typeof rawValue === "string"
5721
+ ? rawValue
5722
+ : typeof rawValue === "number" || typeof rawValue === "boolean"
5723
+ ? String(rawValue)
5724
+ : undefined;
5725
+ if (valueText === undefined)
5493
5726
  continue;
5494
- var trimmed = rawValue.trim();
5727
+ var trimmed = valueText.trim();
5495
5728
  if (!trimmed)
5496
5729
  continue;
5497
5730
  var expression = trimmed.startsWith("=") ? trimmed.slice(1) : trimmed;
5498
- entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(hiddenAttr, ">").concat(escapeXmlText(expression), "</definedName>"));
5731
+ if (!claimNameScope(namedRange.name, scopeAttr))
5732
+ continue;
5733
+ // A formula-valued name (`Dbl` = `LAMBDA(x,x*2)`) is stored with the same
5734
+ // markers as a cell formula: `_xlfn.LAMBDA(_xlpm.x,_xlpm.x*2)`.
5735
+ entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(scopeAttr).concat(hiddenAttr, ">").concat(escapeXmlText(isAFormulaExpression(expression)
5736
+ ? sanitizeFormulaText(expression)
5737
+ : expression), "</definedName>"));
5499
5738
  }
5500
5739
  }
5501
- catch (e_51_1) { e_51 = { error: e_51_1 }; }
5740
+ catch (e_53_1) { e_53 = { error: e_53_1 }; }
5502
5741
  finally {
5503
5742
  try {
5504
5743
  if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
5505
5744
  }
5506
- finally { if (e_51) throw e_51.error; }
5745
+ finally { if (e_53) throw e_53.error; }
5507
5746
  }
5508
5747
  if (!entries.length)
5509
5748
  return "";
@@ -5538,11 +5777,12 @@ var buildWorkbookSlicerCachesXml = function (slicerCacheRelIds) {
5538
5777
  };
5539
5778
  var buildWorkbookRelationships = function (
5540
5779
  /** One entry per sheet in `<sheets>` order; `target` is relative to `xl/`. */
5541
- sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons) {
5780
+ sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons, hasSheetMetadata) {
5542
5781
  if (slicerCacheCount === void 0) { slicerCacheCount = 0; }
5543
5782
  if (externalLinkCount === void 0) { externalLinkCount = 0; }
5544
5783
  if (pivotCacheCount === void 0) { pivotCacheCount = 0; }
5545
5784
  if (hasPersons === void 0) { hasPersons = false; }
5785
+ if (hasSheetMetadata === void 0) { hasSheetMetadata = false; }
5546
5786
  var relationships = [];
5547
5787
  var sheetRelIds = [];
5548
5788
  var slicerCacheRelIds = [];
@@ -5559,6 +5799,9 @@ sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons) {
5559
5799
  relationships.push("<Relationship Id=\"".concat(themeId, "\" Type=\"").concat(REL_NS, "/theme\" Target=\"theme/theme1.xml\"/>"));
5560
5800
  relationships.push("<Relationship Id=\"".concat(sharedStringsId, "\" Type=\"").concat(REL_NS, "/sharedStrings\" Target=\"sharedStrings.xml\"/>"));
5561
5801
  var nextRelId = sheetCount + 4;
5802
+ if (hasSheetMetadata) {
5803
+ relationships.push("<Relationship Id=\"rId".concat(nextRelId++, "\" Type=\"").concat(REL_NS, "/sheetMetadata\" Target=\"metadata.xml\"/>"));
5804
+ }
5562
5805
  for (var i = 0; i < slicerCacheCount; i++) {
5563
5806
  var relId = "rId".concat(nextRelId++);
5564
5807
  slicerCacheRelIds.push(relId);
@@ -5596,7 +5839,10 @@ sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons) {
5596
5839
  };
5597
5840
  };
5598
5841
  var buildContentTypesXml = function (_a) {
5599
- var worksheetCount = _a.worksheetCount, _b = _a.chartsheetCount, chartsheetCount = _b === void 0 ? 0 : _b, tableCount = _a.tableCount, drawingSheets = _a.drawingSheets, mediaExtensions = _a.mediaExtensions, chartCount = _a.chartCount, _d = _a.chartExCount, chartExCount = _d === void 0 ? 0 : _d, _e = _a.slicerCount, slicerCount = _e === void 0 ? 0 : _e, _f = _a.slicerCacheCount, slicerCacheCount = _f === void 0 ? 0 : _f, _g = _a.pivotTableCount, pivotTableCount = _g === void 0 ? 0 : _g, _h = _a.pivotCacheCount, pivotCacheCount = _h === void 0 ? 0 : _h, _j = _a.commentsSheets, commentsSheets = _j === void 0 ? [] : _j, _k = _a.threadedCommentsSheets, threadedCommentsSheets = _k === void 0 ? [] : _k, _l = _a.hasPersons, hasPersons = _l === void 0 ? false : _l, _m = _a.externalLinkCount, externalLinkCount = _m === void 0 ? 0 : _m, _o = _a.hasVmlDrawings, hasVmlDrawings = _o === void 0 ? false : _o, _p = _a.ctrlPropCount, ctrlPropCount = _p === void 0 ? 0 : _p;
5842
+ var worksheetCount = _a.worksheetCount, _b = _a.chartsheetCount, chartsheetCount = _b === void 0 ? 0 : _b, tableCount = _a.tableCount, drawingSheets = _a.drawingSheets, mediaExtensions = _a.mediaExtensions, chartCount = _a.chartCount, _d = _a.chartExCount, chartExCount = _d === void 0 ? 0 : _d, _e = _a.slicerCount, slicerCount = _e === void 0 ? 0 : _e, _f = _a.slicerCacheCount, slicerCacheCount = _f === void 0 ? 0 : _f, _g = _a.pivotTableCount, pivotTableCount = _g === void 0 ? 0 : _g, _h = _a.pivotCacheCount, pivotCacheCount = _h === void 0 ? 0 : _h, _j = _a.commentsSheets, commentsSheets = _j === void 0 ? [] : _j, _k = _a.threadedCommentsSheets, threadedCommentsSheets = _k === void 0 ? [] : _k, _l = _a.hasPersons, hasPersons = _l === void 0 ? false : _l, _m = _a.externalLinkCount, externalLinkCount = _m === void 0 ? 0 : _m, _o = _a.hasVmlDrawings, hasVmlDrawings = _o === void 0 ? false : _o, _p = _a.ctrlPropCount, ctrlPropCount = _p === void 0 ? 0 : _p, _q = _a.hasSheetMetadata, hasSheetMetadata = _q === void 0 ? false : _q;
5843
+ var metadataOverride = hasSheetMetadata
5844
+ ? "<Override PartName=\"/xl/metadata.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml\"/>"
5845
+ : "";
5600
5846
  var sheetOverrides = Array.from({ length: worksheetCount }, function (_, index) {
5601
5847
  return "<Override PartName=\"/xl/worksheets/sheet".concat(index + 1, ".xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>");
5602
5848
  }).join("");
@@ -5657,7 +5903,7 @@ var buildContentTypesXml = function (_a) {
5657
5903
  var ctrlPropOverrides = Array.from({ length: ctrlPropCount }, function (_, index) {
5658
5904
  return "<Override PartName=\"/xl/ctrlProps/ctrlProp".concat(index + 1, ".xml\" ContentType=\"").concat(CTRL_PROP_CONTENT_TYPE, "\"/>");
5659
5905
  }).join("");
5660
- return "".concat(XML_DECLARATION, "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/>").concat(vmlDefault).concat(mediaDefaults, "<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>").concat(sheetOverrides).concat(chartsheetOverrides).concat(tableOverrides).concat(drawingOverrides).concat(chartOverrides).concat(chartExOverrides).concat(slicerOverrides).concat(slicerCacheOverrides).concat(pivotTableOverrides).concat(pivotCacheOverrides).concat(externalLinkOverrides).concat(ctrlPropOverrides).concat(commentsOverrides).concat(threadedCommentsOverrides).concat(personOverride, "<Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/><Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/></Types>");
5906
+ return "".concat(XML_DECLARATION, "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/>").concat(vmlDefault).concat(mediaDefaults, "<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>").concat(sheetOverrides).concat(chartsheetOverrides).concat(tableOverrides).concat(drawingOverrides).concat(chartOverrides).concat(chartExOverrides).concat(slicerOverrides).concat(slicerCacheOverrides).concat(pivotTableOverrides).concat(pivotCacheOverrides).concat(externalLinkOverrides).concat(ctrlPropOverrides).concat(commentsOverrides).concat(threadedCommentsOverrides).concat(personOverride).concat(metadataOverride, "<Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/><Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/></Types>");
5661
5907
  };
5662
5908
  var buildRootRelationshipsXml = function () {
5663
5909
  return "".concat(XML_DECLARATION, "<Relationships xmlns=\"").concat(PACKAGE_REL_NS, "\"><Relationship Id=\"rId1\" Type=\"").concat(REL_NS, "/officeDocument\" Target=\"xl/workbook.xml\"/><Relationship Id=\"rId2\" Type=\"").concat(REL_NS, "/extended-properties\" Target=\"docProps/app.xml\"/><Relationship Id=\"rId3\" Type=\"").concat(REL_NS, "/core-properties\" Target=\"docProps/core.xml\"/></Relationships>");