@paperjsx/json-to-xlsx-pro 0.0.1

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 (175) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +61 -0
  3. package/dist/assembly/xlsx-assembler.d.ts +53 -0
  4. package/dist/assembly/xlsx-assembler.d.ts.map +1 -0
  5. package/dist/benchmarks/phase2.d.ts +72 -0
  6. package/dist/benchmarks/phase2.d.ts.map +1 -0
  7. package/dist/benchmarks/phase2.js +14 -0
  8. package/dist/benchmarks/phase2.js.map +7 -0
  9. package/dist/benchmarks/report.d.ts +21 -0
  10. package/dist/benchmarks/report.d.ts.map +1 -0
  11. package/dist/benchmarks/report.js +13 -0
  12. package/dist/benchmarks/report.js.map +7 -0
  13. package/dist/benchmarks/rigorous.d.ts +85 -0
  14. package/dist/benchmarks/rigorous.d.ts.map +1 -0
  15. package/dist/benchmarks/rigorous.js +534 -0
  16. package/dist/benchmarks/rigorous.js.map +7 -0
  17. package/dist/chaos-lab/index.d.ts +69 -0
  18. package/dist/chaos-lab/index.d.ts.map +1 -0
  19. package/dist/chaos-lab/index.js +1696 -0
  20. package/dist/chaos-lab/index.js.map +7 -0
  21. package/dist/chunk-2IVXCH6I.js +1002 -0
  22. package/dist/chunk-2IVXCH6I.js.map +7 -0
  23. package/dist/chunk-IYMS2CLX.js +478 -0
  24. package/dist/chunk-IYMS2CLX.js.map +7 -0
  25. package/dist/chunk-PQSLPEN5.js +290 -0
  26. package/dist/chunk-PQSLPEN5.js.map +7 -0
  27. package/dist/chunk-QDWDSM74.js +142 -0
  28. package/dist/chunk-QDWDSM74.js.map +7 -0
  29. package/dist/chunk-S5RMAWLC.js +25347 -0
  30. package/dist/chunk-S5RMAWLC.js.map +7 -0
  31. package/dist/chunk-Z2JSZFNG.js +308 -0
  32. package/dist/chunk-Z2JSZFNG.js.map +7 -0
  33. package/dist/diagnostics/corruption.d.ts +9 -0
  34. package/dist/diagnostics/corruption.d.ts.map +1 -0
  35. package/dist/diagnostics/workloads.d.ts +6 -0
  36. package/dist/diagnostics/workloads.d.ts.map +1 -0
  37. package/dist/diff/document-diff.d.ts +5 -0
  38. package/dist/diff/document-diff.d.ts.map +1 -0
  39. package/dist/document-diff/src/index.d.ts +50 -0
  40. package/dist/document-diff/src/index.d.ts.map +1 -0
  41. package/dist/errors.d.ts +35 -0
  42. package/dist/errors.d.ts.map +1 -0
  43. package/dist/fixtures/phase1.d.ts +14 -0
  44. package/dist/fixtures/phase1.d.ts.map +1 -0
  45. package/dist/fixtures/phase2.d.ts +9 -0
  46. package/dist/fixtures/phase2.d.ts.map +1 -0
  47. package/dist/fixtures/phase3.d.ts +9 -0
  48. package/dist/fixtures/phase3.d.ts.map +1 -0
  49. package/dist/fixtures/phase4.d.ts +10 -0
  50. package/dist/fixtures/phase4.d.ts.map +1 -0
  51. package/dist/fixtures/phase5.d.ts +9 -0
  52. package/dist/fixtures/phase5.d.ts.map +1 -0
  53. package/dist/formulas/builder.d.ts +91 -0
  54. package/dist/formulas/builder.d.ts.map +1 -0
  55. package/dist/formulas/evaluator.d.ts +25 -0
  56. package/dist/formulas/evaluator.d.ts.map +1 -0
  57. package/dist/formulas/shift.d.ts +14 -0
  58. package/dist/formulas/shift.d.ts.map +1 -0
  59. package/dist/index-pro.d.ts +12 -0
  60. package/dist/index-pro.d.ts.map +1 -0
  61. package/dist/index.d.ts +41 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +2167 -0
  64. package/dist/index.js.map +7 -0
  65. package/dist/layout/column-width.d.ts +32 -0
  66. package/dist/layout/column-width.d.ts.map +1 -0
  67. package/dist/layout/row-height.d.ts +3 -0
  68. package/dist/layout/row-height.d.ts.map +1 -0
  69. package/dist/preflight.d.ts +31 -0
  70. package/dist/preflight.d.ts.map +1 -0
  71. package/dist/public-quality-types.d.ts +44 -0
  72. package/dist/public-quality-types.d.ts.map +1 -0
  73. package/dist/quality/accessibility-contract.d.ts +38 -0
  74. package/dist/quality/accessibility-contract.d.ts.map +1 -0
  75. package/dist/quality/accessibility.d.ts +33 -0
  76. package/dist/quality/accessibility.d.ts.map +1 -0
  77. package/dist/quality/shared-quality.d.ts +4 -0
  78. package/dist/quality/shared-quality.d.ts.map +1 -0
  79. package/dist/quality/structural-validation.d.ts +11 -0
  80. package/dist/quality/structural-validation.d.ts.map +1 -0
  81. package/dist/quality/workbook-quality.d.ts +63 -0
  82. package/dist/quality/workbook-quality.d.ts.map +1 -0
  83. package/dist/render-metrics.d.ts +67 -0
  84. package/dist/render-metrics.d.ts.map +1 -0
  85. package/dist/render-plan.d.ts +40 -0
  86. package/dist/render-plan.d.ts.map +1 -0
  87. package/dist/serializers/chart-serializer.d.ts +3 -0
  88. package/dist/serializers/chart-serializer.d.ts.map +1 -0
  89. package/dist/serializers/comment-serializer.d.ts +12 -0
  90. package/dist/serializers/comment-serializer.d.ts.map +1 -0
  91. package/dist/serializers/doc-props-serializer.d.ts +5 -0
  92. package/dist/serializers/doc-props-serializer.d.ts.map +1 -0
  93. package/dist/serializers/drawing-serializer.d.ts +24 -0
  94. package/dist/serializers/drawing-serializer.d.ts.map +1 -0
  95. package/dist/serializers/package-serializer.d.ts +13 -0
  96. package/dist/serializers/package-serializer.d.ts.map +1 -0
  97. package/dist/serializers/pivot-serializer.d.ts +37 -0
  98. package/dist/serializers/pivot-serializer.d.ts.map +1 -0
  99. package/dist/serializers/shared-strings.d.ts +11 -0
  100. package/dist/serializers/shared-strings.d.ts.map +1 -0
  101. package/dist/serializers/sheet-serializer.d.ts +58 -0
  102. package/dist/serializers/sheet-serializer.d.ts.map +1 -0
  103. package/dist/serializers/sheet-xml-builder.d.ts +33 -0
  104. package/dist/serializers/sheet-xml-builder.d.ts.map +1 -0
  105. package/dist/serializers/style-registry.d.ts +2 -0
  106. package/dist/serializers/style-registry.d.ts.map +1 -0
  107. package/dist/serializers/table-serializer.d.ts +20 -0
  108. package/dist/serializers/table-serializer.d.ts.map +1 -0
  109. package/dist/serializers/theme-serializer.d.ts +3 -0
  110. package/dist/serializers/theme-serializer.d.ts.map +1 -0
  111. package/dist/serializers/workbook-serializer.d.ts +16 -0
  112. package/dist/serializers/workbook-serializer.d.ts.map +1 -0
  113. package/dist/serializers/worksheet-rels-serializer.d.ts +7 -0
  114. package/dist/serializers/worksheet-rels-serializer.d.ts.map +1 -0
  115. package/dist/source-js-extension-loader.mjs +44 -0
  116. package/dist/spreadsheet-engine.d.ts +50 -0
  117. package/dist/spreadsheet-engine.d.ts.map +1 -0
  118. package/dist/styles/border-serializer.d.ts +6 -0
  119. package/dist/styles/border-serializer.d.ts.map +1 -0
  120. package/dist/styles/color.d.ts +5 -0
  121. package/dist/styles/color.d.ts.map +1 -0
  122. package/dist/styles/component-registry.d.ts +13 -0
  123. package/dist/styles/component-registry.d.ts.map +1 -0
  124. package/dist/styles/conditional-formatting.d.ts +8 -0
  125. package/dist/styles/conditional-formatting.d.ts.map +1 -0
  126. package/dist/styles/fill-serializer.d.ts +9 -0
  127. package/dist/styles/fill-serializer.d.ts.map +1 -0
  128. package/dist/styles/font-serializer.d.ts +11 -0
  129. package/dist/styles/font-serializer.d.ts.map +1 -0
  130. package/dist/styles/numfmt-registry.d.ts +7 -0
  131. package/dist/styles/numfmt-registry.d.ts.map +1 -0
  132. package/dist/styles/presets.d.ts +190 -0
  133. package/dist/styles/presets.d.ts.map +1 -0
  134. package/dist/styles/style-registry.d.ts +24 -0
  135. package/dist/styles/style-registry.d.ts.map +1 -0
  136. package/dist/styles/style-utils.d.ts +11 -0
  137. package/dist/styles/style-utils.d.ts.map +1 -0
  138. package/dist/template-assembler.d.ts +26 -0
  139. package/dist/template-assembler.d.ts.map +1 -0
  140. package/dist/template-parser.d.ts +96 -0
  141. package/dist/template-parser.d.ts.map +1 -0
  142. package/dist/types/spreadsheet-ast.d.ts +470 -0
  143. package/dist/types/spreadsheet-ast.d.ts.map +1 -0
  144. package/dist/utils/cell-ref.d.ts +21 -0
  145. package/dist/utils/cell-ref.d.ts.map +1 -0
  146. package/dist/utils/date.d.ts +32 -0
  147. package/dist/utils/date.d.ts.map +1 -0
  148. package/dist/utils/hyperlinks.d.ts +16 -0
  149. package/dist/utils/hyperlinks.d.ts.map +1 -0
  150. package/dist/utils/xml.d.ts +7 -0
  151. package/dist/utils/xml.d.ts.map +1 -0
  152. package/dist/validation/spreadsheet-schema.d.ts +1513 -0
  153. package/dist/validation/spreadsheet-schema.d.ts.map +1 -0
  154. package/dist/workers/sheet-serialization-worker-pool.d.ts +32 -0
  155. package/dist/workers/sheet-serialization-worker-pool.d.ts.map +1 -0
  156. package/dist/workers/sheet-serializer-worker.d.ts +2 -0
  157. package/dist/workers/sheet-serializer-worker.d.ts.map +1 -0
  158. package/dist/workers/sheet-serializer-worker.js +2565 -0
  159. package/dist/workers/sheet-serializer-worker.js.map +7 -0
  160. package/dist/worksheet/structure.d.ts +33 -0
  161. package/dist/worksheet/structure.d.ts.map +1 -0
  162. package/dist-pro/benchmarks/phase2.js +1 -0
  163. package/dist-pro/benchmarks/report.js +1 -0
  164. package/dist-pro/benchmarks/rigorous.js +2 -0
  165. package/dist-pro/chaos-lab/index.js +2 -0
  166. package/dist-pro/chunk-FFIHITWB.js +1 -0
  167. package/dist-pro/chunk-INDNGGXB.js +2 -0
  168. package/dist-pro/chunk-K2MQYNU6.js +1 -0
  169. package/dist-pro/chunk-MEZHQFH3.js +2 -0
  170. package/dist-pro/chunk-RB42Q36L.js +1 -0
  171. package/dist-pro/chunk-WYTH4W4N.js +48 -0
  172. package/dist-pro/index.js +3 -0
  173. package/dist-pro/source-js-extension-loader.mjs +44 -0
  174. package/dist-pro/workers/sheet-serializer-worker.js +3 -0
  175. package/package.json +62 -0
@@ -0,0 +1,2565 @@
1
+ // src/workers/sheet-serializer-worker.ts
2
+ import { parentPort } from "node:worker_threads";
3
+
4
+ // src/types/spreadsheet-ast.ts
5
+ function isRichTextValue(value) {
6
+ return Array.isArray(value);
7
+ }
8
+ function isErrorValue(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value) && "error" in value;
10
+ }
11
+
12
+ // src/styles/presets.ts
13
+ var PRESETS = {
14
+ header: {
15
+ font: { bold: true, color: "#FFFFFF", size: 11, family: "Calibri" },
16
+ fill: { color: "#4472C4" },
17
+ border: { bottom: { style: "medium", color: "#2F5597" } },
18
+ alignment: { horizontal: "center", vertical: "center" }
19
+ },
20
+ headerDark: {
21
+ font: { bold: true, color: "#FFFFFF", size: 11 },
22
+ fill: { color: "#1F3864" },
23
+ border: { bottom: { style: "medium", color: "#0D2240" } },
24
+ alignment: { horizontal: "center", vertical: "center" }
25
+ },
26
+ headerGreen: {
27
+ font: { bold: true, color: "#FFFFFF", size: 11 },
28
+ fill: { color: "#548235" },
29
+ border: { bottom: { style: "medium", color: "#375623" } },
30
+ alignment: { horizontal: "center", vertical: "center" }
31
+ },
32
+ subheader: {
33
+ font: { bold: true, size: 10, color: "#1F3864" },
34
+ fill: { color: "#D6E4F0" },
35
+ border: { bottom: { style: "thin", color: "#9DC3E6" } }
36
+ },
37
+ total: {
38
+ font: { bold: true },
39
+ border: {
40
+ top: { style: "thin", color: "#333333" },
41
+ bottom: { style: "double", color: "#333333" }
42
+ },
43
+ numberFormat: "#,##0.00"
44
+ },
45
+ subtotal: {
46
+ font: { bold: true, color: "#44546A" },
47
+ border: { top: { style: "thin", color: "#D9D9D9" } },
48
+ numberFormat: "#,##0.00"
49
+ },
50
+ currency: { alignment: { horizontal: "right" }, numberFormat: "$#,##0.00" },
51
+ currencyKRW: { alignment: { horizontal: "right" }, numberFormat: "\u20A9#,##0" },
52
+ currencyEUR: { alignment: { horizontal: "right" }, numberFormat: "\u20AC#,##0.00" },
53
+ percentage: { alignment: { horizontal: "right" }, numberFormat: "0.0%" },
54
+ percentageChange: {
55
+ alignment: { horizontal: "right" },
56
+ numberFormat: "+0.0%;-0.0%;0.0%"
57
+ },
58
+ integer: { alignment: { horizontal: "right" }, numberFormat: "#,##0" },
59
+ decimal2: { alignment: { horizontal: "right" }, numberFormat: "#,##0.00" },
60
+ date: { numberFormat: "yyyy-mm-dd" },
61
+ datetime: { numberFormat: "yyyy-mm-dd hh:mm" },
62
+ warning: { font: { color: "#9C5700" }, fill: { color: "#FFEB9C" } },
63
+ error: { font: { color: "#9C0006" }, fill: { color: "#FFC7CE" } },
64
+ success: { font: { color: "#006100" }, fill: { color: "#C6EFCE" } },
65
+ neutral: { font: { color: "#44546A" }, fill: { color: "#F2F2F2" } }
66
+ };
67
+ var PRESET_NAMES = Object.keys(PRESETS);
68
+
69
+ // src/styles/style-utils.ts
70
+ var resolvedInlineStyleCache = /* @__PURE__ */ new WeakMap();
71
+ var resolvedInlineStyleValueCache = /* @__PURE__ */ new Map();
72
+ function fontStyleKey(font) {
73
+ if (!font) {
74
+ return "";
75
+ }
76
+ return [
77
+ font.family ?? "",
78
+ font.size ?? "",
79
+ font.bold ? 1 : 0,
80
+ font.italic ? 1 : 0,
81
+ font.underline === true ? "single" : font.underline ?? "",
82
+ font.strikethrough ? 1 : 0,
83
+ font.color ?? "",
84
+ font.vertAlign ?? "",
85
+ font.charset ?? ""
86
+ ].join("|");
87
+ }
88
+ function fillStyleKey(fill) {
89
+ if (!fill) {
90
+ return "";
91
+ }
92
+ return [
93
+ fill.type ?? "",
94
+ fill.patternType ?? "",
95
+ fill.color ?? "",
96
+ fill.fgColor ?? "",
97
+ fill.bgColor ?? ""
98
+ ].join("|");
99
+ }
100
+ function borderEdgeKey(edge) {
101
+ if (!edge) {
102
+ return "";
103
+ }
104
+ return `${edge.style ?? ""}:${edge.color ?? ""}`;
105
+ }
106
+ function borderDiagonalKey(diagonal) {
107
+ if (!diagonal) {
108
+ return "";
109
+ }
110
+ return `${diagonal.style ?? ""}:${diagonal.color ?? ""}:${diagonal.direction ?? ""}`;
111
+ }
112
+ function borderStyleKey(border) {
113
+ if (!border) {
114
+ return "";
115
+ }
116
+ return [
117
+ borderEdgeKey(border.left),
118
+ borderEdgeKey(border.right),
119
+ borderEdgeKey(border.top),
120
+ borderEdgeKey(border.bottom),
121
+ borderDiagonalKey(border.diagonal)
122
+ ].join("|");
123
+ }
124
+ function alignmentStyleKey(alignment) {
125
+ if (!alignment) {
126
+ return "";
127
+ }
128
+ return [
129
+ alignment.horizontal ?? "",
130
+ alignment.vertical ?? "",
131
+ alignment.wrapText ? 1 : 0,
132
+ alignment.textRotation ?? "",
133
+ alignment.indent ?? "",
134
+ alignment.shrinkToFit ? 1 : 0,
135
+ alignment.readingOrder ?? ""
136
+ ].join("|");
137
+ }
138
+ function protectionStyleKey(protection) {
139
+ if (!protection) {
140
+ return "";
141
+ }
142
+ return [
143
+ protection.locked === void 0 ? "" : protection.locked ? 1 : 0,
144
+ protection.hidden === void 0 ? "" : protection.hidden ? 1 : 0
145
+ ].join("|");
146
+ }
147
+ function inlineStyleKey(style) {
148
+ return [
149
+ style.numberFormat ?? "",
150
+ fontStyleKey(style.font),
151
+ fillStyleKey(style.fill),
152
+ borderStyleKey(style.border),
153
+ alignmentStyleKey(style.alignment),
154
+ protectionStyleKey(style.protection)
155
+ ].join("||");
156
+ }
157
+ function isObject(value) {
158
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
159
+ }
160
+ function deepMerge(base, override) {
161
+ if (base === void 0) return override;
162
+ if (override === void 0) return base;
163
+ if (!isObject(base) || !isObject(override)) {
164
+ return override;
165
+ }
166
+ const result = { ...base };
167
+ for (const [key, value] of Object.entries(override)) {
168
+ if (value === void 0) {
169
+ continue;
170
+ }
171
+ result[key] = key in result ? deepMerge(result[key], value) : value;
172
+ }
173
+ return result;
174
+ }
175
+ function resolveStyleInput(style) {
176
+ if (!style) {
177
+ return void 0;
178
+ }
179
+ if (typeof style === "string") {
180
+ return PRESETS[style];
181
+ }
182
+ const presetStyle = style.preset ? PRESETS[style.preset] : void 0;
183
+ const { preset: _preset, ...rest } = style;
184
+ void _preset;
185
+ return deepMerge(presetStyle, rest);
186
+ }
187
+ function resolveNumberFormatAlias(numberFormat) {
188
+ if (!numberFormat) {
189
+ return void 0;
190
+ }
191
+ const aliasMap = {
192
+ currency: "$#,##0.00",
193
+ "currency:EUR": "\u20AC#,##0.00",
194
+ "currency:GBP": "\xA3#,##0.00",
195
+ "currency:KRW": "\u20A9#,##0",
196
+ "currency:JPY": "\xA5#,##0",
197
+ percentage: "0.0%",
198
+ "percentage:0": "0%",
199
+ "percentage:2": "0.00%",
200
+ date: "yyyy-mm-dd",
201
+ "date:us": "m/d/yyyy",
202
+ "date:eu": "d/m/yyyy",
203
+ "date:kr": "yyyy\uB144 m\uC6D4 d\uC77C",
204
+ datetime: "yyyy-mm-dd hh:mm",
205
+ time: "h:mm:ss",
206
+ accounting: '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)',
207
+ "number:0": "#,##0",
208
+ "number:2": "#,##0.00",
209
+ scientific: "0.00E+00",
210
+ text: "@"
211
+ };
212
+ return aliasMap[numberFormat] ?? numberFormat;
213
+ }
214
+ function resolveCellStyle(style, value, sheetBaseStyle) {
215
+ if (sheetBaseStyle === void 0 && style !== void 0 && typeof style !== "string" && !style.preset && !(value instanceof Date && !style.numberFormat)) {
216
+ if (!style.numberFormat) {
217
+ return style;
218
+ }
219
+ const cached = resolvedInlineStyleCache.get(style);
220
+ if (cached) {
221
+ return cached;
222
+ }
223
+ const valueKey = inlineStyleKey(style);
224
+ const cachedByValue = resolvedInlineStyleValueCache.get(valueKey);
225
+ if (cachedByValue) {
226
+ resolvedInlineStyleCache.set(style, cachedByValue);
227
+ return cachedByValue;
228
+ }
229
+ const resolvedInline = {
230
+ ...style,
231
+ numberFormat: resolveNumberFormatAlias(style.numberFormat)
232
+ };
233
+ resolvedInlineStyleCache.set(style, resolvedInline);
234
+ resolvedInlineStyleValueCache.set(valueKey, resolvedInline);
235
+ return resolvedInline;
236
+ }
237
+ const baseStyle = resolveStyleInput(sheetBaseStyle);
238
+ let resolved = deepMerge(baseStyle, resolveStyleInput(style));
239
+ if (value instanceof Date && !resolved?.numberFormat) {
240
+ resolved = deepMerge(resolved, { numberFormat: "date" });
241
+ }
242
+ if (resolved?.numberFormat) {
243
+ resolved = {
244
+ ...resolved,
245
+ numberFormat: resolveNumberFormatAlias(resolved.numberFormat)
246
+ };
247
+ }
248
+ return resolved;
249
+ }
250
+ function normalizeFont(font, defaults) {
251
+ return {
252
+ family: font?.family ?? defaults.family,
253
+ size: font?.size ?? defaults.size,
254
+ bold: font?.bold,
255
+ italic: font?.italic,
256
+ underline: font?.underline,
257
+ strikethrough: font?.strikethrough,
258
+ color: font?.color,
259
+ vertAlign: font?.vertAlign,
260
+ charset: font?.charset
261
+ };
262
+ }
263
+ function normalizeFill(fill) {
264
+ if (!fill) {
265
+ return void 0;
266
+ }
267
+ if (fill.color) {
268
+ return {
269
+ type: "solid",
270
+ fgColor: fill.color,
271
+ bgColor: fill.bgColor,
272
+ patternType: "solid"
273
+ };
274
+ }
275
+ return {
276
+ type: fill.type ?? "solid",
277
+ fgColor: fill.fgColor,
278
+ bgColor: fill.bgColor,
279
+ patternType: fill.patternType ?? (fill.type === "pattern" ? "darkGray" : "solid")
280
+ };
281
+ }
282
+
283
+ // src/worksheet/structure.ts
284
+ function cellKey(row, col) {
285
+ return `${row}:${col}`;
286
+ }
287
+ function cloneCell(cell) {
288
+ return {
289
+ ...cell,
290
+ value: cell.value,
291
+ style: cell.style
292
+ };
293
+ }
294
+ function mergeStylePatch(cell, patch) {
295
+ const baseStyle = resolveStyleInput(cell?.style);
296
+ return {
297
+ ...cell ?? { value: null },
298
+ style: deepMerge(baseStyle, patch)
299
+ };
300
+ }
301
+ function quoteSheetName(sheetName) {
302
+ if (/^[A-Za-z_][A-Za-z0-9_.]*$/.test(sheetName)) {
303
+ return sheetName;
304
+ }
305
+ return `'${sheetName.replaceAll("'", "''")}'`;
306
+ }
307
+ function resolveAutoFilterRef(sheet, maxRow, maxCol) {
308
+ if (!sheet.autoFilter) {
309
+ return void 0;
310
+ }
311
+ if (sheet.autoFilter === true) {
312
+ if (maxRow < 0 || maxCol < 0) {
313
+ return "A1:A1";
314
+ }
315
+ return absRangeRef(0, 0, maxRow, maxCol).replaceAll("$", "");
316
+ }
317
+ return sheet.autoFilter.ref;
318
+ }
319
+ function compileSheetStructure(sheet) {
320
+ const occupied = /* @__PURE__ */ new Set();
321
+ const originCellMap = /* @__PURE__ */ new Map();
322
+ const spanMerges = [];
323
+ let maxRow = sheet.rows.length - 1;
324
+ let maxCol = Math.max(-1, (sheet.columns?.length ?? 0) - 1);
325
+ sheet.rows.forEach((row, rowIndex) => {
326
+ let cursor = 0;
327
+ row.cells.forEach((cellInput) => {
328
+ while (occupied.has(cellKey(rowIndex, cursor))) {
329
+ cursor += 1;
330
+ }
331
+ const cell = cloneCell(cellInput);
332
+ const colSpan = cell.colSpan ?? 1;
333
+ const rowSpan = cell.rowSpan ?? 1;
334
+ originCellMap.set(cellKey(rowIndex, cursor), cell);
335
+ maxRow = Math.max(maxRow, rowIndex + rowSpan - 1);
336
+ maxCol = Math.max(maxCol, cursor + colSpan - 1);
337
+ if (colSpan > 1 || rowSpan > 1) {
338
+ spanMerges.push({
339
+ ref: `${absRangeRef(rowIndex, cursor, rowIndex + rowSpan - 1, cursor + colSpan - 1).replaceAll("$", "")}`,
340
+ bounds: {
341
+ startRow: rowIndex,
342
+ startCol: cursor,
343
+ endRow: rowIndex + rowSpan - 1,
344
+ endCol: cursor + colSpan - 1
345
+ },
346
+ source: "span"
347
+ });
348
+ }
349
+ for (let occupiedRow = rowIndex; occupiedRow < rowIndex + rowSpan; occupiedRow += 1) {
350
+ for (let occupiedCol = cursor; occupiedCol < cursor + colSpan; occupiedCol += 1) {
351
+ if (occupiedRow === rowIndex && occupiedCol === cursor) {
352
+ continue;
353
+ }
354
+ occupied.add(cellKey(occupiedRow, occupiedCol));
355
+ }
356
+ }
357
+ cursor += colSpan;
358
+ });
359
+ });
360
+ const explicitMerges = (sheet.mergedCells ?? []).map((ref) => ({
361
+ ref,
362
+ bounds: parseRangeRef(ref),
363
+ source: "explicit"
364
+ }));
365
+ const mergeRanges = [...spanMerges, ...explicitMerges];
366
+ const propagatedCellMap = new Map(originCellMap);
367
+ for (const merge of mergeRanges) {
368
+ const topLeftKey = cellKey(merge.bounds.startRow, merge.bounds.startCol);
369
+ const topLeftCell = propagatedCellMap.get(topLeftKey);
370
+ const border = resolveStyleInput(topLeftCell?.style)?.border;
371
+ if (!border) {
372
+ continue;
373
+ }
374
+ const applyEdge = (row, col, patch) => {
375
+ const key = cellKey(row, col);
376
+ propagatedCellMap.set(key, mergeStylePatch(propagatedCellMap.get(key), patch));
377
+ };
378
+ if (border.top) {
379
+ for (let col = merge.bounds.startCol; col <= merge.bounds.endCol; col += 1) {
380
+ applyEdge(merge.bounds.startRow, col, { border: { top: border.top } });
381
+ }
382
+ }
383
+ if (border.bottom) {
384
+ for (let col = merge.bounds.startCol; col <= merge.bounds.endCol; col += 1) {
385
+ applyEdge(merge.bounds.endRow, col, { border: { bottom: border.bottom } });
386
+ }
387
+ }
388
+ if (border.left) {
389
+ for (let row = merge.bounds.startRow; row <= merge.bounds.endRow; row += 1) {
390
+ applyEdge(row, merge.bounds.startCol, { border: { left: border.left } });
391
+ }
392
+ }
393
+ if (border.right) {
394
+ for (let row = merge.bounds.startRow; row <= merge.bounds.endRow; row += 1) {
395
+ applyEdge(row, merge.bounds.endCol, { border: { right: border.right } });
396
+ }
397
+ }
398
+ }
399
+ const buildRows = (cellMap) => {
400
+ const rowMap = /* @__PURE__ */ new Map();
401
+ for (const [key, cell] of cellMap) {
402
+ const [row, col] = key.split(":").map(Number);
403
+ const rowCells = rowMap.get(row) ?? [];
404
+ rowCells.push({ row, col, cell });
405
+ rowMap.set(row, rowCells);
406
+ }
407
+ return [...rowMap.entries()].sort((left, right) => left[0] - right[0]).map(([row, cells]) => ({
408
+ row,
409
+ cells: cells.sort((left, right) => left.col - right.col)
410
+ }));
411
+ };
412
+ return {
413
+ rows: buildRows(propagatedCellMap),
414
+ originCells: buildRows(originCellMap),
415
+ mergeRanges,
416
+ autoFilterRef: resolveAutoFilterRef(sheet, maxRow, maxCol),
417
+ maxRow,
418
+ maxCol
419
+ };
420
+ }
421
+
422
+ // src/utils/cell-ref.ts
423
+ var EXCEL_MAX_COLUMNS = 16384;
424
+ var COLUMN_LETTERS = Array.from({ length: EXCEL_MAX_COLUMNS }, (_unused, index) => {
425
+ let current = index + 1;
426
+ let letters = "";
427
+ while (current > 0) {
428
+ current -= 1;
429
+ letters = String.fromCharCode(65 + current % 26) + letters;
430
+ current = Math.floor(current / 26);
431
+ }
432
+ return letters;
433
+ });
434
+ function colIndexToLetter(index) {
435
+ if (!Number.isInteger(index) || index < 0 || index >= EXCEL_MAX_COLUMNS) {
436
+ throw new RangeError(`Column index ${index} is outside Excel's supported range`);
437
+ }
438
+ return COLUMN_LETTERS[index];
439
+ }
440
+ function rowIndexToRowNum(index) {
441
+ if (!Number.isInteger(index) || index < 0) {
442
+ throw new RangeError(`Row index ${index} must be a non-negative integer`);
443
+ }
444
+ return String(index + 1);
445
+ }
446
+ function cellRef(row, col) {
447
+ return `${colIndexToLetter(col)}${rowIndexToRowNum(row)}`;
448
+ }
449
+ function absCellRef(row, col) {
450
+ return `$${colIndexToLetter(col)}$${rowIndexToRowNum(row)}`;
451
+ }
452
+ function parseCellRef(ref) {
453
+ const match = /^\$?([A-Z]+)\$?([1-9]\d*)$/.exec(ref);
454
+ if (!match) {
455
+ throw new Error(`Invalid cell reference: ${ref}`);
456
+ }
457
+ const [, letters, rowString] = match;
458
+ let col = 0;
459
+ for (const character of letters) {
460
+ col = col * 26 + (character.charCodeAt(0) - 64);
461
+ }
462
+ return {
463
+ row: Number(rowString) - 1,
464
+ col: col - 1
465
+ };
466
+ }
467
+ function parseRangeRef(ref) {
468
+ const [startRef, endRef] = ref.split(":");
469
+ if (!startRef || !endRef) {
470
+ const parsed = parseCellRef(ref);
471
+ return {
472
+ startRow: parsed.row,
473
+ startCol: parsed.col,
474
+ endRow: parsed.row,
475
+ endCol: parsed.col
476
+ };
477
+ }
478
+ const start = parseCellRef(startRef);
479
+ const end = parseCellRef(endRef);
480
+ return {
481
+ startRow: Math.min(start.row, end.row),
482
+ startCol: Math.min(start.col, end.col),
483
+ endRow: Math.max(start.row, end.row),
484
+ endCol: Math.max(start.col, end.col)
485
+ };
486
+ }
487
+ function absRangeRef(startRow, startCol, endRow, endCol) {
488
+ return `${absCellRef(startRow, startCol)}:${absCellRef(endRow, endCol)}`;
489
+ }
490
+
491
+ // src/utils/hyperlinks.ts
492
+ function unquoteSheetName(value) {
493
+ if (value.startsWith("'") && value.endsWith("'")) {
494
+ return value.slice(1, -1).replaceAll("''", "'");
495
+ }
496
+ return value;
497
+ }
498
+ function splitHyperlinkLocation(value) {
499
+ const normalized = value.startsWith("#") ? value.slice(1) : value;
500
+ const separatorIndex = normalized.lastIndexOf("!");
501
+ if (separatorIndex === -1) {
502
+ return { ref: normalized };
503
+ }
504
+ return {
505
+ sheetName: unquoteSheetName(normalized.slice(0, separatorIndex)),
506
+ ref: normalized.slice(separatorIndex + 1)
507
+ };
508
+ }
509
+ function isCellOrRangeRef(value) {
510
+ try {
511
+ parseRangeRef(value);
512
+ return true;
513
+ } catch {
514
+ return false;
515
+ }
516
+ }
517
+ function isInternalLocation(value) {
518
+ const { ref } = splitHyperlinkLocation(value.trim());
519
+ return isCellOrRangeRef(ref);
520
+ }
521
+ function normalizeHyperlinkLocation(value) {
522
+ const { sheetName, ref } = splitHyperlinkLocation(value.trim());
523
+ if (!sheetName) {
524
+ return ref;
525
+ }
526
+ return `${quoteSheetName(sheetName)}!${ref}`;
527
+ }
528
+ function normalizeHyperlink(hyperlink) {
529
+ if (typeof hyperlink === "string") {
530
+ const normalized = hyperlink.trim();
531
+ if (isInternalLocation(normalized)) {
532
+ return {
533
+ mode: "internal",
534
+ location: normalizeHyperlinkLocation(normalized)
535
+ };
536
+ }
537
+ return {
538
+ mode: "external",
539
+ target: normalized
540
+ };
541
+ }
542
+ if ("location" in hyperlink) {
543
+ return {
544
+ mode: "internal",
545
+ location: normalizeHyperlinkLocation(hyperlink.location),
546
+ display: hyperlink.display,
547
+ tooltip: hyperlink.tooltip
548
+ };
549
+ }
550
+ return {
551
+ mode: "external",
552
+ target: hyperlink.target,
553
+ display: hyperlink.display,
554
+ tooltip: hyperlink.tooltip
555
+ };
556
+ }
557
+
558
+ // src/utils/xml.ts
559
+ var XML_ESCAPE_PATTERN = /[&<>"']/g;
560
+ var XML_ESCAPE_NEEDS_WORK = /[&<>"']/;
561
+ var FORBIDDEN_CONTROL_PATTERN = new RegExp("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]");
562
+ var FORBIDDEN_CONTROL_PATTERN_GLOBAL = new RegExp("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]", "g");
563
+ var XML_ESCAPE_MAP = {
564
+ "&": "&amp;",
565
+ "<": "&lt;",
566
+ ">": "&gt;",
567
+ '"': "&quot;",
568
+ "'": "&apos;"
569
+ };
570
+ var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
571
+ function escapeXml(value) {
572
+ if (!XML_ESCAPE_NEEDS_WORK.test(value)) {
573
+ return value;
574
+ }
575
+ return value.replace(XML_ESCAPE_PATTERN, (character) => XML_ESCAPE_MAP[character] ?? character);
576
+ }
577
+ function sanitizeSharedString(value) {
578
+ if (!FORBIDDEN_CONTROL_PATTERN.test(value)) {
579
+ return value;
580
+ }
581
+ return value.replace(FORBIDDEN_CONTROL_PATTERN_GLOBAL, "");
582
+ }
583
+ function needsXmlSpacePreserve(value) {
584
+ return /^\s/.test(value) || /\s$/.test(value) || /[\t\r\n]/.test(value);
585
+ }
586
+ function formatNumberForCell(value) {
587
+ if (Object.is(value, -0)) {
588
+ return "-0";
589
+ }
590
+ return String(value);
591
+ }
592
+
593
+ // src/styles/color.ts
594
+ function normalizeHex(color) {
595
+ const raw = color.startsWith("#") ? color.slice(1) : color;
596
+ if (raw.length === 6) {
597
+ return `FF${raw.toUpperCase()}`;
598
+ }
599
+ if (raw.length === 8) {
600
+ return raw.toUpperCase();
601
+ }
602
+ return raw.toUpperCase();
603
+ }
604
+ function serializeColorAttributes(color) {
605
+ if (color.startsWith("theme:")) {
606
+ const [, themeIndex, tint] = color.split(":");
607
+ const attributes = [`theme="${escapeXml(themeIndex)}"`];
608
+ if (tint !== void 0) {
609
+ attributes.push(`tint="${escapeXml(tint)}"`);
610
+ }
611
+ return attributes.join(" ");
612
+ }
613
+ return `rgb="${normalizeHex(color)}"`;
614
+ }
615
+
616
+ // src/styles/font-serializer.ts
617
+ function serializeUnderline(underline) {
618
+ if (!underline) {
619
+ return "";
620
+ }
621
+ if (underline === true) {
622
+ return '<u val="single"/>';
623
+ }
624
+ return `<u val="${escapeXml(underline)}"/>`;
625
+ }
626
+ function serializeFont(font) {
627
+ const parts = ["<font>"];
628
+ if (font.bold) parts.push("<b/>");
629
+ if (font.italic) parts.push("<i/>");
630
+ if (font.strikethrough) parts.push("<strike/>");
631
+ const underline = serializeUnderline(font.underline);
632
+ if (underline) parts.push(underline);
633
+ if (font.vertAlign) parts.push(`<vertAlign val="${font.vertAlign}"/>`);
634
+ parts.push(`<sz val="${font.size}"/>`);
635
+ if (font.color) {
636
+ parts.push(`<color ${serializeColorAttributes(font.color)}/>`);
637
+ }
638
+ parts.push(`<name val="${escapeXml(font.family)}"/>`);
639
+ if (font.familyClassification !== void 0) {
640
+ parts.push(`<family val="${font.familyClassification}"/>`);
641
+ }
642
+ if (font.charset !== void 0) {
643
+ parts.push(`<charset val="${font.charset}"/>`);
644
+ }
645
+ if (font.scheme) {
646
+ parts.push(`<scheme val="${font.scheme}"/>`);
647
+ }
648
+ parts.push("</font>");
649
+ return parts.join("");
650
+ }
651
+ function serializeRichTextRunFont(font) {
652
+ const parts = ["<rPr>"];
653
+ if (font.bold) parts.push("<b/>");
654
+ if (font.italic) parts.push("<i/>");
655
+ if (font.strikethrough) parts.push("<strike/>");
656
+ const underline = serializeUnderline(font.underline);
657
+ if (underline) parts.push(underline);
658
+ if (font.vertAlign) parts.push(`<vertAlign val="${font.vertAlign}"/>`);
659
+ parts.push(`<sz val="${font.size}"/>`);
660
+ if (font.color) {
661
+ parts.push(`<color ${serializeColorAttributes(font.color)}/>`);
662
+ }
663
+ parts.push(`<rFont val="${escapeXml(font.family)}"/>`);
664
+ if (font.charset !== void 0) {
665
+ parts.push(`<charset val="${font.charset}"/>`);
666
+ }
667
+ parts.push("</rPr>");
668
+ return parts.join("");
669
+ }
670
+
671
+ // src/styles/conditional-formatting.ts
672
+ function serializeCfvo(rulePoint) {
673
+ const valAttr = rulePoint.value !== void 0 ? ` val="${rulePoint.value}"` : "";
674
+ return `<cfvo type="${rulePoint.type}"${valAttr}/>`;
675
+ }
676
+ function serializeCellIs(rule, registry, priority) {
677
+ const dxfId = registry.registerDxf(rule.style);
678
+ return `<cfRule type="cellIs" dxfId="${dxfId}" priority="${priority}" operator="${rule.operator}"><formula>${rule.formula}</formula></cfRule>`;
679
+ }
680
+ function serializeTop10(rule, registry, priority) {
681
+ const dxfId = registry.registerDxf(rule.style);
682
+ return `<cfRule type="top10" dxfId="${dxfId}" priority="${priority}" rank="${rule.rank}" percent="${rule.percent ? 1 : 0}" bottom="${rule.bottom ? 1 : 0}"/>`;
683
+ }
684
+ function serializeDuplicate(rule, registry, priority) {
685
+ const dxfId = registry.registerDxf(rule.style);
686
+ return `<cfRule type="${rule.type}" dxfId="${dxfId}" priority="${priority}"/>`;
687
+ }
688
+ function serializeColorScale(rule, priority) {
689
+ const points = [rule.scale.min, rule.scale.mid, rule.scale.max].filter(
690
+ (point) => point !== void 0
691
+ );
692
+ const colors = points.map((point) => `<color ${serializeColorAttributes(point.color)}/>`).join("");
693
+ return `<cfRule type="colorScale" priority="${priority}"><colorScale>${points.map((point) => serializeCfvo(point)).join("")}${colors}</colorScale></cfRule>`;
694
+ }
695
+ function needsExtendedDataBar(rule) {
696
+ return rule.negativeColor !== void 0 || rule.axisPosition !== void 0 && rule.axisPosition !== "automatic" || rule.gradient === false || rule.direction !== void 0;
697
+ }
698
+ function serializeDataBar(rule, priority) {
699
+ const showValueAttr = rule.showValue === false ? ` showValue="0"` : "";
700
+ const basic = `<cfRule type="dataBar" priority="${priority}"><dataBar${showValueAttr}>${serializeCfvo(rule.min)}${serializeCfvo(rule.max)}<color ${serializeColorAttributes(rule.color)}/></dataBar></cfRule>`;
701
+ if (!needsExtendedDataBar(rule)) {
702
+ return { basic, extended: "" };
703
+ }
704
+ const guid = `{00000000-0000-0000-0000-${String(priority).padStart(12, "0")}}`;
705
+ const extParts = [];
706
+ extParts.push(`<x14:cfRule type="dataBar" id="${guid}">`);
707
+ extParts.push(`<x14:dataBar`);
708
+ const extAttrs = [];
709
+ if (rule.gradient === false) {
710
+ extAttrs.push(` gradient="0"`);
711
+ }
712
+ if (rule.direction !== void 0) {
713
+ extAttrs.push(` direction="${rule.direction}"`);
714
+ }
715
+ if (rule.axisPosition !== void 0 && rule.axisPosition !== "automatic") {
716
+ extAttrs.push(` axisPosition="${rule.axisPosition}"`);
717
+ }
718
+ extParts.push(extAttrs.join(""));
719
+ extParts.push(">");
720
+ extParts.push(serializeX14Cfvo(rule.min));
721
+ extParts.push(serializeX14Cfvo(rule.max));
722
+ if (rule.negativeColor !== void 0) {
723
+ extParts.push(`<x14:negativeFillColor ${serializeColorAttributes(rule.negativeColor)}/>`);
724
+ }
725
+ if (rule.axisPosition !== "none") {
726
+ extParts.push(`<x14:axisColor rgb="FF000000"/>`);
727
+ }
728
+ extParts.push("</x14:dataBar>");
729
+ extParts.push("</x14:cfRule>");
730
+ return { basic, extended: extParts.join("") };
731
+ }
732
+ function serializeX14Cfvo(cfvo) {
733
+ const valAttr = cfvo.value !== void 0 ? `<xm:f>${cfvo.value}</xm:f>` : "";
734
+ return `<x14:cfvo type="${cfvo.type}">${valAttr}</x14:cfvo>`;
735
+ }
736
+ var DEFAULT_THRESHOLDS = {
737
+ 3: [0, 33, 67],
738
+ 4: [0, 25, 50, 75],
739
+ 5: [0, 20, 40, 60, 80]
740
+ };
741
+ function serializeIconSet(rule, priority) {
742
+ const iconCount = parseInt(rule.iconSet[0], 10);
743
+ const attrs = [`iconSet="${rule.iconSet}"`];
744
+ if (rule.showValue === false) {
745
+ attrs.push(`showValue="0"`);
746
+ }
747
+ if (rule.reverse === true) {
748
+ attrs.push(`reverse="1"`);
749
+ }
750
+ let cfvos;
751
+ if (rule.thresholds) {
752
+ cfvos = rule.thresholds.map((t) => serializeCfvo(t)).join("");
753
+ } else {
754
+ const defaults = DEFAULT_THRESHOLDS[iconCount];
755
+ cfvos = defaults.map((val) => `<cfvo type="percent" val="${val}"/>`).join("");
756
+ }
757
+ return `<cfRule type="iconSet" priority="${priority}"><iconSet ${attrs.join(" ")}>${cfvos}</iconSet></cfRule>`;
758
+ }
759
+ function serializeRule(rule, registry, priority) {
760
+ switch (rule.type) {
761
+ case "cellIs":
762
+ return { basic: serializeCellIs(rule, registry, priority), extended: "" };
763
+ case "top10":
764
+ return { basic: serializeTop10(rule, registry, priority), extended: "" };
765
+ case "duplicateValues":
766
+ case "uniqueValues":
767
+ return { basic: serializeDuplicate(rule, registry, priority), extended: "" };
768
+ case "colorScale":
769
+ return { basic: serializeColorScale(rule, priority), extended: "" };
770
+ case "dataBar":
771
+ return serializeDataBar(rule, priority);
772
+ case "iconSet":
773
+ return { basic: serializeIconSet(rule, priority), extended: "" };
774
+ default: {
775
+ const _exhaustive = rule;
776
+ void _exhaustive;
777
+ return { basic: "", extended: "" };
778
+ }
779
+ }
780
+ }
781
+ function serializeConditionalFormatting(rules, registry) {
782
+ if (!rules || rules.length === 0) {
783
+ return { xml: "", extLst: "" };
784
+ }
785
+ let priority = 1;
786
+ const xmlParts = [];
787
+ const extEntries = [];
788
+ for (const entry of rules) {
789
+ const ruleParts = [];
790
+ for (const rule of entry.rules) {
791
+ const result = serializeRule(rule, registry, priority);
792
+ ruleParts.push(result.basic);
793
+ if (result.extended) {
794
+ extEntries.push(
795
+ `<x14:conditionalFormatting xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main">${result.extended}<xm:sqref>${entry.ref}</xm:sqref></x14:conditionalFormatting>`
796
+ );
797
+ }
798
+ priority += 1;
799
+ }
800
+ xmlParts.push(`<conditionalFormatting sqref="${entry.ref}">${ruleParts.join("")}</conditionalFormatting>`);
801
+ }
802
+ let extLst = "";
803
+ if (extEntries.length > 0) {
804
+ extLst = `<extLst><ext uri="{78C0D931-6437-407d-A8EE-F0AAD7539E65}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"><x14:conditionalFormattings>${extEntries.join("")}</x14:conditionalFormattings></ext></extLst>`;
805
+ }
806
+ return { xml: xmlParts.join(""), extLst };
807
+ }
808
+
809
+ // src/layout/column-width.ts
810
+ function isCJKCharacter(codePoint) {
811
+ return codePoint >= 11904 && codePoint <= 40959 || codePoint >= 63744 && codePoint <= 64255 || codePoint >= 65072 && codePoint <= 65103;
812
+ }
813
+ function estimateCharacterBaseWidth(char) {
814
+ const codePoint = char.codePointAt(0) ?? 0;
815
+ return isCJKCharacter(codePoint) ? 1.8 : 1;
816
+ }
817
+ function estimateStringWidth(value) {
818
+ let maxLineWidth = 0;
819
+ let currentLineWidth = 0;
820
+ for (let i = 0; i < value.length; i++) {
821
+ const ch = value[i];
822
+ if (ch === "\n" || ch === "\r") {
823
+ maxLineWidth = Math.max(maxLineWidth, currentLineWidth);
824
+ currentLineWidth = 0;
825
+ if (ch === "\r" && value[i + 1] === "\n") {
826
+ i++;
827
+ }
828
+ continue;
829
+ }
830
+ currentLineWidth += estimateCharacterBaseWidth(ch);
831
+ }
832
+ return Math.max(maxLineWidth, currentLineWidth);
833
+ }
834
+ function longestLineLength(value) {
835
+ return value.split(/\r\n|\r|\n/).reduce(
836
+ (max, line) => Math.max(max, line.length),
837
+ 0
838
+ );
839
+ }
840
+ function countIntegerDigits(value) {
841
+ if (!Number.isFinite(value) || value === 0) {
842
+ return 1;
843
+ }
844
+ return Math.floor(Math.log10(Math.abs(value))) + 1;
845
+ }
846
+ function countGroupedDigits(value) {
847
+ const digits = countIntegerDigits(value);
848
+ return digits + Math.max(0, Math.floor((digits - 1) / 3));
849
+ }
850
+ function countDecimalPlaces(format) {
851
+ const decimalSection = format.split(".")[1] ?? "";
852
+ const match = decimalSection.match(/0/g);
853
+ return match?.length ?? 0;
854
+ }
855
+ function estimateNumberDisplayLength(value, numberFormat) {
856
+ if (!numberFormat) {
857
+ return formatNumberForCell(value).length;
858
+ }
859
+ const absValue = Math.abs(value);
860
+ const sign = value < 0 ? 1 : 0;
861
+ if (numberFormat.includes("E+")) {
862
+ return sign + 8;
863
+ }
864
+ if (numberFormat.includes("%")) {
865
+ const decimals = countDecimalPlaces(numberFormat);
866
+ const scaled = absValue * 100;
867
+ return sign + countIntegerDigits(scaled) + (decimals > 0 ? decimals + 1 : 0) + 1;
868
+ }
869
+ if (numberFormat.includes("\u20A9")) {
870
+ return sign + 1 + countGroupedDigits(absValue);
871
+ }
872
+ if (numberFormat.includes("$") || numberFormat.includes("\u20AC") || numberFormat.includes("\xA3") || numberFormat.includes("\xA5")) {
873
+ const decimals = countDecimalPlaces(numberFormat);
874
+ return sign + 1 + countGroupedDigits(absValue) + (decimals > 0 ? decimals + 1 : 0);
875
+ }
876
+ if (numberFormat.includes("#,##0")) {
877
+ const decimals = countDecimalPlaces(numberFormat);
878
+ return sign + countGroupedDigits(absValue) + (decimals > 0 ? decimals + 1 : 0);
879
+ }
880
+ if (numberFormat === "@") {
881
+ return String(value).length;
882
+ }
883
+ return formatNumberForCell(value).length;
884
+ }
885
+ function resolveWidthCoefficient(style, defaults) {
886
+ const fontFamily = style?.font?.family ?? defaults?.font?.family ?? "Calibri";
887
+ return fontFamily === "Courier New" ? 1 : 1.15;
888
+ }
889
+ function estimateDisplayCharWidth(value, style) {
890
+ if (value === null || value === void 0) {
891
+ return void 0;
892
+ }
893
+ const boldMultiplier = style?.font?.bold === true ? 1.05 : 1;
894
+ if (Array.isArray(value)) {
895
+ return estimateStringWidth(value.map((run) => run.text).join("")) * boldMultiplier;
896
+ }
897
+ if (isErrorValue(value)) {
898
+ return estimateStringWidth(value.error) * boldMultiplier;
899
+ }
900
+ if (typeof value === "string") {
901
+ return estimateStringWidth(value) * boldMultiplier;
902
+ }
903
+ return estimateDisplayLength(value, style) * boldMultiplier;
904
+ }
905
+ function estimateDisplayWidth(value, style, defaults) {
906
+ const charWidth = estimateDisplayCharWidth(value, style);
907
+ if (charWidth === void 0 || charWidth === 0) {
908
+ return void 0;
909
+ }
910
+ const coefficient = resolveWidthCoefficient(style, defaults);
911
+ return Math.min(Math.max(charWidth * coefficient + 2, 8.43), 255);
912
+ }
913
+ function estimateDisplayLength(value, style) {
914
+ if (value === null || value === void 0) {
915
+ return 0;
916
+ }
917
+ if (Array.isArray(value)) {
918
+ return longestLineLength(value.map((run) => run.text).join(""));
919
+ }
920
+ if (isErrorValue(value)) {
921
+ return value.error.length;
922
+ }
923
+ if (typeof value === "string") {
924
+ return longestLineLength(value);
925
+ }
926
+ if (typeof value === "boolean") {
927
+ return value ? 4 : 5;
928
+ }
929
+ if (value instanceof Date) {
930
+ const numberFormat = resolveNumberFormatAlias(style?.numberFormat);
931
+ if (numberFormat === "yyyy-mm-dd hh:mm") return 16;
932
+ if (numberFormat === "h:mm:ss") return 8;
933
+ if (numberFormat === "m/d/yyyy") return 10;
934
+ if (numberFormat === "d/m/yyyy") return 10;
935
+ return 10;
936
+ }
937
+ return estimateNumberDisplayLength(value, resolveNumberFormatAlias(style?.numberFormat));
938
+ }
939
+ function estimateHeuristicColumnWidth(value, style, defaults) {
940
+ return estimateDisplayWidth(value, style, defaults);
941
+ }
942
+ function getSheetColumnCount(sheet) {
943
+ let maxColumnCount = sheet.columns?.length ?? 0;
944
+ for (const row of sheet.rows) {
945
+ if (row.cells.length > maxColumnCount) {
946
+ maxColumnCount = row.cells.length;
947
+ }
948
+ }
949
+ return maxColumnCount;
950
+ }
951
+ function buildColumnLayout(sheet, computedColumns, defaults) {
952
+ const columnCount = computedColumns.length;
953
+ const columnWidths = computedColumns.map(
954
+ (column) => column?.width ?? (defaults?.columnWidth ?? 8.43)
955
+ );
956
+ const segments = [];
957
+ for (let index = 0; index < columnCount; index += 1) {
958
+ const explicit = sheet.columns?.[index];
959
+ const computed = computedColumns[index];
960
+ const descriptor = {
961
+ width: explicit?.width ?? computed?.width ?? (defaults?.columnWidth ?? 8.43),
962
+ hidden: explicit?.hidden,
963
+ bestFit: explicit?.bestFit ?? computed?.bestFit,
964
+ customWidth: explicit?.width !== void 0 || computed?.width !== void 0
965
+ };
966
+ const shouldEmitSegment = descriptor.customWidth || descriptor.hidden || descriptor.bestFit;
967
+ if (!shouldEmitSegment) {
968
+ continue;
969
+ }
970
+ const previous = segments[segments.length - 1];
971
+ if (previous && previous.end === index && previous.width === descriptor.width && previous.hidden === descriptor.hidden && previous.bestFit === descriptor.bestFit && previous.customWidth === descriptor.customWidth) {
972
+ previous.end = index + 1;
973
+ continue;
974
+ }
975
+ segments.push({
976
+ start: index + 1,
977
+ end: index + 1,
978
+ ...descriptor
979
+ });
980
+ }
981
+ return {
982
+ columnCount,
983
+ columnWidths,
984
+ segments
985
+ };
986
+ }
987
+
988
+ // src/serializers/sheet-xml-builder.ts
989
+ var WORKSHEET_SECTION_ORDER = {
990
+ sheetPr: 1,
991
+ dimension: 2,
992
+ sheetViews: 3,
993
+ sheetFormatPr: 4,
994
+ cols: 5,
995
+ sheetData: 6,
996
+ autoFilter: 11,
997
+ sheetProtection: 13,
998
+ mergeCells: 15,
999
+ conditionalFormatting: 17,
1000
+ dataValidations: 18,
1001
+ hyperlinks: 19,
1002
+ printOptions: 20,
1003
+ pageMargins: 21,
1004
+ pageSetup: 22,
1005
+ drawing: 23,
1006
+ legacyDrawing: 24,
1007
+ tableParts: 25,
1008
+ pivotTableParts: 26,
1009
+ extLst: 27
1010
+ };
1011
+ var SHEET_DATA_POSITION = WORKSHEET_SECTION_ORDER.sheetData;
1012
+ var SheetXmlBuilder = class {
1013
+ constructor(rootAttributes) {
1014
+ this.rootAttributes = rootAttributes;
1015
+ }
1016
+ sections = /* @__PURE__ */ new Map();
1017
+ setSheetPr(xml) {
1018
+ this.set(WORKSHEET_SECTION_ORDER.sheetPr, xml);
1019
+ }
1020
+ setDimension(xml) {
1021
+ this.set(WORKSHEET_SECTION_ORDER.dimension, xml);
1022
+ }
1023
+ setSheetViews(xml) {
1024
+ this.set(WORKSHEET_SECTION_ORDER.sheetViews, xml);
1025
+ }
1026
+ setSheetFormatPr(xml) {
1027
+ this.set(WORKSHEET_SECTION_ORDER.sheetFormatPr, xml);
1028
+ }
1029
+ setCols(xml) {
1030
+ this.set(WORKSHEET_SECTION_ORDER.cols, xml);
1031
+ }
1032
+ setSheetData(xml) {
1033
+ this.set(WORKSHEET_SECTION_ORDER.sheetData, xml);
1034
+ }
1035
+ setAutoFilter(xml) {
1036
+ this.set(WORKSHEET_SECTION_ORDER.autoFilter, xml);
1037
+ }
1038
+ setSheetProtection(xml) {
1039
+ this.set(WORKSHEET_SECTION_ORDER.sheetProtection, xml);
1040
+ }
1041
+ setMergeCells(xml) {
1042
+ this.set(WORKSHEET_SECTION_ORDER.mergeCells, xml);
1043
+ }
1044
+ addConditionalFormatting(xml) {
1045
+ this.add(WORKSHEET_SECTION_ORDER.conditionalFormatting, xml);
1046
+ }
1047
+ setDataValidations(xml) {
1048
+ this.set(WORKSHEET_SECTION_ORDER.dataValidations, xml);
1049
+ }
1050
+ setHyperlinks(xml) {
1051
+ this.set(WORKSHEET_SECTION_ORDER.hyperlinks, xml);
1052
+ }
1053
+ setPrintOptions(xml) {
1054
+ this.set(WORKSHEET_SECTION_ORDER.printOptions, xml);
1055
+ }
1056
+ setPageMargins(xml) {
1057
+ this.set(WORKSHEET_SECTION_ORDER.pageMargins, xml);
1058
+ }
1059
+ setPageSetup(xml) {
1060
+ this.set(WORKSHEET_SECTION_ORDER.pageSetup, xml);
1061
+ }
1062
+ setTableParts(xml) {
1063
+ this.set(WORKSHEET_SECTION_ORDER.tableParts, xml);
1064
+ }
1065
+ setPivotTableParts(xml) {
1066
+ this.set(WORKSHEET_SECTION_ORDER.pivotTableParts, xml);
1067
+ }
1068
+ setExtLst(xml) {
1069
+ this.set(WORKSHEET_SECTION_ORDER.extLst, xml);
1070
+ }
1071
+ setLegacyDrawing(xml) {
1072
+ this.set(WORKSHEET_SECTION_ORDER.legacyDrawing, xml);
1073
+ }
1074
+ setDrawing(xml) {
1075
+ this.set(WORKSHEET_SECTION_ORDER.drawing, xml);
1076
+ }
1077
+ build() {
1078
+ const parts = [
1079
+ XML_DECLARATION,
1080
+ `<worksheet ${this.rootAttributes.join(" ")}>`
1081
+ ];
1082
+ for (const [, sectionParts] of [...this.sections.entries()].sort((left, right) => left[0] - right[0])) {
1083
+ parts.push(...sectionParts);
1084
+ }
1085
+ parts.push("</worksheet>");
1086
+ return parts.join("");
1087
+ }
1088
+ buildSheetDataEnvelope() {
1089
+ const prefix = [
1090
+ XML_DECLARATION,
1091
+ `<worksheet ${this.rootAttributes.join(" ")}>`
1092
+ ];
1093
+ const suffix = [];
1094
+ for (const [position, sectionParts] of [...this.sections.entries()].sort((left, right) => left[0] - right[0])) {
1095
+ if (position < SHEET_DATA_POSITION) {
1096
+ prefix.push(...sectionParts);
1097
+ continue;
1098
+ }
1099
+ if (position > SHEET_DATA_POSITION) {
1100
+ suffix.push(...sectionParts);
1101
+ }
1102
+ }
1103
+ prefix.push("<sheetData>");
1104
+ suffix.unshift("</sheetData>");
1105
+ suffix.push("</worksheet>");
1106
+ return {
1107
+ prefix: prefix.join(""),
1108
+ suffix: suffix.join("")
1109
+ };
1110
+ }
1111
+ set(position, xml) {
1112
+ if (!xml) {
1113
+ return;
1114
+ }
1115
+ this.sections.set(position, [xml]);
1116
+ }
1117
+ add(position, xml) {
1118
+ if (!xml) {
1119
+ return;
1120
+ }
1121
+ const section = this.sections.get(position) ?? [];
1122
+ section.push(xml);
1123
+ this.sections.set(position, section);
1124
+ }
1125
+ };
1126
+
1127
+ // src/serializers/worksheet-rels-serializer.ts
1128
+ var RELATIONSHIP_TYPE_URIS = {
1129
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
1130
+ table: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
1131
+ vmlDrawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
1132
+ comment: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
1133
+ drawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
1134
+ pivotTable: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"
1135
+ };
1136
+ function serializeWorksheetRelationships(relationships) {
1137
+ return [
1138
+ XML_DECLARATION,
1139
+ `<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">`,
1140
+ ...relationships.map((relationship) => {
1141
+ const typeUri = RELATIONSHIP_TYPE_URIS[relationship.type];
1142
+ const targetMode = relationship.type === "hyperlink" ? ` TargetMode="External"` : "";
1143
+ return `<Relationship Id="${relationship.id}" Type="${typeUri}" Target="${escapeXml(relationship.target)}"${targetMode}/>`;
1144
+ }),
1145
+ `</Relationships>`
1146
+ ].join("");
1147
+ }
1148
+
1149
+ // src/serializers/table-serializer.ts
1150
+ function totalsRowFunctionCode(value) {
1151
+ switch (value) {
1152
+ case "average":
1153
+ return 101;
1154
+ case "countNums":
1155
+ return 102;
1156
+ case "count":
1157
+ return 103;
1158
+ case "max":
1159
+ return 104;
1160
+ case "min":
1161
+ return 105;
1162
+ case "stdDev":
1163
+ return 107;
1164
+ case "sum":
1165
+ return 109;
1166
+ case "var":
1167
+ return 110;
1168
+ default:
1169
+ return null;
1170
+ }
1171
+ }
1172
+ function createTotalsRowCell(table, range, column, columnIndex) {
1173
+ if (column?.totalsRowLabel) {
1174
+ return { value: column.totalsRowLabel };
1175
+ }
1176
+ if (column?.totalsRowFormula) {
1177
+ return {
1178
+ formula: column.totalsRowFormula.startsWith("=") ? column.totalsRowFormula.slice(1) : column.totalsRowFormula
1179
+ };
1180
+ }
1181
+ if (column?.totalsRowFunction) {
1182
+ const functionCode = totalsRowFunctionCode(column.totalsRowFunction);
1183
+ const dataStartRow = range.startRow + 1;
1184
+ const dataEndRow = Math.max(range.startRow + 1, range.endRow - 1);
1185
+ if (functionCode !== null && dataEndRow >= dataStartRow) {
1186
+ return {
1187
+ formula: `SUBTOTAL(${functionCode},${cellRef(dataStartRow, columnIndex)}:${cellRef(dataEndRow, columnIndex)})`
1188
+ };
1189
+ }
1190
+ }
1191
+ if (table.totalsRow) {
1192
+ return { value: "" };
1193
+ }
1194
+ return { value: "" };
1195
+ }
1196
+ function buildWorksheetSyntheticTableCells(bindings) {
1197
+ const cellsByRow = /* @__PURE__ */ new Map();
1198
+ for (const binding of bindings ?? []) {
1199
+ const table = binding.definition;
1200
+ if (table.totalsRow !== true) {
1201
+ continue;
1202
+ }
1203
+ const range = parseRangeRef(table.ref);
1204
+ const totalsRowIndex = range.endRow;
1205
+ const columns = table.columns ?? [];
1206
+ const rowCells = cellsByRow.get(totalsRowIndex) ?? [];
1207
+ for (let offset = 0; offset <= range.endCol - range.startCol; offset += 1) {
1208
+ const columnIndex = range.startCol + offset;
1209
+ rowCells.push({
1210
+ row: totalsRowIndex,
1211
+ col: columnIndex,
1212
+ cell: createTotalsRowCell(table, range, columns[offset], columnIndex)
1213
+ });
1214
+ }
1215
+ cellsByRow.set(totalsRowIndex, rowCells);
1216
+ }
1217
+ return cellsByRow;
1218
+ }
1219
+
1220
+ // src/utils/date.ts
1221
+ var EXCEL_EPOCH_UTC = Date.UTC(1899, 11, 30);
1222
+ var EXCEL_1904_EPOCH_UTC = Date.UTC(1904, 0, 1);
1223
+ var MIN_EXCEL_SUPPORTED_DATE_UTC = Date.UTC(1899, 11, 31);
1224
+ var LOTUS_RAW_THRESHOLD = 61;
1225
+ function isSupportedExcelDate(value) {
1226
+ return !Number.isNaN(value.getTime()) && value.getTime() >= MIN_EXCEL_SUPPORTED_DATE_UTC;
1227
+ }
1228
+ function assertSupportedExcelDate(value) {
1229
+ if (!isSupportedExcelDate(value)) {
1230
+ const received = Number.isNaN(value.getTime()) ? String(value) : value.toISOString();
1231
+ throw new RangeError(
1232
+ `Spreadsheet dates must be on or after 1899-12-31T00:00:00.000Z. Received ${received}.`
1233
+ );
1234
+ }
1235
+ }
1236
+ function dateToSerial(value, dateSystem = "1900") {
1237
+ assertSupportedExcelDate(value);
1238
+ if (dateSystem === "1904") {
1239
+ return (value.getTime() - EXCEL_1904_EPOCH_UTC) / 864e5;
1240
+ }
1241
+ const raw = (value.getTime() - EXCEL_EPOCH_UTC) / 864e5;
1242
+ if (raw >= 1 && raw < LOTUS_RAW_THRESHOLD) {
1243
+ return raw - 1;
1244
+ }
1245
+ return raw;
1246
+ }
1247
+ function dateToSerialString(value, dateSystem = "1900") {
1248
+ return formatNumberForCell(dateToSerial(value, dateSystem));
1249
+ }
1250
+
1251
+ // src/serializers/sheet-serializer.ts
1252
+ var noRefCellOpenTagCache = /* @__PURE__ */ new Map();
1253
+ var noRefCellEmptyTagCache = /* @__PURE__ */ new Map();
1254
+ var noRefInlineStringOpenTagCache = /* @__PURE__ */ new Map();
1255
+ var LARGE_ROW_REF_OMISSION_THRESHOLD = 512;
1256
+ var SIMPLE_ROW_OPEN_TAG = "<row>";
1257
+ var SIMPLE_ROW_CLOSE_TAG = "</row>";
1258
+ function getNoRefCellOpenTag(styleAttr, typeAttr) {
1259
+ const key = `${typeAttr}|${styleAttr}`;
1260
+ const cached = noRefCellOpenTagCache.get(key);
1261
+ if (cached !== void 0) {
1262
+ return cached;
1263
+ }
1264
+ const tag = `<c${typeAttr}${styleAttr}><v>`;
1265
+ noRefCellOpenTagCache.set(key, tag);
1266
+ return tag;
1267
+ }
1268
+ function getNoRefCellEmptyTag(styleAttr) {
1269
+ const cached = noRefCellEmptyTagCache.get(styleAttr);
1270
+ if (cached !== void 0) {
1271
+ return cached;
1272
+ }
1273
+ const tag = `<c${styleAttr}/>`;
1274
+ noRefCellEmptyTagCache.set(styleAttr, tag);
1275
+ return tag;
1276
+ }
1277
+ function getNoRefInlineStringOpenTag(styleAttr) {
1278
+ const cached = noRefInlineStringOpenTagCache.get(styleAttr);
1279
+ if (cached !== void 0) {
1280
+ return cached;
1281
+ }
1282
+ const tag = `<c t="inlineStr"${styleAttr}>`;
1283
+ noRefInlineStringOpenTagCache.set(styleAttr, tag);
1284
+ return tag;
1285
+ }
1286
+ function serializeSheetPr(sheet) {
1287
+ const parts = [];
1288
+ if (sheet.tabColor) {
1289
+ parts.push(`<tabColor rgb="FF${sheet.tabColor.replace(/^#/, "").toUpperCase()}"/>`);
1290
+ }
1291
+ if (sheet.pageSetup && (sheet.pageSetup.fitToWidth !== void 0 || sheet.pageSetup.fitToHeight !== void 0)) {
1292
+ parts.push(`<pageSetUpPr fitToPage="1"/>`);
1293
+ }
1294
+ return parts.length > 0 ? `<sheetPr>${parts.join("")}</sheetPr>` : "";
1295
+ }
1296
+ function serializePrintOptions(sheet) {
1297
+ const options = sheet.pageSetup?.options;
1298
+ if (!options) {
1299
+ return "";
1300
+ }
1301
+ const attributes = [];
1302
+ if (options.gridLines !== void 0) {
1303
+ attributes.push(`gridLines="${options.gridLines ? 1 : 0}"`);
1304
+ }
1305
+ if (options.headings !== void 0) {
1306
+ attributes.push(`headings="${options.headings ? 1 : 0}"`);
1307
+ }
1308
+ return attributes.length > 0 ? `<printOptions ${attributes.join(" ")}/>` : "";
1309
+ }
1310
+ function serializePageMargins(sheet) {
1311
+ const margins = sheet.pageSetup?.margins;
1312
+ if (!margins) {
1313
+ return "";
1314
+ }
1315
+ const attributes = [];
1316
+ if (margins.left !== void 0) attributes.push(`left="${margins.left}"`);
1317
+ if (margins.right !== void 0) attributes.push(`right="${margins.right}"`);
1318
+ if (margins.top !== void 0) attributes.push(`top="${margins.top}"`);
1319
+ if (margins.bottom !== void 0) attributes.push(`bottom="${margins.bottom}"`);
1320
+ if (margins.header !== void 0) attributes.push(`header="${margins.header}"`);
1321
+ if (margins.footer !== void 0) attributes.push(`footer="${margins.footer}"`);
1322
+ return attributes.length > 0 ? `<pageMargins ${attributes.join(" ")}/>` : "";
1323
+ }
1324
+ function serializePageSetup(sheet) {
1325
+ const pageSetup = sheet.pageSetup;
1326
+ if (!pageSetup) {
1327
+ return "";
1328
+ }
1329
+ const attributes = [];
1330
+ if (pageSetup.paperSize !== void 0) attributes.push(`paperSize="${pageSetup.paperSize}"`);
1331
+ if (pageSetup.orientation) attributes.push(`orientation="${pageSetup.orientation}"`);
1332
+ if (pageSetup.scale !== void 0) attributes.push(`scale="${pageSetup.scale}"`);
1333
+ if (pageSetup.fitToWidth !== void 0) attributes.push(`fitToWidth="${pageSetup.fitToWidth}"`);
1334
+ if (pageSetup.fitToHeight !== void 0) attributes.push(`fitToHeight="${pageSetup.fitToHeight}"`);
1335
+ return attributes.length > 0 ? `<pageSetup ${attributes.join(" ")}/>` : "";
1336
+ }
1337
+ function dateToSerial2(value, dateSystem) {
1338
+ return dateToSerialString(value, dateSystem);
1339
+ }
1340
+ function serializeRichText(value, cellStyle, defaults) {
1341
+ const runs = value.map((run) => {
1342
+ const font = normalizeFont({
1343
+ ...cellStyle?.font,
1344
+ ...run.font
1345
+ }, defaults);
1346
+ const textAttrs = needsXmlSpacePreserve(run.text) ? ` xml:space="preserve"` : "";
1347
+ return `<r>${serializeRichTextRunFont(font)}<t${textAttrs}>${escapeXml(run.text)}</t></r>`;
1348
+ }).join("");
1349
+ return `<is>${runs}</is>`;
1350
+ }
1351
+ function serializeInlineString(value) {
1352
+ const sanitized = sanitizeSharedString(value);
1353
+ const textAttrs = needsXmlSpacePreserve(sanitized) ? ` xml:space="preserve"` : "";
1354
+ return `<is><t${textAttrs}>${escapeXml(sanitized)}</t></is>`;
1355
+ }
1356
+ function serializeCell(ref, cell, styleAttr, resolvedStyle, defaults, sheetName, formulaEvaluator, sharedStrings, dateSystem) {
1357
+ const refAttr = ref ? ` r="${ref}"` : "";
1358
+ const rawFormula = cell.formula;
1359
+ if (!rawFormula) {
1360
+ if (cell.value === null || cell.value === void 0) {
1361
+ if (!styleAttr) {
1362
+ return "";
1363
+ }
1364
+ return refAttr ? `<c${refAttr}${styleAttr}/>` : getNoRefCellEmptyTag(styleAttr);
1365
+ }
1366
+ if (isRichTextValue(cell.value)) {
1367
+ const defaultFont = {
1368
+ family: defaults?.font?.family ?? "Calibri",
1369
+ size: defaults?.font?.size ?? 11
1370
+ };
1371
+ return `<c${refAttr} t="inlineStr"${styleAttr}>${serializeRichText(cell.value, resolvedStyle, defaultFont)}</c>`;
1372
+ }
1373
+ if (isErrorValue(cell.value)) {
1374
+ const openTag2 = refAttr ? `<c${refAttr} t="e"${styleAttr}><v>` : getNoRefCellOpenTag(styleAttr, ` t="e"`);
1375
+ return `${openTag2}${cell.value.error}</v></c>`;
1376
+ }
1377
+ if (typeof cell.value === "string") {
1378
+ if (sharedStrings) {
1379
+ const sharedIndex = sharedStrings.register(cell.value);
1380
+ const openTag3 = refAttr ? `<c${refAttr} t="s"${styleAttr}><v>` : getNoRefCellOpenTag(styleAttr, ` t="s"`);
1381
+ return `${openTag3}${sharedIndex}</v></c>`;
1382
+ }
1383
+ const openTag2 = refAttr ? `<c${refAttr} t="inlineStr"${styleAttr}>` : getNoRefInlineStringOpenTag(styleAttr);
1384
+ return `${openTag2}${serializeInlineString(cell.value)}</c>`;
1385
+ }
1386
+ if (typeof cell.value === "boolean") {
1387
+ const openTag2 = refAttr ? `<c${refAttr} t="b"${styleAttr}><v>` : getNoRefCellOpenTag(styleAttr, ` t="b"`);
1388
+ return `${openTag2}${cell.value ? 1 : 0}</v></c>`;
1389
+ }
1390
+ if (cell.value instanceof Date) {
1391
+ const openTag2 = refAttr ? `<c${refAttr}${styleAttr}><v>` : getNoRefCellOpenTag(styleAttr, "");
1392
+ return `${openTag2}${dateToSerial2(cell.value, dateSystem)}</v></c>`;
1393
+ }
1394
+ const openTag = refAttr ? `<c${refAttr}${styleAttr}><v>` : getNoRefCellOpenTag(styleAttr, "");
1395
+ return `${openTag}${formatNumberForCell(cell.value)}</v></c>`;
1396
+ }
1397
+ const formula = formulaEvaluator?.getFormulaDefinition(cell) ?? null;
1398
+ if (!formula) {
1399
+ const rawExpression = typeof rawFormula === "string" ? rawFormula : rawFormula.expression;
1400
+ const formulaTag2 = `<f>${escapeXml(rawExpression)}</f>`;
1401
+ return `<c${refAttr}${styleAttr}>${formulaTag2}</c>`;
1402
+ }
1403
+ const cachedValue = formula.cachedValue ?? formulaEvaluator?.evaluateCell(cell, sheetName, ref ?? "");
1404
+ const formulaAttributes = [];
1405
+ const dynamicAttr = formula.dynamic ? ` cm="1"` : "";
1406
+ if (formula.arrayRange) {
1407
+ formulaAttributes.push(`t="array"`, `ref="${formula.arrayRange}"`);
1408
+ }
1409
+ const formulaTag = formulaAttributes.length > 0 ? `<f ${formulaAttributes.join(" ")}>${escapeXml(formula.expression)}</f>` : `<f>${escapeXml(formula.expression)}</f>`;
1410
+ if (cachedValue === void 0 || cachedValue === null) {
1411
+ return `<c${refAttr}${styleAttr}${dynamicAttr}>${formulaTag}</c>`;
1412
+ }
1413
+ if (isRichTextValue(cachedValue)) {
1414
+ const text = cachedValue.map((run) => run.text).join("");
1415
+ return `<c${refAttr} t="str"${styleAttr}${dynamicAttr}>${formulaTag}<v>${escapeXml(text)}</v></c>`;
1416
+ }
1417
+ if (isErrorValue(cachedValue)) {
1418
+ return `<c${refAttr} t="e"${styleAttr}${dynamicAttr}>${formulaTag}<v>${cachedValue.error}</v></c>`;
1419
+ }
1420
+ if (typeof cachedValue === "string") {
1421
+ return `<c${refAttr} t="str"${styleAttr}${dynamicAttr}>${formulaTag}<v>${escapeXml(cachedValue)}</v></c>`;
1422
+ }
1423
+ if (typeof cachedValue === "boolean") {
1424
+ return `<c${refAttr} t="b"${styleAttr}${dynamicAttr}>${formulaTag}<v>${cachedValue ? 1 : 0}</v></c>`;
1425
+ }
1426
+ if (cachedValue instanceof Date) {
1427
+ return `<c${refAttr}${styleAttr}${dynamicAttr}>${formulaTag}<v>${dateToSerial2(cachedValue, dateSystem)}</v></c>`;
1428
+ }
1429
+ return `<c${refAttr}${styleAttr}${dynamicAttr}>${formulaTag}<v>${formatNumberForCell(cachedValue)}</v></c>`;
1430
+ }
1431
+ function resolveStyleAttr(styleRegistry, resolvedStyle, cache) {
1432
+ if (!resolvedStyle) {
1433
+ return "";
1434
+ }
1435
+ const cached = cache.get(resolvedStyle);
1436
+ if (cached !== void 0) {
1437
+ return cached;
1438
+ }
1439
+ const styleIndex = styleRegistry.registerResolvedStyle(resolvedStyle);
1440
+ const styleAttr = styleIndex > 0 ? ` s="${styleIndex}"` : "";
1441
+ cache.set(resolvedStyle, styleAttr);
1442
+ return styleAttr;
1443
+ }
1444
+ function canCacheRawCellStyle(style, value, rowStyle) {
1445
+ return rowStyle === void 0 && typeof style === "object" && style !== null && style.preset === void 0 && !(value instanceof Date && style.numberFormat === void 0);
1446
+ }
1447
+ function resolveCellStyleBundle(cell, rowStyle, styleRegistry, styleAttrCache, rawStyleCache) {
1448
+ if (canCacheRawCellStyle(cell.style, cell.value, rowStyle)) {
1449
+ const cached = rawStyleCache.get(cell.style);
1450
+ if (cached !== void 0) {
1451
+ return cached;
1452
+ }
1453
+ const resolvedStyle2 = resolveCellStyle(cell.style, cell.value, rowStyle);
1454
+ const bundle = {
1455
+ resolvedStyle: resolvedStyle2,
1456
+ styleAttr: resolveStyleAttr(styleRegistry, resolvedStyle2, styleAttrCache)
1457
+ };
1458
+ rawStyleCache.set(cell.style, bundle);
1459
+ return bundle;
1460
+ }
1461
+ const resolvedStyle = resolveCellStyle(cell.style, cell.value, rowStyle);
1462
+ return {
1463
+ resolvedStyle,
1464
+ styleAttr: resolveStyleAttr(styleRegistry, resolvedStyle, styleAttrCache)
1465
+ };
1466
+ }
1467
+ function getDisplayValueForMetrics(cell, formulaEvaluator, sheetName, ref) {
1468
+ if (!cell.formula || !formulaEvaluator) {
1469
+ return cell.value;
1470
+ }
1471
+ const formula = formulaEvaluator.getFormulaDefinition(cell);
1472
+ if (!formula) {
1473
+ return cell.value;
1474
+ }
1475
+ return formula.cachedValue ?? formulaEvaluator?.evaluateCell(cell, sheetName, ref);
1476
+ }
1477
+ function estimateWrappedCellHeight(cell, resolvedStyle, columnWidth, defaults) {
1478
+ if (!resolvedStyle?.alignment?.wrapText) {
1479
+ return void 0;
1480
+ }
1481
+ const displayLength = estimateDisplayLength(cell.value, resolvedStyle);
1482
+ if (displayLength === 0) {
1483
+ return void 0;
1484
+ }
1485
+ const charsPerLine = Math.max(1, Math.floor((columnWidth || (defaults?.columnWidth ?? 8.43)) * 1.6));
1486
+ const rawText = typeof cell.value === "string" ? cell.value : Array.isArray(cell.value) ? cell.value.map((run) => run.text).join("") : "";
1487
+ const explicitLineCount = rawText.length > 0 ? rawText.split(/\r\n|\r|\n/).length : 1;
1488
+ const lines = Math.max(explicitLineCount, Math.ceil(displayLength / charsPerLine));
1489
+ if (lines <= 1) {
1490
+ return void 0;
1491
+ }
1492
+ const fontSize = resolvedStyle.font?.size ?? defaults?.font?.size ?? 11;
1493
+ const estimatedHeight = Math.min(lines * fontSize * 1.4, 409);
1494
+ const defaultRowHeight = defaults?.rowHeight ?? 15;
1495
+ return estimatedHeight > defaultRowHeight ? estimatedHeight : void 0;
1496
+ }
1497
+ function formatFormula(value, type, dateSystem) {
1498
+ if (Array.isArray(value)) return `"${value.join(",")}"`;
1499
+ if (typeof value === "number") return String(value);
1500
+ if (type === "date" && /^\d{4}-\d{2}-\d{2}(T|$)/.test(value)) {
1501
+ return dateToSerial2(new Date(value), dateSystem);
1502
+ }
1503
+ return value;
1504
+ }
1505
+ function serializeDataValidations(dataValidations, dateSystem) {
1506
+ if (!dataValidations || dataValidations.length === 0) {
1507
+ return "";
1508
+ }
1509
+ return `<dataValidations count="${dataValidations.length}">${dataValidations.map((validation) => {
1510
+ const attributes = [
1511
+ `sqref="${validation.ref}"`,
1512
+ `type="${validation.type}"`
1513
+ ];
1514
+ if (validation.operator) attributes.push(`operator="${validation.operator}"`);
1515
+ attributes.push(`allowBlank="${validation.allowBlank === false ? 0 : 1}"`);
1516
+ if (validation.showInputMessage !== void 0) attributes.push(`showInputMessage="${validation.showInputMessage ? 1 : 0}"`);
1517
+ attributes.push(`showErrorMessage="${validation.showErrorMessage === false ? 0 : 1}"`);
1518
+ if (validation.showDropDown !== void 0) attributes.push(`showDropDown="${validation.showDropDown ? 0 : 1}"`);
1519
+ if (validation.errorStyle) attributes.push(`errorStyle="${validation.errorStyle}"`);
1520
+ if (validation.errorTitle) attributes.push(`errorTitle="${escapeXml(validation.errorTitle)}"`);
1521
+ if (validation.error) attributes.push(`error="${escapeXml(validation.error)}"`);
1522
+ if (validation.promptTitle) attributes.push(`promptTitle="${escapeXml(validation.promptTitle)}"`);
1523
+ if (validation.prompt) attributes.push(`prompt="${escapeXml(validation.prompt)}"`);
1524
+ const f1 = formatFormula(validation.formula1, validation.type, dateSystem);
1525
+ const formulas = [`<formula1>${escapeXml(f1)}</formula1>`];
1526
+ if (validation.formula2 !== void 0) {
1527
+ const f2 = formatFormula(validation.formula2, validation.type, dateSystem);
1528
+ formulas.push(`<formula2>${escapeXml(f2)}</formula2>`);
1529
+ }
1530
+ return `<dataValidation ${attributes.join(" ")}>${formulas.join("")}</dataValidation>`;
1531
+ }).join("")}</dataValidations>`;
1532
+ }
1533
+ function hashPassword(password) {
1534
+ let hash = 0;
1535
+ for (let i = password.length - 1; i >= 0; i--) {
1536
+ hash = hash >> 14 & 1 | hash << 1 & 32767;
1537
+ hash ^= password.charCodeAt(i);
1538
+ }
1539
+ hash ^= password.length;
1540
+ hash ^= 52811;
1541
+ return hash.toString(16).toUpperCase().padStart(4, "0");
1542
+ }
1543
+ function serializeSheetProtection(protection) {
1544
+ if (!protection) {
1545
+ return "";
1546
+ }
1547
+ const attributes = [];
1548
+ if (protection.password) {
1549
+ attributes.push(`password="${hashPassword(protection.password)}"`);
1550
+ }
1551
+ const sheetEnabled = protection.sheet !== false;
1552
+ attributes.push(`sheet="${sheetEnabled ? "1" : "0"}"`);
1553
+ if (protection.objects !== void 0) {
1554
+ attributes.push(`objects="${protection.objects ? "1" : "0"}"`);
1555
+ }
1556
+ if (protection.scenarios !== void 0) {
1557
+ attributes.push(`scenarios="${protection.scenarios ? "1" : "0"}"`);
1558
+ }
1559
+ const protectedByDefault = [
1560
+ ["formatCells", "formatCells"],
1561
+ ["formatColumns", "formatColumns"],
1562
+ ["formatRows", "formatRows"],
1563
+ ["insertColumns", "insertColumns"],
1564
+ ["insertRows", "insertRows"],
1565
+ ["insertHyperlinks", "insertHyperlinks"],
1566
+ ["deleteColumns", "deleteColumns"],
1567
+ ["deleteRows", "deleteRows"],
1568
+ ["sort", "sort"],
1569
+ ["autoFilter", "autoFilter"],
1570
+ ["pivotTables", "pivotTables"]
1571
+ ];
1572
+ for (const [key, attr] of protectedByDefault) {
1573
+ const value = protection[key];
1574
+ if (value !== void 0) {
1575
+ attributes.push(`${attr}="${value ? "1" : "0"}"`);
1576
+ }
1577
+ }
1578
+ if (protection.selectLockedCells !== void 0) {
1579
+ attributes.push(`selectLockedCells="${protection.selectLockedCells ? "1" : "0"}"`);
1580
+ }
1581
+ if (protection.selectUnlockedCells !== void 0) {
1582
+ attributes.push(`selectUnlockedCells="${protection.selectUnlockedCells ? "1" : "0"}"`);
1583
+ }
1584
+ return `<sheetProtection ${attributes.join(" ")}/>`;
1585
+ }
1586
+ function isEmptyPlaceholderCell(cell) {
1587
+ return cell.formula === void 0 && (cell.value === null || cell.value === void 0);
1588
+ }
1589
+ function serializesCellWithoutGap(cell) {
1590
+ return cell.formula !== void 0 || cell.value !== null && cell.value !== void 0 || cell.style !== void 0;
1591
+ }
1592
+ function canInferCellRefFromPosition(cell) {
1593
+ return cell.formula === void 0 && cell.hyperlink === void 0 && cell.comment === void 0;
1594
+ }
1595
+ function columnNeedsHeuristicWidth(column) {
1596
+ return column?.width === void 0 && column?.bestFit === true;
1597
+ }
1598
+ function serializeSheetChunks(sheet, options) {
1599
+ const defaultRowHeight = String(options.defaults?.rowHeight ?? 15);
1600
+ const defaultColWidth = String(options.defaults?.columnWidth ?? 8.43);
1601
+ const rowChunkSize = Math.min(1e4, Math.max(100, options.rowChunkSize ?? 1e3));
1602
+ const sheetColumnCount = getSheetColumnCount(sheet);
1603
+ const columnLetters = Array.from({ length: sheetColumnCount }, (_unused, index) => colIndexToLetter(index));
1604
+ const tableBindings = options.tableBindings ?? [];
1605
+ const pivotTableBindings = options.pivotTableBindings ?? [];
1606
+ const dateSystem = options.dateSystem ?? "1900";
1607
+ const builder = new SheetXmlBuilder([
1608
+ `xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"`,
1609
+ `xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"`
1610
+ ]);
1611
+ const structure = compileSheetStructure(sheet);
1612
+ const sheetViewAttributes = [`workbookViewId="0"`];
1613
+ if (options.selected) {
1614
+ sheetViewAttributes.push(`tabSelected="1"`);
1615
+ }
1616
+ if (sheet.rightToLeft) {
1617
+ sheetViewAttributes.push(`rightToLeft="1"`);
1618
+ }
1619
+ const freezePane = sheet.freezePane;
1620
+ if ((freezePane?.row ?? 0) > 0 || (freezePane?.col ?? 0) > 0) {
1621
+ const xSplit = freezePane && freezePane.col > 0 ? ` xSplit="${freezePane.col}"` : "";
1622
+ const ySplit = freezePane && freezePane.row > 0 ? ` ySplit="${freezePane.row}"` : "";
1623
+ const topLeftCell = cellRef(freezePane?.row ?? 0, freezePane?.col ?? 0);
1624
+ const activePane = freezePane && freezePane.row > 0 && freezePane.col > 0 ? "bottomRight" : freezePane && freezePane.row > 0 ? "bottomLeft" : "topRight";
1625
+ builder.setSheetViews(
1626
+ `<sheetViews><sheetView ${sheetViewAttributes.join(" ")}><pane${xSplit}${ySplit} topLeftCell="${topLeftCell}" activePane="${activePane}" state="frozen"/><selection pane="${activePane}" activeCell="${topLeftCell}" sqref="${topLeftCell}"/></sheetView></sheetViews>`
1627
+ );
1628
+ } else {
1629
+ builder.setSheetViews(`<sheetViews><sheetView ${sheetViewAttributes.join(" ")}/></sheetViews>`);
1630
+ }
1631
+ const sheetPr = serializeSheetPr(sheet);
1632
+ if (sheetPr) {
1633
+ builder.setSheetPr(sheetPr);
1634
+ }
1635
+ const dimensionRef = structure.maxCol >= 0 && structure.maxRow >= 0 ? structure.maxCol === 0 && structure.maxRow === 0 ? cellRef(0, 0) : absRangeRef(0, 0, structure.maxRow, structure.maxCol).replaceAll("$", "") : "A1";
1636
+ builder.setDimension(`<dimension ref="${dimensionRef}"/>`);
1637
+ builder.setSheetFormatPr(`<sheetFormatPr defaultRowHeight="${defaultRowHeight}" defaultColWidth="${defaultColWidth}"/>`);
1638
+ const columnCount = getSheetColumnCount(sheet);
1639
+ const computedColumns = Array.from(
1640
+ { length: columnCount },
1641
+ (_unused, index) => {
1642
+ const explicit = sheet.columns?.[index];
1643
+ return explicit?.width !== void 0 ? { width: explicit.width, bestFit: explicit.bestFit ?? false } : void 0;
1644
+ }
1645
+ );
1646
+ const hyperlinkParts = [];
1647
+ const collectedComments = [];
1648
+ const worksheetRelationships = [];
1649
+ const styleAttrCache = /* @__PURE__ */ new WeakMap();
1650
+ const rawCellStyleCache = /* @__PURE__ */ new WeakMap();
1651
+ const syntheticTableCellsByRow = buildWorksheetSyntheticTableCells(tableBindings);
1652
+ const syntheticRowIndices = [...syntheticTableCellsByRow.keys()];
1653
+ const maxSyntheticRowIndex = syntheticRowIndices.length > 0 ? Math.max(...syntheticRowIndices) : -1;
1654
+ const totalSourceRows = Math.max(sheet.rows.length, maxSyntheticRowIndex + 1);
1655
+ const rowChunks = [];
1656
+ let chunkStartRowNumber = 0;
1657
+ let chunkEndRowNumber = 0;
1658
+ let chunkSourceRowCount = 0;
1659
+ let chunkSerializedRowCount = 0;
1660
+ let chunkCellCount = 0;
1661
+ let chunkXml = "";
1662
+ let totalSerializedRows = 0;
1663
+ let totalCellsWritten = 0;
1664
+ const canUseSimpleRowPath = syntheticTableCellsByRow.size === 0 && structure.mergeRanges.length === 0 && structure.rows.length === sheet.rows.length && structure.rows.every((structuredRow, rowIndex) => structuredRow.row === rowIndex && structuredRow.cells.length === (sheet.rows[rowIndex]?.cells.length ?? 0) && structuredRow.cells.every((entry, columnIndex) => entry.col === columnIndex));
1665
+ const flushChunk = () => {
1666
+ if (chunkSourceRowCount === 0) {
1667
+ return;
1668
+ }
1669
+ const xml = chunkXml;
1670
+ rowChunks.push({
1671
+ startRowNumber: chunkStartRowNumber,
1672
+ endRowNumber: chunkEndRowNumber,
1673
+ sourceRowCount: chunkSourceRowCount,
1674
+ serializedRowCount: chunkSerializedRowCount,
1675
+ cellCount: chunkCellCount,
1676
+ byteLength: Buffer.byteLength(xml, "utf8"),
1677
+ xml
1678
+ });
1679
+ chunkStartRowNumber = 0;
1680
+ chunkEndRowNumber = 0;
1681
+ chunkSourceRowCount = 0;
1682
+ chunkSerializedRowCount = 0;
1683
+ chunkCellCount = 0;
1684
+ chunkXml = "";
1685
+ };
1686
+ const positionedRowMap = canUseSimpleRowPath ? void 0 : new Map(structure.rows.map((row) => [row.row, row]));
1687
+ const originRowMap = canUseSimpleRowPath ? void 0 : new Map(structure.originCells.map((row) => [row.row, row]));
1688
+ const headerRowStyle = resolveCellStyle(sheet.styling?.headerRow, void 0);
1689
+ const alternateOddStyle = resolveCellStyle(sheet.styling?.alternateRows?.odd, void 0);
1690
+ const alternateEvenStyle = resolveCellStyle(sheet.styling?.alternateRows?.even, void 0);
1691
+ for (let rowIndex = 0; rowIndex < totalSourceRows; rowIndex += 1) {
1692
+ const row = sheet.rows[rowIndex] ?? { cells: [] };
1693
+ const mergedCells = canUseSimpleRowPath ? [] : (() => {
1694
+ const positionedRow = positionedRowMap?.get(rowIndex) ?? { row: rowIndex, cells: [] };
1695
+ const syntheticCells = syntheticTableCellsByRow.get(rowIndex) ?? [];
1696
+ const cellMap = new Map(
1697
+ positionedRow.cells.map((entry) => [entry.col, entry])
1698
+ );
1699
+ syntheticCells.forEach((entry) => {
1700
+ const existing = cellMap.get(entry.col);
1701
+ if (!existing || isEmptyPlaceholderCell(existing.cell)) {
1702
+ cellMap.set(entry.col, {
1703
+ col: entry.col,
1704
+ cell: entry.cell
1705
+ });
1706
+ }
1707
+ });
1708
+ return [...cellMap.values()].sort((left, right) => left.col - right.col);
1709
+ })();
1710
+ const rowNumber = rowIndex + 1;
1711
+ if (chunkSourceRowCount === 0) {
1712
+ chunkStartRowNumber = rowNumber;
1713
+ }
1714
+ chunkEndRowNumber = rowNumber;
1715
+ chunkSourceRowCount += 1;
1716
+ const rowStyle = rowIndex === 0 ? headerRowStyle : rowNumber % 2 === 0 ? alternateEvenStyle : alternateOddStyle;
1717
+ let cellXml = "";
1718
+ let cellCount = 0;
1719
+ let estimatedHeight = row.height;
1720
+ let adjustedHeight = row.height !== void 0;
1721
+ const originColumns = canUseSimpleRowPath ? void 0 : new Set((originRowMap?.get(rowIndex)?.cells ?? []).map((cell) => cell.col));
1722
+ const canOmitCellRefs = canUseSimpleRowPath && row.cells.length >= 16 && row.cells.every((cell) => serializesCellWithoutGap(cell) && canInferCellRefFromPosition(cell));
1723
+ if (canUseSimpleRowPath) {
1724
+ for (let col = 0; col < row.cells.length; col += 1) {
1725
+ const cell = row.cells[col];
1726
+ const needsColumnWidth = columnNeedsHeuristicWidth(sheet.columns?.[col]);
1727
+ const needsWrappedHeight = row.height === void 0;
1728
+ const needsRef = !canOmitCellRefs || cell.hyperlink !== void 0 || cell.comment !== void 0 || options.formulaEvaluator !== null && cell.formula !== void 0;
1729
+ const fallbackRef = `${columnLetters[col] ?? colIndexToLetter(col)}${rowNumber}`;
1730
+ const ref = needsRef ? fallbackRef : void 0;
1731
+ const { resolvedStyle, styleAttr } = resolveCellStyleBundle(
1732
+ cell,
1733
+ rowStyle,
1734
+ options.styleRegistry,
1735
+ styleAttrCache,
1736
+ rawCellStyleCache
1737
+ );
1738
+ const serialized = serializeCell(
1739
+ ref,
1740
+ cell,
1741
+ styleAttr,
1742
+ resolvedStyle,
1743
+ options.defaults,
1744
+ sheet.name,
1745
+ options.formulaEvaluator,
1746
+ options.sharedStrings,
1747
+ dateSystem
1748
+ );
1749
+ if (serialized) {
1750
+ cellXml += serialized;
1751
+ cellCount += 1;
1752
+ }
1753
+ let displayValue;
1754
+ if (needsColumnWidth || needsWrappedHeight && resolvedStyle?.alignment?.wrapText) {
1755
+ displayValue = getDisplayValueForMetrics(
1756
+ cell,
1757
+ options.formulaEvaluator,
1758
+ sheet.name,
1759
+ ref ?? fallbackRef
1760
+ );
1761
+ }
1762
+ if (needsColumnWidth) {
1763
+ const heuristicWidth = estimateHeuristicColumnWidth(
1764
+ displayValue,
1765
+ resolvedStyle,
1766
+ options.defaults
1767
+ );
1768
+ if (heuristicWidth !== void 0) {
1769
+ const existing = computedColumns[col];
1770
+ if (!existing || heuristicWidth > existing.width) {
1771
+ computedColumns[col] = {
1772
+ width: heuristicWidth,
1773
+ bestFit: true
1774
+ };
1775
+ }
1776
+ }
1777
+ }
1778
+ if (cell.hyperlink) {
1779
+ const hyperlink = normalizeHyperlink(cell.hyperlink);
1780
+ const attributes = [`ref="${ref}"`];
1781
+ if (hyperlink.display) {
1782
+ attributes.push(`display="${escapeXml(hyperlink.display)}"`);
1783
+ }
1784
+ if (hyperlink.tooltip) {
1785
+ attributes.push(`tooltip="${escapeXml(hyperlink.tooltip)}"`);
1786
+ }
1787
+ if (hyperlink.mode === "internal") {
1788
+ attributes.push(`location="${escapeXml(hyperlink.location)}"`);
1789
+ } else {
1790
+ const relationshipId = `rId${worksheetRelationships.length + 1}`;
1791
+ worksheetRelationships.push({
1792
+ id: relationshipId,
1793
+ target: hyperlink.target,
1794
+ type: "hyperlink"
1795
+ });
1796
+ attributes.push(`r:id="${relationshipId}"`);
1797
+ }
1798
+ hyperlinkParts.push(`<hyperlink ${attributes.join(" ")}/>`);
1799
+ }
1800
+ if (cell.comment) {
1801
+ collectedComments.push({
1802
+ ref,
1803
+ row: rowIndex,
1804
+ col,
1805
+ author: cell.comment.author,
1806
+ text: cell.comment.text
1807
+ });
1808
+ }
1809
+ if (needsWrappedHeight && resolvedStyle?.alignment?.wrapText) {
1810
+ const wrappedHeight = estimateWrappedCellHeight(
1811
+ { ...cell, value: displayValue },
1812
+ resolvedStyle,
1813
+ computedColumns[col]?.width ?? (options.defaults?.columnWidth ?? 8.43),
1814
+ options.defaults
1815
+ );
1816
+ if (wrappedHeight !== void 0) {
1817
+ estimatedHeight = Math.max(estimatedHeight ?? (options.defaults?.rowHeight ?? 15), wrappedHeight);
1818
+ adjustedHeight = true;
1819
+ }
1820
+ }
1821
+ }
1822
+ } else {
1823
+ for (const { cell, col } of mergedCells) {
1824
+ let ref;
1825
+ const isOriginCell = originColumns?.has(col) === true;
1826
+ const needsColumnWidth = isOriginCell && columnNeedsHeuristicWidth(sheet.columns?.[col]);
1827
+ const needsWrappedHeight = row.height === void 0;
1828
+ const needsRef = !canOmitCellRefs || isOriginCell && (cell.hyperlink !== void 0 || cell.comment !== void 0) || options.formulaEvaluator !== null && cell.formula !== void 0;
1829
+ const ensureRef = () => {
1830
+ if (ref === void 0) {
1831
+ ref = `${columnLetters[col] ?? colIndexToLetter(col)}${rowNumber}`;
1832
+ }
1833
+ return ref;
1834
+ };
1835
+ const { resolvedStyle, styleAttr } = resolveCellStyleBundle(
1836
+ cell,
1837
+ rowStyle,
1838
+ options.styleRegistry,
1839
+ styleAttrCache,
1840
+ rawCellStyleCache
1841
+ );
1842
+ const serialized = serializeCell(
1843
+ needsRef ? ensureRef() : void 0,
1844
+ cell,
1845
+ styleAttr,
1846
+ resolvedStyle,
1847
+ options.defaults,
1848
+ sheet.name,
1849
+ options.formulaEvaluator,
1850
+ options.sharedStrings,
1851
+ dateSystem
1852
+ );
1853
+ if (serialized) {
1854
+ cellXml += serialized;
1855
+ cellCount += 1;
1856
+ }
1857
+ let displayValue;
1858
+ const getDisplayValue = () => {
1859
+ if (displayValue === void 0) {
1860
+ displayValue = getDisplayValueForMetrics(
1861
+ cell,
1862
+ options.formulaEvaluator,
1863
+ sheet.name,
1864
+ needsRef ? ensureRef() : `${columnLetters[col] ?? colIndexToLetter(col)}${rowNumber}`
1865
+ );
1866
+ }
1867
+ return displayValue;
1868
+ };
1869
+ if (needsColumnWidth) {
1870
+ const heuristicWidth = estimateHeuristicColumnWidth(
1871
+ getDisplayValue(),
1872
+ resolvedStyle,
1873
+ options.defaults
1874
+ );
1875
+ if (heuristicWidth !== void 0) {
1876
+ const existing = computedColumns[col];
1877
+ if (!existing || heuristicWidth > existing.width) {
1878
+ computedColumns[col] = {
1879
+ width: heuristicWidth,
1880
+ bestFit: true
1881
+ };
1882
+ }
1883
+ }
1884
+ }
1885
+ if (isOriginCell && cell.hyperlink) {
1886
+ const refValue = ensureRef();
1887
+ const hyperlink = normalizeHyperlink(cell.hyperlink);
1888
+ const attributes = [`ref="${refValue}"`];
1889
+ if (hyperlink.display) {
1890
+ attributes.push(`display="${escapeXml(hyperlink.display)}"`);
1891
+ }
1892
+ if (hyperlink.tooltip) {
1893
+ attributes.push(`tooltip="${escapeXml(hyperlink.tooltip)}"`);
1894
+ }
1895
+ if (hyperlink.mode === "internal") {
1896
+ attributes.push(`location="${escapeXml(hyperlink.location)}"`);
1897
+ } else {
1898
+ const relationshipId = `rId${worksheetRelationships.length + 1}`;
1899
+ worksheetRelationships.push({
1900
+ id: relationshipId,
1901
+ target: hyperlink.target,
1902
+ type: "hyperlink"
1903
+ });
1904
+ attributes.push(`r:id="${relationshipId}"`);
1905
+ }
1906
+ hyperlinkParts.push(`<hyperlink ${attributes.join(" ")}/>`);
1907
+ }
1908
+ if (isOriginCell && cell.comment) {
1909
+ collectedComments.push({
1910
+ ref: ensureRef(),
1911
+ row: rowIndex,
1912
+ col,
1913
+ author: cell.comment.author,
1914
+ text: cell.comment.text
1915
+ });
1916
+ }
1917
+ if (needsWrappedHeight && resolvedStyle?.alignment?.wrapText) {
1918
+ const wrappedHeight = estimateWrappedCellHeight(
1919
+ { ...cell, value: getDisplayValue() },
1920
+ resolvedStyle,
1921
+ computedColumns[col]?.width ?? (options.defaults?.columnWidth ?? 8.43),
1922
+ options.defaults
1923
+ );
1924
+ if (wrappedHeight !== void 0) {
1925
+ estimatedHeight = Math.max(estimatedHeight ?? (options.defaults?.rowHeight ?? 15), wrappedHeight);
1926
+ adjustedHeight = true;
1927
+ }
1928
+ }
1929
+ }
1930
+ }
1931
+ const shouldSerializeRow = cellCount > 0 || row.hidden || estimatedHeight !== void 0;
1932
+ if (!shouldSerializeRow) {
1933
+ continue;
1934
+ }
1935
+ const canOmitRowRef = canOmitCellRefs && totalSourceRows >= LARGE_ROW_REF_OMISSION_THRESHOLD && !adjustedHeight && !row.hidden;
1936
+ if (canOmitRowRef) {
1937
+ chunkXml += `${SIMPLE_ROW_OPEN_TAG}${cellXml}${SIMPLE_ROW_CLOSE_TAG}`;
1938
+ } else if (!adjustedHeight && !row.hidden) {
1939
+ chunkXml += `<row r="${rowNumber}">${cellXml}</row>`;
1940
+ } else {
1941
+ const rowAttributes = [`r="${rowNumber}"`];
1942
+ if (estimatedHeight !== void 0 && adjustedHeight) {
1943
+ rowAttributes.push(`ht="${estimatedHeight}"`, `customHeight="1"`);
1944
+ }
1945
+ if (row.hidden) {
1946
+ rowAttributes.push(`hidden="1"`);
1947
+ }
1948
+ chunkXml += `<row ${rowAttributes.join(" ")}>${cellXml}</row>`;
1949
+ }
1950
+ chunkSerializedRowCount += 1;
1951
+ totalSerializedRows += 1;
1952
+ chunkCellCount += cellCount;
1953
+ totalCellsWritten += cellCount;
1954
+ if (chunkSourceRowCount >= rowChunkSize) {
1955
+ flushChunk();
1956
+ }
1957
+ }
1958
+ flushChunk();
1959
+ const columnLayout = buildColumnLayout(sheet, computedColumns, options.defaults);
1960
+ if (columnLayout.segments.length > 0) {
1961
+ builder.setCols(`<cols>${columnLayout.segments.map((segment) => {
1962
+ const attributes = [`min="${segment.start}"`, `max="${segment.end}"`, `width="${segment.width}"`];
1963
+ if (segment.customWidth) attributes.push(`customWidth="1"`);
1964
+ if (segment.hidden) attributes.push(`hidden="1"`);
1965
+ if (segment.bestFit) attributes.push(`bestFit="1"`);
1966
+ return `<col ${attributes.join(" ")}/>`;
1967
+ }).join("")}</cols>`);
1968
+ }
1969
+ if (structure.autoFilterRef) {
1970
+ builder.setAutoFilter(`<autoFilter ref="${structure.autoFilterRef}"/>`);
1971
+ }
1972
+ const sheetProtectionXml = serializeSheetProtection(sheet.protection);
1973
+ if (sheetProtectionXml) {
1974
+ builder.setSheetProtection(sheetProtectionXml);
1975
+ }
1976
+ if (structure.mergeRanges.length > 0) {
1977
+ builder.setMergeCells(
1978
+ `<mergeCells count="${structure.mergeRanges.length}">${structure.mergeRanges.map((merge) => `<mergeCell ref="${merge.ref}"/>`).join("")}</mergeCells>`
1979
+ );
1980
+ }
1981
+ const conditionalFormatting = serializeConditionalFormatting(sheet.conditionalFormatting, options.styleRegistry);
1982
+ if (conditionalFormatting.xml) {
1983
+ builder.addConditionalFormatting(conditionalFormatting.xml);
1984
+ }
1985
+ if (conditionalFormatting.extLst) {
1986
+ builder.setExtLst(conditionalFormatting.extLst);
1987
+ }
1988
+ const dataValidations = serializeDataValidations(sheet.dataValidations, dateSystem);
1989
+ if (dataValidations) {
1990
+ builder.setDataValidations(dataValidations);
1991
+ }
1992
+ if (hyperlinkParts.length > 0) {
1993
+ builder.setHyperlinks(`<hyperlinks>${hyperlinkParts.join("")}</hyperlinks>`);
1994
+ }
1995
+ const printOptions = serializePrintOptions(sheet);
1996
+ if (printOptions) {
1997
+ builder.setPrintOptions(printOptions);
1998
+ }
1999
+ const pageMargins = serializePageMargins(sheet);
2000
+ if (pageMargins) {
2001
+ builder.setPageMargins(pageMargins);
2002
+ }
2003
+ const pageSetup = serializePageSetup(sheet);
2004
+ if (pageSetup) {
2005
+ builder.setPageSetup(pageSetup);
2006
+ }
2007
+ if (tableBindings.length > 0) {
2008
+ const tableParts = tableBindings.map((binding) => {
2009
+ const relationshipId = `rId${worksheetRelationships.length + 1}`;
2010
+ worksheetRelationships.push({
2011
+ id: relationshipId,
2012
+ target: `../tables/${binding.partName}`,
2013
+ type: "table"
2014
+ });
2015
+ return `<tablePart r:id="${relationshipId}"/>`;
2016
+ });
2017
+ builder.setTableParts(`<tableParts count="${tableParts.length}">${tableParts.join("")}</tableParts>`);
2018
+ }
2019
+ if (pivotTableBindings.length > 0) {
2020
+ pivotTableBindings.forEach((binding) => {
2021
+ const relationshipId = `rId${worksheetRelationships.length + 1}`;
2022
+ worksheetRelationships.push({
2023
+ id: relationshipId,
2024
+ target: `../pivotTables/${binding.partName}`,
2025
+ type: "pivotTable"
2026
+ });
2027
+ });
2028
+ }
2029
+ if (collectedComments.length > 0) {
2030
+ const sheetNumber = options.sheetIndex + 1;
2031
+ const commentRelId = `rId${worksheetRelationships.length + 1}`;
2032
+ worksheetRelationships.push({
2033
+ id: commentRelId,
2034
+ target: `../comments${sheetNumber}.xml`,
2035
+ type: "comment"
2036
+ });
2037
+ const vmlRelId = `rId${worksheetRelationships.length + 1}`;
2038
+ worksheetRelationships.push({
2039
+ id: vmlRelId,
2040
+ target: `../drawings/vmlDrawing${sheetNumber}.vml`,
2041
+ type: "vmlDrawing"
2042
+ });
2043
+ builder.setLegacyDrawing(`<legacyDrawing r:id="${vmlRelId}"/>`);
2044
+ }
2045
+ const hasImages = sheet.images && sheet.images.length > 0;
2046
+ const hasCharts = sheet.charts && sheet.charts.length > 0;
2047
+ if (hasImages || hasCharts) {
2048
+ const drawingRelId = `rId${worksheetRelationships.length + 1}`;
2049
+ const sheetNumber = options.sheetIndex + 1;
2050
+ worksheetRelationships.push({
2051
+ id: drawingRelId,
2052
+ target: `../drawings/drawing${sheetNumber}.xml`,
2053
+ type: "drawing"
2054
+ });
2055
+ builder.setDrawing(`<drawing r:id="${drawingRelId}"/>`);
2056
+ }
2057
+ const envelope = builder.buildSheetDataEnvelope();
2058
+ return {
2059
+ prefix: envelope.prefix,
2060
+ suffix: envelope.suffix,
2061
+ rowChunks,
2062
+ comments: collectedComments,
2063
+ metrics: {
2064
+ totalRowsWritten: totalSourceRows,
2065
+ totalSerializedRows,
2066
+ totalCellsWritten,
2067
+ chunkCount: rowChunks.length
2068
+ },
2069
+ autoFilterRef: structure.autoFilterRef,
2070
+ printArea: sheet.pageSetup?.printArea,
2071
+ printTitles: sheet.pageSetup?.printTitles,
2072
+ relationships: worksheetRelationships.length > 0 ? serializeWorksheetRelationships(worksheetRelationships) : void 0
2073
+ };
2074
+ }
2075
+
2076
+ // src/styles/component-registry.ts
2077
+ function stableNormalize(value) {
2078
+ if (Array.isArray(value)) {
2079
+ return value.map((entry) => stableNormalize(entry));
2080
+ }
2081
+ if (value && typeof value === "object" && !(value instanceof Date)) {
2082
+ const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([left], [right]) => left.localeCompare(right));
2083
+ return Object.fromEntries(entries.map(([key, entry]) => [key, stableNormalize(entry)]));
2084
+ }
2085
+ return value;
2086
+ }
2087
+ function stableStringify(value) {
2088
+ return JSON.stringify(stableNormalize(value));
2089
+ }
2090
+ var ComponentRegistry = class {
2091
+ constructor(seedEntries = [], keyFn = stableStringify) {
2092
+ this.keyFn = keyFn;
2093
+ for (const entry of seedEntries) {
2094
+ this.register(entry);
2095
+ }
2096
+ }
2097
+ entries = [];
2098
+ keyMap = /* @__PURE__ */ new Map();
2099
+ refMap = /* @__PURE__ */ new WeakMap();
2100
+ register(entry) {
2101
+ if (entry && typeof entry === "object") {
2102
+ const cached = this.refMap.get(entry);
2103
+ if (cached !== void 0) {
2104
+ return cached;
2105
+ }
2106
+ }
2107
+ const key = this.keyFn(entry);
2108
+ const existing = this.keyMap.get(key);
2109
+ if (existing !== void 0) {
2110
+ if (entry && typeof entry === "object") {
2111
+ this.refMap.set(entry, existing);
2112
+ }
2113
+ return existing;
2114
+ }
2115
+ const index = this.entries.length;
2116
+ this.entries.push(entry);
2117
+ this.keyMap.set(key, index);
2118
+ if (entry && typeof entry === "object") {
2119
+ this.refMap.set(entry, index);
2120
+ }
2121
+ return index;
2122
+ }
2123
+ get size() {
2124
+ return this.entries.length;
2125
+ }
2126
+ get values() {
2127
+ return this.entries;
2128
+ }
2129
+ };
2130
+
2131
+ // src/styles/fill-serializer.ts
2132
+ var NONE_FILL = { type: "pattern", patternType: "none" };
2133
+ var GRAY125_FILL = { type: "pattern", patternType: "gray125" };
2134
+ function serializeFill(fill) {
2135
+ if (fill.patternType === "none" || fill.patternType === "gray125") {
2136
+ return `<fill><patternFill patternType="${fill.patternType}"/></fill>`;
2137
+ }
2138
+ const patternType = fill.patternType ?? (fill.type === "pattern" ? "darkGray" : "solid");
2139
+ const parts = [`<fill><patternFill patternType="${patternType}">`];
2140
+ if (fill.fgColor) {
2141
+ parts.push(`<fgColor ${serializeColorAttributes(fill.fgColor)}/>`);
2142
+ }
2143
+ if (fill.type !== "solid" && fill.bgColor) {
2144
+ parts.push(`<bgColor ${serializeColorAttributes(fill.bgColor)}/>`);
2145
+ }
2146
+ parts.push("</patternFill></fill>");
2147
+ return parts.join("");
2148
+ }
2149
+ function serializeDxfFill(fill) {
2150
+ if (!fill?.fgColor && !fill?.bgColor) {
2151
+ return "";
2152
+ }
2153
+ const color = fill.bgColor ?? fill.fgColor;
2154
+ if (!color) {
2155
+ return "";
2156
+ }
2157
+ return `<fill><patternFill><bgColor ${serializeColorAttributes(color)}/></patternFill></fill>`;
2158
+ }
2159
+
2160
+ // src/styles/border-serializer.ts
2161
+ var EMPTY_BORDER = {};
2162
+ function serializeEdge(name, edge) {
2163
+ if (!edge) {
2164
+ return "";
2165
+ }
2166
+ const parts = [`<${name} style="${edge.style}">`];
2167
+ if (edge.color) {
2168
+ parts.push(`<color ${serializeColorAttributes(edge.color)}/>`);
2169
+ }
2170
+ parts.push(`</${name}>`);
2171
+ return parts.join("");
2172
+ }
2173
+ function serializeBorder(border) {
2174
+ const diagonalUp = border.diagonal?.direction === "up" || border.diagonal?.direction === "both" ? ` diagonalUp="1"` : "";
2175
+ const diagonalDown = border.diagonal?.direction === "down" || border.diagonal?.direction === "both" ? ` diagonalDown="1"` : "";
2176
+ const left = serializeEdge("left", border.left);
2177
+ const right = serializeEdge("right", border.right);
2178
+ const top = serializeEdge("top", border.top);
2179
+ const bottom = serializeEdge("bottom", border.bottom);
2180
+ const diagonal = serializeEdge("diagonal", border.diagonal);
2181
+ if (!diagonalUp && !diagonalDown && !left && !right && !top && !bottom && !diagonal) {
2182
+ return "<border/>";
2183
+ }
2184
+ return [
2185
+ `<border${diagonalUp}${diagonalDown}>`,
2186
+ left,
2187
+ right,
2188
+ top,
2189
+ bottom,
2190
+ diagonal,
2191
+ `</border>`
2192
+ ].join("");
2193
+ }
2194
+ function serializeDxfBorder(border) {
2195
+ if (!border) {
2196
+ return "";
2197
+ }
2198
+ return serializeBorder(border);
2199
+ }
2200
+
2201
+ // src/styles/numfmt-registry.ts
2202
+ var BUILT_IN_FORMATS = /* @__PURE__ */ new Map([
2203
+ ["General", 0],
2204
+ ["0", 1],
2205
+ ["0.00", 2],
2206
+ ["#,##0", 3],
2207
+ ["#,##0.00", 4],
2208
+ ["0%", 9],
2209
+ ["0.00%", 10],
2210
+ ["0.00E+00", 11],
2211
+ ["# ?/?", 12],
2212
+ ["# ??/??", 13],
2213
+ ["mm-dd-yy", 14],
2214
+ ["d-mmm-yy", 15],
2215
+ ["d-mmm", 16],
2216
+ ["mmm-yy", 17],
2217
+ ["h:mm AM/PM", 18],
2218
+ ["h:mm:ss AM/PM", 19],
2219
+ ["h:mm", 20],
2220
+ ["h:mm:ss", 21],
2221
+ ["m/d/yy h:mm", 22],
2222
+ ["#,##0 ;(#,##0)", 37],
2223
+ ["#,##0 ;[Red](#,##0)", 38],
2224
+ ["#,##0.00;(#,##0.00)", 39],
2225
+ ["#,##0.00;[Red](#,##0.00)", 40],
2226
+ ["mm:ss", 45],
2227
+ ["[h]:mm:ss", 46],
2228
+ ["mmss.0", 47],
2229
+ ["##0.0E+0", 48],
2230
+ ["@", 49]
2231
+ ]);
2232
+ var NumFmtRegistry = class {
2233
+ customFormats = /* @__PURE__ */ new Map();
2234
+ nextCustomId = 164;
2235
+ register(formatCode) {
2236
+ if (!formatCode) {
2237
+ return 0;
2238
+ }
2239
+ const builtIn = BUILT_IN_FORMATS.get(formatCode);
2240
+ if (builtIn !== void 0) {
2241
+ return builtIn;
2242
+ }
2243
+ const existing = this.customFormats.get(formatCode);
2244
+ if (existing !== void 0) {
2245
+ return existing;
2246
+ }
2247
+ const id = this.nextCustomId;
2248
+ this.customFormats.set(formatCode, id);
2249
+ this.nextCustomId += 1;
2250
+ return id;
2251
+ }
2252
+ toXml() {
2253
+ if (this.customFormats.size === 0) {
2254
+ return "";
2255
+ }
2256
+ const parts = [`<numFmts count="${this.customFormats.size}">`];
2257
+ for (const [formatCode, id] of this.customFormats) {
2258
+ parts.push(`<numFmt numFmtId="${id}" formatCode="${escapeXml(formatCode)}"/>`);
2259
+ }
2260
+ parts.push(`</numFmts>`);
2261
+ return parts.join("");
2262
+ }
2263
+ };
2264
+
2265
+ // src/styles/style-registry.ts
2266
+ function fontKey(font) {
2267
+ return [
2268
+ font.family,
2269
+ font.size,
2270
+ font.bold ? 1 : 0,
2271
+ font.italic ? 1 : 0,
2272
+ font.underline === true ? "single" : font.underline ?? "",
2273
+ font.strikethrough ? 1 : 0,
2274
+ font.color ?? "",
2275
+ font.vertAlign ?? "",
2276
+ font.charset ?? "",
2277
+ font.familyClassification ?? "",
2278
+ font.scheme ?? ""
2279
+ ].join("|");
2280
+ }
2281
+ function fillKey(fill) {
2282
+ return [
2283
+ fill.type,
2284
+ fill.patternType ?? "",
2285
+ fill.fgColor ?? "",
2286
+ fill.bgColor ?? "",
2287
+ fill.color ?? ""
2288
+ ].join("|");
2289
+ }
2290
+ function edgeKey(edge) {
2291
+ if (!edge) {
2292
+ return "";
2293
+ }
2294
+ return `${edge.style}:${edge.color ?? ""}`;
2295
+ }
2296
+ function borderKey(border) {
2297
+ return [
2298
+ edgeKey(border.left),
2299
+ edgeKey(border.right),
2300
+ edgeKey(border.top),
2301
+ edgeKey(border.bottom),
2302
+ border.diagonal ? `${border.diagonal.style}:${border.diagonal.color ?? ""}:${border.diagonal.direction ?? ""}` : ""
2303
+ ].join("|");
2304
+ }
2305
+ function alignmentKey(alignment) {
2306
+ if (!alignment) {
2307
+ return "";
2308
+ }
2309
+ return [
2310
+ alignment.horizontal ?? "",
2311
+ alignment.vertical ?? "",
2312
+ alignment.wrapText ? 1 : 0,
2313
+ alignment.textRotation ?? "",
2314
+ alignment.indent ?? "",
2315
+ alignment.shrinkToFit ? 1 : 0,
2316
+ alignment.readingOrder ?? ""
2317
+ ].join("|");
2318
+ }
2319
+ function protectionKey(protection) {
2320
+ if (!protection) {
2321
+ return "";
2322
+ }
2323
+ return [
2324
+ protection.locked === void 0 ? "" : protection.locked ? 1 : 0,
2325
+ protection.hidden === void 0 ? "" : protection.hidden ? 1 : 0
2326
+ ].join("|");
2327
+ }
2328
+ function cellXfKey(xf) {
2329
+ return [
2330
+ xf.numFmtId,
2331
+ xf.fontId,
2332
+ xf.fillId,
2333
+ xf.borderId,
2334
+ xf.xfId,
2335
+ alignmentKey(xf.alignment),
2336
+ protectionKey(xf.protection)
2337
+ ].join("|");
2338
+ }
2339
+ function styleKey(style) {
2340
+ return [
2341
+ style.numberFormat ?? "",
2342
+ style.font ? fontKey({
2343
+ family: style.font.family ?? "",
2344
+ size: style.font.size ?? 0,
2345
+ bold: style.font.bold,
2346
+ italic: style.font.italic,
2347
+ underline: style.font.underline,
2348
+ strikethrough: style.font.strikethrough,
2349
+ color: style.font.color,
2350
+ vertAlign: style.font.vertAlign,
2351
+ charset: style.font.charset
2352
+ }) : "",
2353
+ style.fill ? fillKey(style.fill) : "",
2354
+ style.border ? borderKey(style.border) : "",
2355
+ alignmentKey(style.alignment),
2356
+ protectionKey(style.protection)
2357
+ ].join("||");
2358
+ }
2359
+ var DEFAULT_FONT_FAMILY = "Calibri";
2360
+ var DEFAULT_FONT_SIZE = 11;
2361
+ var DEFAULT_FONT = {
2362
+ family: DEFAULT_FONT_FAMILY,
2363
+ size: DEFAULT_FONT_SIZE,
2364
+ color: "theme:1",
2365
+ familyClassification: 2,
2366
+ scheme: "minor"
2367
+ };
2368
+ var DEFAULT_XF = {
2369
+ numFmtId: 0,
2370
+ fontId: 0,
2371
+ fillId: 0,
2372
+ borderId: 0,
2373
+ xfId: 0
2374
+ };
2375
+ function serializeAlignment(alignment) {
2376
+ if (!alignment) {
2377
+ return "";
2378
+ }
2379
+ const attributes = [];
2380
+ if (alignment.horizontal) attributes.push(`horizontal="${alignment.horizontal}"`);
2381
+ if (alignment.vertical) attributes.push(`vertical="${alignment.vertical}"`);
2382
+ if (alignment.wrapText) attributes.push(`wrapText="1"`);
2383
+ if (alignment.textRotation !== void 0) attributes.push(`textRotation="${alignment.textRotation}"`);
2384
+ if (alignment.indent !== void 0) attributes.push(`indent="${alignment.indent}"`);
2385
+ if (alignment.shrinkToFit) attributes.push(`shrinkToFit="1"`);
2386
+ if (alignment.readingOrder !== void 0) attributes.push(`readingOrder="${alignment.readingOrder}"`);
2387
+ return attributes.length > 0 ? `<alignment ${attributes.join(" ")}/>` : "";
2388
+ }
2389
+ function serializeProtection(protection) {
2390
+ if (!protection) {
2391
+ return "";
2392
+ }
2393
+ const attributes = [];
2394
+ if (protection.locked !== void 0) attributes.push(`locked="${protection.locked ? 1 : 0}"`);
2395
+ if (protection.hidden !== void 0) attributes.push(`hidden="${protection.hidden ? 1 : 0}"`);
2396
+ return attributes.length > 0 ? `<protection ${attributes.join(" ")}/>` : "";
2397
+ }
2398
+ function serializeCellXf(xf) {
2399
+ const attributes = [
2400
+ `numFmtId="${xf.numFmtId}"`,
2401
+ `fontId="${xf.fontId}"`,
2402
+ `fillId="${xf.fillId}"`,
2403
+ `borderId="${xf.borderId}"`
2404
+ ];
2405
+ if (xf.xfId !== 0) {
2406
+ attributes.push(`xfId="${xf.xfId}"`);
2407
+ }
2408
+ const alignment = serializeAlignment(xf.alignment);
2409
+ const protection = serializeProtection(xf.protection);
2410
+ if (!alignment && !protection) {
2411
+ return `<xf ${attributes.join(" ")}/>`;
2412
+ }
2413
+ return `<xf ${attributes.join(" ")}>${alignment}${protection}</xf>`;
2414
+ }
2415
+ function normalizeFont2(font, defaults) {
2416
+ return {
2417
+ family: font?.family ?? defaults?.font?.family ?? DEFAULT_FONT_FAMILY,
2418
+ size: font?.size ?? defaults?.font?.size ?? DEFAULT_FONT_SIZE,
2419
+ bold: font?.bold,
2420
+ italic: font?.italic,
2421
+ underline: font?.underline,
2422
+ strikethrough: font?.strikethrough,
2423
+ color: font?.color,
2424
+ vertAlign: font?.vertAlign,
2425
+ charset: font?.charset
2426
+ };
2427
+ }
2428
+ var StyleRegistry = class {
2429
+ constructor(defaults) {
2430
+ this.defaults = defaults;
2431
+ const seededDefaultFont = {
2432
+ ...DEFAULT_FONT,
2433
+ family: defaults?.font?.family ?? DEFAULT_FONT.family,
2434
+ size: defaults?.font?.size ?? DEFAULT_FONT.size
2435
+ };
2436
+ this.defaultFontFamily = seededDefaultFont.family;
2437
+ this.defaultFontSize = seededDefaultFont.size;
2438
+ this.fontRegistry = new ComponentRegistry([seededDefaultFont], fontKey);
2439
+ this.fillRegistry = new ComponentRegistry([NONE_FILL, GRAY125_FILL], fillKey);
2440
+ this.borderRegistry = new ComponentRegistry([EMPTY_BORDER], borderKey);
2441
+ this.cellXfRegistry = new ComponentRegistry([DEFAULT_XF], cellXfKey);
2442
+ this.dxfRegistry = new ComponentRegistry([], styleKey);
2443
+ }
2444
+ fontRegistry;
2445
+ fillRegistry;
2446
+ borderRegistry;
2447
+ numFmtRegistry = new NumFmtRegistry();
2448
+ cellXfRegistry;
2449
+ dxfRegistry;
2450
+ styleIndexCache = /* @__PURE__ */ new WeakMap();
2451
+ dxfIndexCache = /* @__PURE__ */ new WeakMap();
2452
+ defaultFontFamily;
2453
+ defaultFontSize;
2454
+ registerStyle(styleInput, cellValue) {
2455
+ const style = resolveCellStyle(styleInput, cellValue);
2456
+ return this.registerResolvedStyle(style);
2457
+ }
2458
+ registerResolvedStyle(style) {
2459
+ if (!style) {
2460
+ return 0;
2461
+ }
2462
+ const cached = this.styleIndexCache.get(style);
2463
+ if (cached !== void 0) {
2464
+ return cached;
2465
+ }
2466
+ const numFmtId = this.numFmtRegistry.register(style.numberFormat);
2467
+ const fontDef = normalizeFont2(style.font, this.defaults);
2468
+ const fontId = fontDef.family === this.defaultFontFamily && fontDef.size === this.defaultFontSize && !fontDef.bold && !fontDef.italic && !fontDef.underline && !fontDef.strikethrough && !fontDef.color && !fontDef.vertAlign && fontDef.charset === void 0 ? 0 : this.fontRegistry.register(fontDef);
2469
+ const fillDef = normalizeFill(style.fill);
2470
+ const fillId = fillDef ? this.fillRegistry.register(fillDef) : 0;
2471
+ const borderId = style.border ? this.borderRegistry.register(style.border) : 0;
2472
+ const xf = {
2473
+ numFmtId,
2474
+ fontId,
2475
+ fillId,
2476
+ borderId,
2477
+ xfId: 0,
2478
+ alignment: style.alignment,
2479
+ protection: style.protection
2480
+ };
2481
+ const index = this.cellXfRegistry.register(xf);
2482
+ this.styleIndexCache.set(style, index);
2483
+ return index;
2484
+ }
2485
+ registerDxf(styleInput) {
2486
+ const style = resolveCellStyle(styleInput, void 0);
2487
+ if (!style) {
2488
+ return 0;
2489
+ }
2490
+ const cached = this.dxfIndexCache.get(style);
2491
+ if (cached !== void 0) {
2492
+ return cached;
2493
+ }
2494
+ const index = this.dxfRegistry.register(style);
2495
+ this.dxfIndexCache.set(style, index);
2496
+ return index;
2497
+ }
2498
+ getDefaultFont() {
2499
+ return this.fontRegistry.values[0] ?? DEFAULT_FONT;
2500
+ }
2501
+ get cellStyleCount() {
2502
+ return this.cellXfRegistry.size;
2503
+ }
2504
+ get differentialStyleCount() {
2505
+ return this.dxfRegistry.values.length;
2506
+ }
2507
+ toXml() {
2508
+ const dxfs = this.dxfRegistry.values;
2509
+ return [
2510
+ XML_DECLARATION,
2511
+ `<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`,
2512
+ this.numFmtRegistry.toXml(),
2513
+ `<fonts count="${this.fontRegistry.size}">${this.fontRegistry.values.map((font) => serializeFont(font)).join("")}</fonts>`,
2514
+ `<fills count="${this.fillRegistry.size}">${this.fillRegistry.values.map((fill) => serializeFill(fill)).join("")}</fills>`,
2515
+ `<borders count="${this.borderRegistry.size}">${this.borderRegistry.values.map((border) => serializeBorder(border)).join("")}</borders>`,
2516
+ `<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>`,
2517
+ `<cellXfs count="${this.cellXfRegistry.size}">${this.cellXfRegistry.values.map((xf) => serializeCellXf(xf)).join("")}</cellXfs>`,
2518
+ `<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>`,
2519
+ dxfs.length === 0 ? `<dxfs count="0"/>` : `<dxfs count="${dxfs.length}">${dxfs.map((style) => {
2520
+ const font = style.font ? `<font>${serializeFont(normalizeFont2(style.font, this.defaults)).replace(/^<font>|<\/font>$/g, "")}</font>` : "";
2521
+ const fill = serializeDxfFill(normalizeFill(style.fill));
2522
+ const border = serializeDxfBorder(style.border);
2523
+ const numFmt = style.numberFormat ? `<numFmt numFmtId="0" formatCode="${escapeXml(style.numberFormat)}"/>` : "";
2524
+ const alignment = serializeAlignment(style.alignment);
2525
+ return `<dxf>${numFmt}${font}${fill}${border}${alignment}</dxf>`;
2526
+ }).join("")}</dxfs>`,
2527
+ `<tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/>`,
2528
+ `</styleSheet>`
2529
+ ].join("");
2530
+ }
2531
+ };
2532
+
2533
+ // src/workers/sheet-serializer-worker.ts
2534
+ if (!parentPort) {
2535
+ throw new Error("XLSX sheet serializer worker requires parentPort");
2536
+ }
2537
+ parentPort.on("message", (request) => {
2538
+ try {
2539
+ const artifacts = request.tasks.map((task) => serializeSheetChunks(task.sheet, {
2540
+ dateSystem: task.dateSystem,
2541
+ defaults: task.defaults,
2542
+ formulaEvaluator: null,
2543
+ rowChunkSize: task.rowChunkSize,
2544
+ selected: task.selected,
2545
+ sheetIndex: task.sheetIndex,
2546
+ stringStrategy: task.stringStrategy,
2547
+ styleRegistry: new StyleRegistry(task.defaults)
2548
+ }));
2549
+ parentPort.postMessage({
2550
+ id: request.id,
2551
+ ok: true,
2552
+ artifacts
2553
+ });
2554
+ } catch (error) {
2555
+ parentPort.postMessage({
2556
+ id: request.id,
2557
+ ok: false,
2558
+ error: {
2559
+ message: error instanceof Error ? error.message : String(error),
2560
+ stack: error instanceof Error ? error.stack : void 0
2561
+ }
2562
+ });
2563
+ }
2564
+ });
2565
+ //# sourceMappingURL=sheet-serializer-worker.js.map