@ai-matrx/office 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/chunk-5T2M6LSI.js +529 -0
  3. package/dist/chunk-5T2M6LSI.js.map +1 -0
  4. package/dist/chunk-QZE7HBZB.cjs +529 -0
  5. package/dist/chunk-QZE7HBZB.cjs.map +1 -0
  6. package/dist/chunk-WKBWRG7N.js +209 -0
  7. package/dist/chunk-WKBWRG7N.js.map +1 -0
  8. package/dist/chunk-ZDZCCOUB.cjs +209 -0
  9. package/dist/chunk-ZDZCCOUB.cjs.map +1 -0
  10. package/dist/core.d.cts +5 -1
  11. package/dist/core.d.ts +5 -1
  12. package/dist/matrxImagePorts-JDFYE4QI.cjs +59 -0
  13. package/dist/matrxImagePorts-JDFYE4QI.cjs.map +1 -0
  14. package/dist/matrxImagePorts-VPBBUADM.js +59 -0
  15. package/dist/matrxImagePorts-VPBBUADM.js.map +1 -0
  16. package/dist/sheets-xlsx.cjs +525 -0
  17. package/dist/sheets-xlsx.cjs.map +1 -0
  18. package/dist/sheets-xlsx.d.cts +153 -0
  19. package/dist/sheets-xlsx.d.ts +153 -0
  20. package/dist/sheets-xlsx.js +525 -0
  21. package/dist/sheets-xlsx.js.map +1 -0
  22. package/dist/sheets.cjs +921 -0
  23. package/dist/sheets.cjs.map +1 -0
  24. package/dist/sheets.d.cts +605 -0
  25. package/dist/sheets.d.ts +605 -0
  26. package/dist/sheets.js +921 -0
  27. package/dist/sheets.js.map +1 -0
  28. package/dist/univer-collab.cjs +2 -78
  29. package/dist/univer-collab.cjs.map +1 -1
  30. package/dist/univer-collab.d.cts +7 -15
  31. package/dist/univer-collab.d.ts +7 -15
  32. package/dist/univer-collab.js +2 -78
  33. package/dist/univer-collab.js.map +1 -1
  34. package/dist/univer-realtime.cjs +102 -0
  35. package/dist/univer-realtime.cjs.map +1 -0
  36. package/dist/univer-realtime.d.cts +15 -0
  37. package/dist/univer-realtime.d.ts +15 -0
  38. package/dist/univer-realtime.js +80 -0
  39. package/dist/univer-realtime.js.map +1 -0
  40. package/dist/xlsx-to-univer-AQAXU3TC.cjs +7 -0
  41. package/dist/xlsx-to-univer-AQAXU3TC.cjs.map +1 -0
  42. package/dist/xlsx-to-univer-OPMMBWEW.js +7 -0
  43. package/dist/xlsx-to-univer-OPMMBWEW.js.map +1 -0
  44. package/package.json +41 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0
4
+
5
+ W1-G2b. The Sheets model and io move in from matrx-frontend `features/workbooks`.
6
+
7
+ - New `./sheets` entry (pure, SSR-import-safe): the workbook service (`createWorkbook`, `getLatestSnapshot`, `saveSnapshot`, `listSnapshots`, `copyWorkbook`, ...), `univerSnapshotToRows`, `snapshotToGridSheets`, the snapshot miniature (`snapshotPreviewSvg`, `workbookPreviewSvg`, `documentPreviewSvg`, `formatCellValue`; moved from `features/templates/files/thumbnail`), sheet page setup (`sheet-page-setup`, its service) and print pages, the sheet output (CSV, print, PDF) and `registerWorkbookScopeSource` / `readWorkbookScopeSource`.
8
+ - New `./sheets/xlsx` entry (heavy; load on demand): `buildXlsxFromUniver`, `xlsxToUniverWorkbook`, the xlsx resource helpers, and the one file-import path `importWorkbookFile` / `unsupportedFileReason`.
9
+ - New host port `configureSheetsHost({ getSupabase, ensureOrgId, uploadOriginalFile })`. An unconfigured port throws naming itself.
10
+ - `./univer/collab` is now the collab session only (the Yjs import). `useWorkbookRealtime` moved to its own entry, `./univer/realtime`, so a static import of the hook never loads Yjs into the editor chunk (module graph of the hook: 67 modules -> 25; no `yjs` / `y-protocols`).
11
+ - `/core` adds `WorkbookSnapshotOrigin` and `DocumentSnapshotOrigin`.
12
+ - Depends on `@ai-matrx/{api,auth,alchemy,print,records}`; `@supabase/supabase-js` is a type-only peer.
13
+
14
+ ### Consumer action
15
+
16
+ Call `configureSheetsHost(...)` once at start-up. Replace `@/features/workbooks/{workbook-service,univer-snapshot-rows,snapshot-grid,sheet-*,workbook-scope-source}` imports with `@ai-matrx/office/sheets`, and `xlsx-shared`, `univer-to-xlsx`, `xlsx-to-univer`, `import-workbook-file` with `@ai-matrx/office/sheets/xlsx`. Import `useWorkbookRealtime` from `@ai-matrx/office/univer/realtime` (not `univer/collab`).
17
+
3
18
  ## 0.3.0
4
19
 
5
20
  W1-G2a2. The collab layer shared by Sheets and Docs moves in from matrx-frontend.
@@ -0,0 +1,529 @@
1
+ // src/sheets/xlsx-to-univer.ts
2
+ import { readWorkbook } from "@ai-matrx/alchemy/operate/read";
3
+ import { writeWorkbookBytes } from "@ai-matrx/alchemy/operate/formats/xlsx";
4
+
5
+ // src/sheets/xlsx-to-univer-excel.ts
6
+ import { loadExcelJs } from "@ai-matrx/print/xlsx-styled";
7
+
8
+ // src/sheets/xlsx-shared.ts
9
+ var RESOURCE = {
10
+ validation: "SHEET_DATA_VALIDATION_PLUGIN",
11
+ conditional: "SHEET_CONDITIONAL_FORMATTING_PLUGIN",
12
+ filter: "SHEET_FILTER_PLUGIN",
13
+ note: "SHEET_NOTE_PLUGIN",
14
+ comments: "SHEET_UNIVER_THREAD_COMMENT_PLUGIN",
15
+ drawing: "SHEET_DRAWING_PLUGIN",
16
+ table: "SHEET_TABLE_PLUGIN"
17
+ };
18
+ function readResource(resources, name) {
19
+ const raw = resources?.find((r) => r.name === name)?.data;
20
+ if (!raw) return void 0;
21
+ try {
22
+ return JSON.parse(raw);
23
+ } catch {
24
+ return void 0;
25
+ }
26
+ }
27
+ function writeResource(resources, name, value) {
28
+ const i = resources.findIndex((r) => r.name === name);
29
+ const entry = { name, data: JSON.stringify(value) };
30
+ if (i >= 0) resources[i] = entry;
31
+ else resources.push(entry);
32
+ }
33
+ var colPxToChars = (px) => Math.max(0, Math.round(px / 7 * 100) / 100);
34
+ var colCharsToPx = (chars) => Math.round(chars * 7);
35
+ var rowPxToPt = (px) => Math.round(px * 0.75 * 100) / 100;
36
+ var rowPtToPx = (pt) => Math.round(pt / 0.75 * 100) / 100;
37
+ function colorToArgb(input) {
38
+ if (!input) return void 0;
39
+ const s = input.trim();
40
+ const hex = /^#?([0-9a-f]{6})$/i.exec(s);
41
+ if (hex) return `FF${hex[1].toUpperCase()}`;
42
+ const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(s);
43
+ if (short) return `FF${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`.toUpperCase();
44
+ const rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(s);
45
+ if (rgb) {
46
+ const h = (n) => Number(n).toString(16).padStart(2, "0");
47
+ return `FF${h(rgb[1])}${h(rgb[2])}${h(rgb[3])}`.toUpperCase();
48
+ }
49
+ return void 0;
50
+ }
51
+ function argbToColor(argb) {
52
+ if (!argb) return void 0;
53
+ const v = argb.replace(/^#/, "");
54
+ if (v.length === 8) return `#${v.slice(2).toLowerCase()}`;
55
+ if (v.length === 6) return `#${v.toLowerCase()}`;
56
+ return void 0;
57
+ }
58
+ var BORDER_OUT = {
59
+ 1: "thin",
60
+ 2: "hair",
61
+ 3: "dotted",
62
+ 4: "dashed",
63
+ 5: "dashDot",
64
+ 6: "dashDotDot",
65
+ 7: "double",
66
+ 8: "medium",
67
+ 9: "mediumDashed",
68
+ 10: "mediumDashDot",
69
+ 11: "mediumDashDotDot",
70
+ 12: "slantDashDot",
71
+ 13: "thick"
72
+ };
73
+ var borderToExcel = (n) => n === void 0 ? void 0 : BORDER_OUT[n];
74
+ var borderFromExcel = (name) => {
75
+ if (!name) return void 0;
76
+ const hit = Object.entries(BORDER_OUT).find(([, v]) => v === name);
77
+ return hit ? Number(hit[0]) : void 0;
78
+ };
79
+ var H_ALIGN_OUT = { 1: "left", 2: "center", 3: "right", 4: "justify", 5: "justify", 6: "distributed" };
80
+ var V_ALIGN_OUT = { 1: "top", 2: "middle", 3: "bottom" };
81
+ var H_ALIGN_IN = { left: 1, center: 2, right: 3, justify: 4, fill: 1, centerContinuous: 2, distributed: 6 };
82
+ var V_ALIGN_IN = { top: 1, middle: 2, bottom: 3, distributed: 2, justify: 2 };
83
+ function a1(row, col) {
84
+ let n = col + 1;
85
+ let letters = "";
86
+ while (n > 0) {
87
+ const m = (n - 1) % 26;
88
+ letters = String.fromCharCode(65 + m) + letters;
89
+ n = Math.floor((n - 1) / 26);
90
+ }
91
+ return `${letters}${row + 1}`;
92
+ }
93
+ var rangeToA1 = (r) => r.startRow === r.endRow && r.startColumn === r.endColumn ? a1(r.startRow, r.startColumn) : `${a1(r.startRow, r.startColumn)}:${a1(r.endRow, r.endColumn)}`;
94
+ function parseA1Range(ref) {
95
+ const m = /^\$?([A-Z]+)\$?(\d+)(?::\$?([A-Z]+)\$?(\d+))?$/i.exec(ref.trim());
96
+ if (!m) return null;
97
+ const col = (s) => [...s.toUpperCase()].reduce((acc, ch) => acc * 26 + ch.charCodeAt(0) - 64, 0) - 1;
98
+ const sc = col(m[1]);
99
+ const sr = Number(m[2]) - 1;
100
+ return { startRow: sr, startColumn: sc, endRow: m[4] ? Number(m[4]) - 1 : sr, endColumn: m[3] ? col(m[3]) : sc };
101
+ }
102
+
103
+ // src/sheets/xlsx-to-univer-excel.ts
104
+ var THEME = ["FFFFFF", "000000", "E7E6E6", "44546A", "4472C4", "ED7D31", "A5A5A5", "FFC000", "5B9BD5", "70AD47"];
105
+ var colorOf = (c) => c?.argb ? argbToColor(c.argb) : typeof c?.theme === "number" && THEME[c.theme] ? `#${THEME[c.theme].toLowerCase()}` : void 0;
106
+ var rid = (prefix) => `${prefix}${Math.random().toString(36).slice(2, 10)}`;
107
+ var sheetId = (name) => `${name.replace(/[^A-Za-z0-9_-]+/g, "-").slice(0, 32) || "sheet"}-${Math.random().toString(36).slice(2, 8)}`;
108
+ async function importXlsxWithExcelJs(file, options = {}) {
109
+ const ExcelJS = await loadExcelJs();
110
+ const wb = new ExcelJS.Workbook();
111
+ await wb.xlsx.load(await file.arrayBuffer());
112
+ const dropped = /* @__PURE__ */ new Set();
113
+ const styles = {};
114
+ const styleIds = /* @__PURE__ */ new Map();
115
+ const styleId = (st) => {
116
+ const key = JSON.stringify(st);
117
+ let id = styleIds.get(key);
118
+ if (!id) {
119
+ id = `s${styleIds.size + 1}`;
120
+ styleIds.set(key, id);
121
+ styles[id] = st;
122
+ }
123
+ return id;
124
+ };
125
+ const sheets = {};
126
+ const sheetOrder = [];
127
+ const resources = [];
128
+ const validation = {};
129
+ const conditional = {};
130
+ const filters = {};
131
+ const notes = {};
132
+ const drawings = {};
133
+ const unitId = `wb-${rid("")}`;
134
+ for (const ws of wb.worksheets) {
135
+ const id = sheetId(ws.name);
136
+ sheetOrder.push(id);
137
+ const cellData = {};
138
+ let maxR = 0;
139
+ let maxC = 0;
140
+ const sheetNotes = {};
141
+ ws.eachRow({ includeEmpty: false }, (row, rowNumber) => {
142
+ row.eachCell({ includeEmpty: false }, (cell, colNumber) => {
143
+ const r = rowNumber - 1;
144
+ const c = colNumber - 1;
145
+ const out = toCell(cell, styleId);
146
+ if (out) {
147
+ (cellData[r] ??= {})[c] = out;
148
+ maxR = Math.max(maxR, r);
149
+ maxC = Math.max(maxC, c);
150
+ }
151
+ const note = cell.note;
152
+ const text = typeof note === "string" ? note : note?.texts?.map((t) => t.text).join("");
153
+ if (text) {
154
+ (sheetNotes[r] ??= {})[c] = { id: rid("n"), row: r, col: c, width: 160, height: 72, note: text, show: false };
155
+ }
156
+ });
157
+ });
158
+ if (Object.keys(sheetNotes).length) notes[id] = sheetNotes;
159
+ const sheet = {
160
+ id,
161
+ name: ws.name.slice(0, 31),
162
+ cellData,
163
+ rowCount: Math.max(maxR + 1, ws.rowCount, 100),
164
+ columnCount: Math.max(maxC + 1, ws.columnCount, 26)
165
+ };
166
+ const tab = colorOf(ws.properties?.tabColor);
167
+ if (tab) sheet.tabColor = tab;
168
+ const merges = ws.model.merges;
169
+ const mergeData = (merges ?? []).map((m) => parseA1Range(m)).filter((m) => !!m);
170
+ if (mergeData.length) {
171
+ sheet.mergeData = mergeData;
172
+ sheet.rowCount = Math.max(sheet.rowCount, ...mergeData.map((m) => m.endRow + 1));
173
+ sheet.columnCount = Math.max(sheet.columnCount, ...mergeData.map((m) => m.endColumn + 1));
174
+ }
175
+ const columnData = {};
176
+ for (let c = 1; c <= Math.min(ws.columnCount, 2e3); c++) {
177
+ const col = ws.getColumn(c);
178
+ if (typeof col.width === "number" || col.hidden) {
179
+ columnData[c - 1] = {
180
+ ...typeof col.width === "number" ? { w: colCharsToPx(col.width) } : {},
181
+ ...col.hidden ? { hd: 1 } : {}
182
+ };
183
+ }
184
+ }
185
+ if (Object.keys(columnData).length) sheet.columnData = columnData;
186
+ const rowData = {};
187
+ ws.eachRow({ includeEmpty: true }, (row, n) => {
188
+ if (typeof row.height === "number" || row.hidden) {
189
+ rowData[n - 1] = {
190
+ ...typeof row.height === "number" ? { h: rowPtToPx(row.height), hd: row.hidden ? 1 : 0 } : { hd: 1 }
191
+ };
192
+ }
193
+ });
194
+ if (Object.keys(rowData).length) sheet.rowData = rowData;
195
+ const view = ws.views?.[0];
196
+ if (view?.state === "frozen" && (view.xSplit || view.ySplit)) {
197
+ sheet.freeze = {
198
+ xSplit: view.xSplit ?? 0,
199
+ ySplit: view.ySplit ?? 0,
200
+ startColumn: view.xSplit ?? 0,
201
+ startRow: view.ySplit ?? 0
202
+ };
203
+ }
204
+ const dvModel = ws.dataValidations?.model;
205
+ const rules = dataValidationRules(dvModel ?? {});
206
+ if (rules.length) validation[id] = rules;
207
+ const cf = conditionalRules(ws.conditionalFormattings ?? [], dropped);
208
+ if (cf.length) conditional[id] = cf;
209
+ const af = ws.autoFilter;
210
+ if (af) {
211
+ const range = typeof af === "string" ? parseA1Range(af) : af.from && af.to ? {
212
+ startRow: af.from.row - 1,
213
+ startColumn: af.from.column - 1,
214
+ endRow: af.to.row - 1,
215
+ endColumn: af.to.column - 1
216
+ } : null;
217
+ if (range) filters[id] = { ref: range, filterColumns: [] };
218
+ }
219
+ const images = ws.getImages();
220
+ if (images.length) {
221
+ if (!options.uploadImage) {
222
+ dropped.add("Pictures in the file were not imported");
223
+ } else {
224
+ const data = {};
225
+ const order = [];
226
+ for (const img of images) {
227
+ try {
228
+ const media = wb.getImage(Number(img.imageId));
229
+ const bytes = new Uint8Array(media.buffer);
230
+ const fileId = await options.uploadImage(bytes, String(media.extension ?? "png"));
231
+ const tl = img.range.tl;
232
+ const ext = img.range.ext;
233
+ const br = img.range.br;
234
+ const width = ext?.width ?? ((br?.nativeCol ?? tl.nativeCol + 3) - tl.nativeCol) * 88;
235
+ const height = ext?.height ?? ((br?.nativeRow ?? tl.nativeRow + 6) - tl.nativeRow) * 24;
236
+ const drawingId = rid("img");
237
+ const column = Math.floor(tl.nativeCol ?? tl.col);
238
+ const rowIdx = Math.floor(tl.nativeRow ?? tl.row);
239
+ data[drawingId] = {
240
+ unitId,
241
+ subUnitId: id,
242
+ drawingId,
243
+ drawingType: 0,
244
+ imageSourceType: "URL",
245
+ source: `matrx-file:${fileId}`,
246
+ transform: { left: column * 88, top: rowIdx * 24, width, height, angle: 0 },
247
+ sheetTransform: {
248
+ from: { column, columnOffset: 0, row: rowIdx, rowOffset: 0 },
249
+ to: { column: column + Math.max(1, Math.round(width / 88)), columnOffset: 0, row: rowIdx + Math.max(1, Math.round(height / 24)), rowOffset: 0 }
250
+ }
251
+ };
252
+ order.push(drawingId);
253
+ } catch {
254
+ dropped.add("Some pictures could not be stored and were left out");
255
+ }
256
+ }
257
+ if (order.length) drawings[id] = { data, order };
258
+ }
259
+ }
260
+ if ((ws.getTables?.() ?? []).length) dropped.add("Excel tables became plain ranges (their data and styling are kept)");
261
+ sheets[id] = sheet;
262
+ }
263
+ if (Object.keys(validation).length) writeResource(resources, RESOURCE.validation, validation);
264
+ if (Object.keys(conditional).length) writeResource(resources, RESOURCE.conditional, conditional);
265
+ if (Object.keys(filters).length) writeResource(resources, RESOURCE.filter, filters);
266
+ if (Object.keys(notes).length) writeResource(resources, RESOURCE.note, notes);
267
+ if (Object.keys(drawings).length) writeResource(resources, RESOURCE.drawing, drawings);
268
+ for (const d of dropped) options.onDropped?.(d);
269
+ return {
270
+ id: unitId,
271
+ sheetOrder,
272
+ name: file.name.replace(/\.[^.]+$/, ""),
273
+ appVersion: "1",
274
+ locale: "enUS",
275
+ styles,
276
+ sheets,
277
+ resources
278
+ };
279
+ }
280
+ function toStyle(cell) {
281
+ const st = {};
282
+ const f = cell.font;
283
+ if (f) {
284
+ if (f.name) st.ff = f.name;
285
+ if (f.size) st.fs = f.size;
286
+ if (f.bold) st.bl = 1;
287
+ if (f.italic) st.it = 1;
288
+ if (f.underline) st.ul = { s: 1 };
289
+ if (f.strike) st.st = { s: 1 };
290
+ const cl = colorOf(f.color);
291
+ if (cl) st.cl = { rgb: cl };
292
+ }
293
+ const fill = cell.fill;
294
+ if (fill?.type === "pattern" && fill.pattern === "solid") {
295
+ const bg = colorOf(fill.fgColor);
296
+ if (bg) st.bg = { rgb: bg };
297
+ }
298
+ const al = cell.alignment;
299
+ if (al) {
300
+ if (al.horizontal && H_ALIGN_IN[al.horizontal]) st.ht = H_ALIGN_IN[al.horizontal];
301
+ if (al.vertical && V_ALIGN_IN[al.vertical]) st.vt = V_ALIGN_IN[al.vertical];
302
+ if (al.wrapText) st.tb = 3;
303
+ }
304
+ const bd = cell.border;
305
+ if (bd) {
306
+ const out = {};
307
+ for (const [side, key] of [["top", "t"], ["bottom", "b"], ["left", "l"], ["right", "r"]]) {
308
+ const s = borderFromExcel(bd[side]?.style);
309
+ if (s) out[key] = { s, cl: { rgb: colorOf(bd[side]?.color) ?? "#000000" } };
310
+ }
311
+ if (Object.keys(out).length) st.bd = out;
312
+ }
313
+ if (cell.numFmt && cell.numFmt !== "General") st.n = { pattern: cell.numFmt };
314
+ return Object.keys(st).length ? st : void 0;
315
+ }
316
+ var EXCEL_EPOCH_OFFSET_DAYS = 25569;
317
+ function toCell(cell, styleId) {
318
+ const out = {};
319
+ let st = toStyle(cell);
320
+ const v = cell.value;
321
+ const setNumber = (n) => {
322
+ out.v = n;
323
+ out.t = 2;
324
+ };
325
+ const apply = (value) => {
326
+ if (value instanceof Date) {
327
+ setNumber(value.getTime() / 864e5 + EXCEL_EPOCH_OFFSET_DAYS);
328
+ st = { ...st ?? {}, n: st?.n ?? { pattern: "yyyy-mm-dd" } };
329
+ } else if (typeof value === "number") setNumber(value);
330
+ else if (typeof value === "boolean") {
331
+ out.v = value ? 1 : 0;
332
+ out.t = 3;
333
+ } else if (typeof value === "string") {
334
+ out.v = value;
335
+ out.t = 1;
336
+ } else if (value && typeof value === "object" && "error" in value) {
337
+ out.v = String(value.error);
338
+ out.t = 1;
339
+ }
340
+ };
341
+ if (v && typeof v === "object" && !(v instanceof Date)) {
342
+ const o = v;
343
+ if ("formula" in o || "sharedFormula" in o) {
344
+ const f = o.formula ?? o.sharedFormula;
345
+ if (f) out.f = `=${String(f).replace(/^=/, "")}`;
346
+ apply(o.result);
347
+ } else if (Array.isArray(o.richText)) {
348
+ apply(o.richText.map((r) => r.text).join(""));
349
+ } else if ("hyperlink" in o) {
350
+ const text = String(typeof o.text === "object" ? (o.text?.richText ?? []).map((r) => r.text).join("") : o.text ?? o.hyperlink);
351
+ out.v = text;
352
+ out.t = 1;
353
+ out.p = linkDoc(text, String(o.hyperlink));
354
+ } else apply(o);
355
+ } else {
356
+ apply(v);
357
+ }
358
+ if (st) out.s = styleId(st);
359
+ return out.v === void 0 && out.f === void 0 && !out.s ? null : out;
360
+ }
361
+ function linkDoc(text, url) {
362
+ return {
363
+ id: "d",
364
+ documentStyle: {},
365
+ body: {
366
+ dataStream: `${text}\r
367
+ `,
368
+ textRuns: [],
369
+ paragraphs: [{ startIndex: text.length }],
370
+ customRanges: [
371
+ { startIndex: 0, endIndex: Math.max(0, text.length - 1), rangeId: rid("link"), rangeType: 0, properties: { url } }
372
+ ]
373
+ }
374
+ };
375
+ }
376
+ function dataValidationRules(model) {
377
+ const groups = /* @__PURE__ */ new Map();
378
+ for (const [ref, dv] of Object.entries(model)) {
379
+ const pos = parseA1Range(ref);
380
+ if (!pos) continue;
381
+ const type = String(dv.type);
382
+ const rule = {
383
+ allowBlank: dv.allowBlank !== false,
384
+ showErrorMessage: dv.showErrorMessage !== false,
385
+ ...dv.error ? { error: dv.error } : {},
386
+ ...dv.errorTitle ? { errorTitle: dv.errorTitle } : {},
387
+ ...dv.prompt ? { prompt: dv.prompt, showInputMessage: true } : {}
388
+ };
389
+ const f = dv.formulae ?? [];
390
+ if (type === "list") {
391
+ const raw = String(f[0] ?? "");
392
+ const literal = /^"(.*)"$/.exec(raw);
393
+ Object.assign(rule, { type: "list", formula1: literal ? literal[1] : raw, formula2: "", showDropDown: true });
394
+ } else if (["whole", "decimal", "date", "time", "textLength"].includes(type)) {
395
+ Object.assign(rule, { type, operator: dv.operator ?? "between", formula1: String(f[0] ?? ""), formula2: f[1] !== void 0 ? String(f[1]) : "" });
396
+ } else if (type === "custom") {
397
+ Object.assign(rule, { type: "custom", formula1: String(f[0] ?? "") });
398
+ } else continue;
399
+ const key = JSON.stringify(rule);
400
+ const g = groups.get(key) ?? { rule, cells: [] };
401
+ g.cells.push([pos.startRow, pos.startColumn]);
402
+ groups.set(key, g);
403
+ }
404
+ return [...groups.values()].map(({ rule, cells }) => ({ uid: rid("dv"), ...rule, ranges: compressCells(cells) }));
405
+ }
406
+ function compressCells(cells) {
407
+ const sorted = [...cells].sort((a, b) => a[1] - b[1] || a[0] - b[0]);
408
+ const out = [];
409
+ for (const [r, c] of sorted) {
410
+ const last = out[out.length - 1];
411
+ if (last && last.startColumn === c && last.endColumn === c && last.endRow === r - 1) last.endRow = r;
412
+ else out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
413
+ }
414
+ return out;
415
+ }
416
+ function dxfToStyle(style) {
417
+ const out = {};
418
+ const fg = colorOf(style?.font?.color);
419
+ if (fg) out.cl = { rgb: fg };
420
+ if (style?.font?.bold) out.bl = 1;
421
+ if (style?.font?.italic) out.it = 1;
422
+ const bg = colorOf(style?.fill?.bgColor) ?? colorOf(style?.fill?.fgColor);
423
+ if (bg) out.bg = { rgb: bg };
424
+ return out;
425
+ }
426
+ function conditionalRules(formats, dropped) {
427
+ const out = [];
428
+ for (const cf of formats) {
429
+ const ranges = String(cf.ref ?? "").split(/\s+/).map((r) => parseA1Range(r)).filter((r) => !!r);
430
+ if (!ranges.length) continue;
431
+ for (const rule of cf.rules ?? []) {
432
+ let mapped = null;
433
+ const style = dxfToStyle(rule.style);
434
+ if (rule.type === "cellIs") {
435
+ const nums = (rule.formulae ?? []).map(Number);
436
+ const between = rule.operator === "between" || rule.operator === "notBetween";
437
+ mapped = { type: "highlightCell", subType: "number", operator: rule.operator, value: between ? nums.slice(0, 2) : nums[0], style };
438
+ } else if (rule.type === "containsText") {
439
+ mapped = { type: "highlightCell", subType: "text", operator: "containsText", value: String(rule.text ?? ""), style };
440
+ } else if (rule.type === "expression") {
441
+ mapped = { type: "highlightCell", subType: "formula", value: `=${String((rule.formulae ?? [])[0] ?? "")}`, style };
442
+ } else if (rule.type === "colorScale") {
443
+ mapped = {
444
+ type: "colorScale",
445
+ config: (rule.cfvo ?? []).map((v, i) => ({
446
+ index: i,
447
+ color: colorOf(rule.color?.[i]) ?? "#ffffff",
448
+ value: { type: v.type, ...v.value !== void 0 ? { value: v.value } : {} }
449
+ }))
450
+ };
451
+ } else if (rule.type === "dataBar") {
452
+ const [min, max] = rule.cfvo ?? [];
453
+ mapped = {
454
+ type: "dataBar",
455
+ isShowValue: true,
456
+ config: {
457
+ min: { type: min?.type ?? "min" },
458
+ max: { type: max?.type ?? "max" },
459
+ isGradient: rule.gradient !== false,
460
+ positiveColor: colorOf(rule.color) ?? "#638ec6",
461
+ nativeColor: "#ff0000"
462
+ }
463
+ };
464
+ }
465
+ if (!mapped) {
466
+ dropped.add("Some conditional formats (icon sets, top/bottom, date rules) were not imported");
467
+ continue;
468
+ }
469
+ out.push({ cfId: rid("cf"), ranges, stopIfTrue: Boolean(rule.stopIfTrue), rule: mapped });
470
+ }
471
+ }
472
+ return out;
473
+ }
474
+
475
+ // src/sheets/xlsx-to-univer.ts
476
+ async function legacyToXlsxBytes(file) {
477
+ const wb = await readWorkbook(file, { dates: true, formulas: true });
478
+ const json = {
479
+ sheets: wb.sheets.map((ws) => {
480
+ const range = ws.range ?? { s: { r: 0, c: 0 }, e: { r: -1, c: -1 } };
481
+ const rows = [];
482
+ for (let r = 0; r <= range.e.r; r++) {
483
+ const row = [];
484
+ for (let c = 0; c <= range.e.c; c++) {
485
+ const cell = ws.cell(r, c);
486
+ if (!cell || cell.v === void 0 || cell.v === null) {
487
+ row.push(null);
488
+ continue;
489
+ }
490
+ const v = cell.v instanceof Date ? cell.v.toISOString().slice(0, 10) : cell.v;
491
+ if (cell.f) row.push({ v: typeof v === "boolean" || typeof v === "number" ? v : String(v), f: cell.f.replace(/^=/, "") });
492
+ else row.push(v);
493
+ }
494
+ rows.push(row);
495
+ }
496
+ return { name: ws.name.slice(0, 31) || "Sheet1", rows, merges: ws.merges };
497
+ })
498
+ };
499
+ const bytes = await writeWorkbookBytes(json);
500
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
501
+ }
502
+ async function xlsxToUniverWorkbook(file, options = {}) {
503
+ if (/\.xlsx$/i.test(file.name)) return importXlsxWithExcelJs(file, options);
504
+ const data = await legacyToXlsxBytes(file);
505
+ return importXlsxWithExcelJs({ name: file.name, arrayBuffer: async () => data }, options);
506
+ }
507
+
508
+ export {
509
+ RESOURCE,
510
+ readResource,
511
+ writeResource,
512
+ colPxToChars,
513
+ colCharsToPx,
514
+ rowPxToPt,
515
+ rowPtToPx,
516
+ colorToArgb,
517
+ argbToColor,
518
+ borderToExcel,
519
+ borderFromExcel,
520
+ H_ALIGN_OUT,
521
+ V_ALIGN_OUT,
522
+ H_ALIGN_IN,
523
+ V_ALIGN_IN,
524
+ a1,
525
+ rangeToA1,
526
+ parseA1Range,
527
+ xlsxToUniverWorkbook
528
+ };
529
+ //# sourceMappingURL=chunk-5T2M6LSI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sheets/xlsx-to-univer.ts","../src/sheets/xlsx-to-univer-excel.ts","../src/sheets/xlsx-shared.ts"],"sourcesContent":["/**\n * xlsxToUniverWorkbook — parse a spreadsheet file into a Univer IWorkbookData\n * suitable for `apiRef.createWorkbook(...)` and for persistence as the initial\n * snapshot of a new workbook.\n *\n * ONE reader: ExcelJS (`xlsx-to-univer-excel`) holds styles, number formats,\n * widths, heights, frozen panes, merges, validation, conditional formatting,\n * filter range, notes, links and pictures. A file that is not already an\n * .xlsx (.xls, .ods, .csv, .tsv) is first re-written as an .xlsx by the\n * Alchemy workbook door — values, formulas and merges — and read by that same\n * reader, so there is no second import path to drift.\n */\n\nimport { readWorkbook } from \"@ai-matrx/alchemy/operate/read\";\nimport { writeWorkbookBytes } from \"@ai-matrx/alchemy/operate/formats/xlsx\";\nimport type { WorkbookJson } from \"@ai-matrx/alchemy/operate/read\";\nimport type { IWorkbookData } from \"@univerjs/core\";\nimport { importXlsxWithExcelJs, type XlsxImportOptions } from \"./xlsx-to-univer-excel\";\n\n/** A legacy or text spreadsheet as .xlsx bytes (values, formulas, merges). */\nasync function legacyToXlsxBytes(file: File): Promise<ArrayBuffer> {\n const wb = await readWorkbook(file, { dates: true, formulas: true });\n const json: WorkbookJson = {\n sheets: wb.sheets.map((ws) => {\n const range = ws.range ?? { s: { r: 0, c: 0 }, e: { r: -1, c: -1 } };\n const rows: WorkbookJson[\"sheets\"][number][\"rows\"] = [];\n for (let r = 0; r <= range.e.r; r++) {\n const row: WorkbookJson[\"sheets\"][number][\"rows\"][number] = [];\n for (let c = 0; c <= range.e.c; c++) {\n const cell = ws.cell(r, c);\n if (!cell || cell.v === undefined || cell.v === null) {\n row.push(null);\n continue;\n }\n const v = cell.v instanceof Date ? cell.v.toISOString().slice(0, 10) : cell.v;\n if (cell.f) row.push({ v: typeof v === \"boolean\" || typeof v === \"number\" ? v : String(v), f: cell.f.replace(/^=/, \"\") });\n else row.push(v);\n }\n rows.push(row);\n }\n return { name: ws.name.slice(0, 31) || \"Sheet1\", rows, merges: ws.merges };\n }),\n };\n const bytes = await writeWorkbookBytes(json);\n return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;\n}\n\n/**\n * Parse a spreadsheet file into a Univer workbook. Whatever could not be\n * carried is reported through `options.onDropped` (the caller tells the person).\n */\nexport async function xlsxToUniverWorkbook(\n file: File,\n options: XlsxImportOptions = {},\n): Promise<Partial<IWorkbookData>> {\n if (/\\.xlsx$/i.test(file.name)) return importXlsxWithExcelJs(file, options);\n const data = await legacyToXlsxBytes(file);\n return importXlsxWithExcelJs({ name: file.name, arrayBuffer: async () => data }, options);\n}\n","/**\n * Full-fidelity .xlsx -> Univer reader (ExcelJS). The inverse of\n * `univer-to-xlsx.ts`: styles, number formats, column widths, row heights,\n * frozen panes, merges, data validation, conditional formatting, the filter\n * range, notes, cell links and pictures. Free of Univer runtime imports (enums\n * are numbers) so it runs under tests as well as in the browser.\n */\n\nimport type { IWorkbookData } from \"@univerjs/core\";\nimport { loadExcelJs, type ExcelJSTypes } from \"@ai-matrx/print/xlsx-styled\";\nimport {\n H_ALIGN_IN,\n RESOURCE,\n V_ALIGN_IN,\n argbToColor,\n borderFromExcel,\n colCharsToPx,\n parseA1Range,\n rowPtToPx,\n writeResource,\n type RangeLike,\n type UniverResource,\n} from \"./xlsx-shared\";\n\nexport type XlsxImportOptions = {\n /** Stores a picture and returns its file id; without it pictures are reported, not imported. */\n uploadImage?: (bytes: Uint8Array, extension: string) => Promise<string>;\n /** Called once per thing the file held that could not be carried. */\n onDropped?: (what: string) => void;\n};\n\ntype Json = Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any -- Univer resource payloads are untyped JSON\n\nconst THEME = [\"FFFFFF\", \"000000\", \"E7E6E6\", \"44546A\", \"4472C4\", \"ED7D31\", \"A5A5A5\", \"FFC000\", \"5B9BD5\", \"70AD47\"];\nconst colorOf = (c: Partial<ExcelJSTypes.Color> | undefined): string | undefined =>\n c?.argb ? argbToColor(c.argb) : typeof c?.theme === \"number\" && THEME[c.theme] ? `#${THEME[c.theme]!.toLowerCase()}` : undefined;\n\nconst rid = (prefix: string) => `${prefix}${Math.random().toString(36).slice(2, 10)}`;\nconst sheetId = (name: string) => `${name.replace(/[^A-Za-z0-9_-]+/g, \"-\").slice(0, 32) || \"sheet\"}-${Math.random().toString(36).slice(2, 8)}`;\n\nexport async function importXlsxWithExcelJs(\n file: { name: string; arrayBuffer(): Promise<ArrayBuffer> },\n options: XlsxImportOptions = {},\n): Promise<Partial<IWorkbookData>> {\n const ExcelJS = await loadExcelJs();\n const wb = new ExcelJS.Workbook();\n await wb.xlsx.load(await file.arrayBuffer());\n\n const dropped = new Set<string>();\n const styles: Record<string, Json> = {};\n const styleIds = new Map<string, string>();\n const styleId = (st: Json): string => {\n const key = JSON.stringify(st);\n let id = styleIds.get(key);\n if (!id) {\n id = `s${styleIds.size + 1}`;\n styleIds.set(key, id);\n styles[id] = st;\n }\n return id;\n };\n\n const sheets: Record<string, Json> = {};\n const sheetOrder: string[] = [];\n const resources: UniverResource[] = [];\n const validation: Json = {};\n const conditional: Json = {};\n const filters: Json = {};\n const notes: Json = {};\n const drawings: Json = {};\n const unitId = `wb-${rid(\"\")}`;\n\n for (const ws of wb.worksheets) {\n const id = sheetId(ws.name);\n sheetOrder.push(id);\n const cellData: Record<number, Record<number, Json>> = {};\n let maxR = 0;\n let maxC = 0;\n const sheetNotes: Json = {};\n\n ws.eachRow({ includeEmpty: false }, (row, rowNumber) => {\n row.eachCell({ includeEmpty: false }, (cell, colNumber) => {\n const r = rowNumber - 1;\n const c = colNumber - 1;\n const out = toCell(cell, styleId);\n if (out) {\n (cellData[r] ??= {})[c] = out;\n maxR = Math.max(maxR, r);\n maxC = Math.max(maxC, c);\n }\n const note = cell.note;\n const text = typeof note === \"string\" ? note : (note as Json | undefined)?.texts?.map((t: Json) => t.text).join(\"\");\n if (text) {\n ((sheetNotes[r] ??= {}) as Json)[c] = { id: rid(\"n\"), row: r, col: c, width: 160, height: 72, note: text, show: false };\n }\n });\n });\n if (Object.keys(sheetNotes).length) notes[id] = sheetNotes;\n\n const sheet: Json = {\n id,\n name: ws.name.slice(0, 31),\n cellData,\n rowCount: Math.max(maxR + 1, ws.rowCount, 100),\n columnCount: Math.max(maxC + 1, ws.columnCount, 26),\n };\n\n const tab = colorOf(ws.properties?.tabColor);\n if (tab) sheet.tabColor = tab;\n\n const merges = (ws.model as Json).merges as string[] | undefined;\n const mergeData = (merges ?? []).map((m) => parseA1Range(m)).filter((m): m is RangeLike => !!m);\n if (mergeData.length) {\n sheet.mergeData = mergeData;\n sheet.rowCount = Math.max(sheet.rowCount, ...mergeData.map((m) => m.endRow + 1));\n sheet.columnCount = Math.max(sheet.columnCount, ...mergeData.map((m) => m.endColumn + 1));\n }\n\n const columnData: Json = {};\n for (let c = 1; c <= Math.min(ws.columnCount, 2000); c++) {\n const col = ws.getColumn(c);\n if (typeof col.width === \"number\" || col.hidden) {\n columnData[c - 1] = {\n ...(typeof col.width === \"number\" ? { w: colCharsToPx(col.width) } : {}),\n ...(col.hidden ? { hd: 1 } : {}),\n };\n }\n }\n if (Object.keys(columnData).length) sheet.columnData = columnData;\n\n const rowData: Json = {};\n ws.eachRow({ includeEmpty: true }, (row, n) => {\n if (typeof row.height === \"number\" || row.hidden) {\n rowData[n - 1] = {\n ...(typeof row.height === \"number\" ? { h: rowPtToPx(row.height), hd: row.hidden ? 1 : 0 } : { hd: 1 }),\n };\n }\n });\n if (Object.keys(rowData).length) sheet.rowData = rowData;\n\n const view = ws.views?.[0] as Json | undefined;\n if (view?.state === \"frozen\" && (view.xSplit || view.ySplit)) {\n sheet.freeze = {\n xSplit: view.xSplit ?? 0,\n ySplit: view.ySplit ?? 0,\n startColumn: view.xSplit ?? 0,\n startRow: view.ySplit ?? 0,\n };\n }\n\n // ── data validation\n const dvModel = ((ws as Json).dataValidations as Json | undefined)?.model as Record<string, Json> | undefined;\n const rules = dataValidationRules(dvModel ?? {});\n if (rules.length) validation[id] = rules;\n\n // ── conditional formatting\n const cf = conditionalRules(((ws as Json).conditionalFormattings ?? []) as Json[], dropped);\n if (cf.length) conditional[id] = cf;\n\n // ── filter range\n const af = ws.autoFilter as ExcelJSTypes.AutoFilter | undefined;\n if (af) {\n const range =\n typeof af === \"string\"\n ? parseA1Range(af)\n : af.from && af.to\n ? {\n startRow: (af.from as Json).row - 1,\n startColumn: (af.from as Json).column - 1,\n endRow: (af.to as Json).row - 1,\n endColumn: (af.to as Json).column - 1,\n }\n : null;\n if (range) filters[id] = { ref: range, filterColumns: [] };\n }\n\n // ── pictures\n const images = ws.getImages();\n if (images.length) {\n if (!options.uploadImage) {\n dropped.add(\"Pictures in the file were not imported\");\n } else {\n const data: Record<string, Json> = {};\n const order: string[] = [];\n for (const img of images) {\n try {\n const media = wb.getImage(Number(img.imageId)) as Json;\n const bytes = new Uint8Array(media.buffer as ArrayBuffer);\n const fileId = await options.uploadImage(bytes, String(media.extension ?? \"png\"));\n const tl = img.range.tl as Json;\n const ext = (img.range as Json).ext as Json | undefined;\n const br = img.range.br as Json | undefined;\n const width = ext?.width ?? ((br?.nativeCol ?? tl.nativeCol + 3) - tl.nativeCol) * 88;\n const height = ext?.height ?? ((br?.nativeRow ?? tl.nativeRow + 6) - tl.nativeRow) * 24;\n const drawingId = rid(\"img\");\n const column = Math.floor(tl.nativeCol ?? tl.col);\n const rowIdx = Math.floor(tl.nativeRow ?? tl.row);\n data[drawingId] = {\n unitId,\n subUnitId: id,\n drawingId,\n drawingType: 0,\n imageSourceType: \"URL\",\n source: `matrx-file:${fileId}`,\n transform: { left: column * 88, top: rowIdx * 24, width, height, angle: 0 },\n sheetTransform: {\n from: { column, columnOffset: 0, row: rowIdx, rowOffset: 0 },\n to: { column: column + Math.max(1, Math.round(width / 88)), columnOffset: 0, row: rowIdx + Math.max(1, Math.round(height / 24)), rowOffset: 0 },\n },\n };\n order.push(drawingId);\n } catch {\n dropped.add(\"Some pictures could not be stored and were left out\");\n }\n }\n if (order.length) drawings[id] = { data, order };\n }\n }\n\n if ((ws.getTables?.() ?? []).length) dropped.add(\"Excel tables became plain ranges (their data and styling are kept)\");\n sheets[id] = sheet;\n }\n\n if (Object.keys(validation).length) writeResource(resources, RESOURCE.validation, validation);\n if (Object.keys(conditional).length) writeResource(resources, RESOURCE.conditional, conditional);\n if (Object.keys(filters).length) writeResource(resources, RESOURCE.filter, filters);\n if (Object.keys(notes).length) writeResource(resources, RESOURCE.note, notes);\n if (Object.keys(drawings).length) writeResource(resources, RESOURCE.drawing, drawings);\n\n for (const d of dropped) options.onDropped?.(d);\n\n return {\n id: unitId,\n sheetOrder,\n name: file.name.replace(/\\.[^.]+$/, \"\"),\n appVersion: \"1\",\n locale: \"enUS\" as IWorkbookData[\"locale\"],\n styles,\n sheets,\n resources,\n } as Partial<IWorkbookData>;\n}\n\nfunction toStyle(cell: ExcelJSTypes.Cell): Json | undefined {\n const st: Json = {};\n const f = cell.font;\n if (f) {\n if (f.name) st.ff = f.name;\n if (f.size) st.fs = f.size;\n if (f.bold) st.bl = 1;\n if (f.italic) st.it = 1;\n if (f.underline) st.ul = { s: 1 };\n if (f.strike) st.st = { s: 1 };\n const cl = colorOf(f.color);\n if (cl) st.cl = { rgb: cl };\n }\n const fill = cell.fill as Json | undefined;\n if (fill?.type === \"pattern\" && fill.pattern === \"solid\") {\n const bg = colorOf(fill.fgColor);\n if (bg) st.bg = { rgb: bg };\n }\n const al = cell.alignment;\n if (al) {\n if (al.horizontal && H_ALIGN_IN[al.horizontal]) st.ht = H_ALIGN_IN[al.horizontal];\n if (al.vertical && V_ALIGN_IN[al.vertical]) st.vt = V_ALIGN_IN[al.vertical];\n if (al.wrapText) st.tb = 3;\n }\n const bd = cell.border as Json | undefined;\n if (bd) {\n const out: Json = {};\n for (const [side, key] of [[\"top\", \"t\"], [\"bottom\", \"b\"], [\"left\", \"l\"], [\"right\", \"r\"]] as const) {\n const s = borderFromExcel(bd[side]?.style);\n if (s) out[key] = { s, cl: { rgb: colorOf(bd[side]?.color) ?? \"#000000\" } };\n }\n if (Object.keys(out).length) st.bd = out;\n }\n if (cell.numFmt && cell.numFmt !== \"General\") st.n = { pattern: cell.numFmt };\n return Object.keys(st).length ? st : undefined;\n}\n\nconst EXCEL_EPOCH_OFFSET_DAYS = 25569;\n\nfunction toCell(cell: ExcelJSTypes.Cell, styleId: (s: Json) => string): Json | null {\n const out: Json = {};\n let st = toStyle(cell);\n const v = cell.value as unknown;\n const setNumber = (n: number) => {\n out.v = n;\n out.t = 2;\n };\n const apply = (value: unknown) => {\n if (value instanceof Date) {\n setNumber(value.getTime() / 86_400_000 + EXCEL_EPOCH_OFFSET_DAYS);\n st = { ...(st ?? {}), n: (st?.n as Json | undefined) ?? { pattern: \"yyyy-mm-dd\" } };\n } else if (typeof value === \"number\") setNumber(value);\n else if (typeof value === \"boolean\") {\n out.v = value ? 1 : 0;\n out.t = 3;\n } else if (typeof value === \"string\") {\n out.v = value;\n out.t = 1;\n } else if (value && typeof value === \"object\" && \"error\" in (value as Json)) {\n out.v = String((value as Json).error);\n out.t = 1;\n }\n };\n if (v && typeof v === \"object\" && !(v instanceof Date)) {\n const o = v as Json;\n if (\"formula\" in o || \"sharedFormula\" in o) {\n const f = o.formula ?? o.sharedFormula;\n if (f) out.f = `=${String(f).replace(/^=/, \"\")}`;\n apply(o.result);\n } else if (Array.isArray(o.richText)) {\n apply(o.richText.map((r: Json) => r.text).join(\"\"));\n } else if (\"hyperlink\" in o) {\n const text = String(typeof o.text === \"object\" ? (o.text?.richText ?? []).map((r: Json) => r.text).join(\"\") : (o.text ?? o.hyperlink));\n out.v = text;\n out.t = 1;\n out.p = linkDoc(text, String(o.hyperlink));\n } else apply(o);\n } else {\n apply(v);\n }\n if (st) out.s = styleId(st);\n return out.v === undefined && out.f === undefined && !out.s ? null : out;\n}\n\nfunction linkDoc(text: string, url: string): Json {\n return {\n id: \"d\",\n documentStyle: {},\n body: {\n dataStream: `${text}\\r\\n`,\n textRuns: [],\n paragraphs: [{ startIndex: text.length }],\n customRanges: [\n { startIndex: 0, endIndex: Math.max(0, text.length - 1), rangeId: rid(\"link\"), rangeType: 0, properties: { url } },\n ],\n },\n };\n}\n\nfunction dataValidationRules(model: Record<string, Json>): Json[] {\n const groups = new Map<string, { rule: Json; cells: [number, number][] }>();\n for (const [ref, dv] of Object.entries(model)) {\n const pos = parseA1Range(ref);\n if (!pos) continue;\n const type = String(dv.type);\n const rule: Json = {\n allowBlank: dv.allowBlank !== false,\n showErrorMessage: dv.showErrorMessage !== false,\n ...(dv.error ? { error: dv.error } : {}),\n ...(dv.errorTitle ? { errorTitle: dv.errorTitle } : {}),\n ...(dv.prompt ? { prompt: dv.prompt, showInputMessage: true } : {}),\n };\n const f = (dv.formulae ?? []) as unknown[];\n if (type === \"list\") {\n const raw = String(f[0] ?? \"\");\n const literal = /^\"(.*)\"$/.exec(raw);\n Object.assign(rule, { type: \"list\", formula1: literal ? literal[1] : raw, formula2: \"\", showDropDown: true });\n } else if ([\"whole\", \"decimal\", \"date\", \"time\", \"textLength\"].includes(type)) {\n Object.assign(rule, { type, operator: dv.operator ?? \"between\", formula1: String(f[0] ?? \"\"), formula2: f[1] !== undefined ? String(f[1]) : \"\" });\n } else if (type === \"custom\") {\n Object.assign(rule, { type: \"custom\", formula1: String(f[0] ?? \"\") });\n } else continue;\n const key = JSON.stringify(rule);\n const g = groups.get(key) ?? { rule, cells: [] };\n g.cells.push([pos.startRow, pos.startColumn]);\n groups.set(key, g);\n }\n return [...groups.values()].map(({ rule, cells }) => ({ uid: rid(\"dv\"), ...rule, ranges: compressCells(cells) }));\n}\n\n/** Single cells -> the fewest vertical runs. */\nfunction compressCells(cells: [number, number][]): RangeLike[] {\n const sorted = [...cells].sort((a, b) => a[1] - b[1] || a[0] - b[0]);\n const out: RangeLike[] = [];\n for (const [r, c] of sorted) {\n const last = out[out.length - 1];\n if (last && last.startColumn === c && last.endColumn === c && last.endRow === r - 1) last.endRow = r;\n else out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });\n }\n return out;\n}\n\nfunction dxfToStyle(style: Json | undefined): Json {\n const out: Json = {};\n const fg = colorOf(style?.font?.color);\n if (fg) out.cl = { rgb: fg };\n if (style?.font?.bold) out.bl = 1;\n if (style?.font?.italic) out.it = 1;\n const bg = colorOf(style?.fill?.bgColor) ?? colorOf(style?.fill?.fgColor);\n if (bg) out.bg = { rgb: bg };\n return out;\n}\n\nfunction conditionalRules(formats: Json[], dropped: Set<string>): Json[] {\n const out: Json[] = [];\n for (const cf of formats) {\n const ranges = String(cf.ref ?? \"\").split(/\\s+/).map((r) => parseA1Range(r)).filter((r): r is RangeLike => !!r);\n if (!ranges.length) continue;\n for (const rule of (cf.rules ?? []) as Json[]) {\n let mapped: Json | null = null;\n const style = dxfToStyle(rule.style);\n if (rule.type === \"cellIs\") {\n const nums = ((rule.formulae ?? []) as unknown[]).map(Number);\n const between = rule.operator === \"between\" || rule.operator === \"notBetween\";\n mapped = { type: \"highlightCell\", subType: \"number\", operator: rule.operator, value: between ? nums.slice(0, 2) : nums[0], style };\n } else if (rule.type === \"containsText\") {\n mapped = { type: \"highlightCell\", subType: \"text\", operator: \"containsText\", value: String(rule.text ?? \"\"), style };\n } else if (rule.type === \"expression\") {\n mapped = { type: \"highlightCell\", subType: \"formula\", value: `=${String((rule.formulae ?? [])[0] ?? \"\")}`, style };\n } else if (rule.type === \"colorScale\") {\n mapped = {\n type: \"colorScale\",\n config: ((rule.cfvo ?? []) as Json[]).map((v, i) => ({\n index: i,\n color: colorOf(rule.color?.[i]) ?? \"#ffffff\",\n value: { type: v.type, ...(v.value !== undefined ? { value: v.value } : {}) },\n })),\n };\n } else if (rule.type === \"dataBar\") {\n const [min, max] = (rule.cfvo ?? []) as Json[];\n mapped = {\n type: \"dataBar\",\n isShowValue: true,\n config: {\n min: { type: min?.type ?? \"min\" },\n max: { type: max?.type ?? \"max\" },\n isGradient: rule.gradient !== false,\n positiveColor: colorOf(rule.color) ?? \"#638ec6\",\n nativeColor: \"#ff0000\",\n },\n };\n }\n if (!mapped) {\n dropped.add(\"Some conditional formats (icon sets, top/bottom, date rules) were not imported\");\n continue;\n }\n out.push({ cfId: rid(\"cf\"), ranges, stopIfTrue: Boolean(rule.stopIfTrue), rule: mapped });\n }\n }\n return out;\n}\n","/**\n * Shared vocabulary between the xlsx importer and exporter: how Univer's\n * style numbers, colours and units map to the xlsx file's.\n *\n * Univer enums are written as numbers here so these helpers stay free of any\n * Univer import (they run in tests and in both directions).\n */\n\nexport const RESOURCE = {\n validation: \"SHEET_DATA_VALIDATION_PLUGIN\",\n conditional: \"SHEET_CONDITIONAL_FORMATTING_PLUGIN\",\n filter: \"SHEET_FILTER_PLUGIN\",\n note: \"SHEET_NOTE_PLUGIN\",\n comments: \"SHEET_UNIVER_THREAD_COMMENT_PLUGIN\",\n drawing: \"SHEET_DRAWING_PLUGIN\",\n table: \"SHEET_TABLE_PLUGIN\",\n} as const;\n\nexport type UniverResource = { name: string; data: string };\n\nexport function readResource<T = unknown>(\n resources: readonly UniverResource[] | undefined,\n name: string,\n): T | undefined {\n const raw = resources?.find((r) => r.name === name)?.data;\n if (!raw) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n}\n\nexport function writeResource(resources: UniverResource[], name: string, value: unknown): void {\n const i = resources.findIndex((r) => r.name === name);\n const entry = { name, data: JSON.stringify(value) };\n if (i >= 0) resources[i] = entry;\n else resources.push(entry);\n}\n\n/** Excel column width (characters) <-> Univer pixels. */\nexport const colPxToChars = (px: number): number => Math.max(0, Math.round((px / 7) * 100) / 100);\nexport const colCharsToPx = (chars: number): number => Math.round(chars * 7);\n/** Excel row height (points) <-> Univer pixels. */\nexport const rowPxToPt = (px: number): number => Math.round(px * 0.75 * 100) / 100;\nexport const rowPtToPx = (pt: number): number => Math.round((pt / 0.75) * 100) / 100;\n\n/** Univer colour (\"#rrggbb\", \"rgb(r,g,b)\", \"rgba(...)\") -> ARGB hex, or undefined. */\nexport function colorToArgb(input: string | undefined | null): string | undefined {\n if (!input) return undefined;\n const s = input.trim();\n const hex = /^#?([0-9a-f]{6})$/i.exec(s);\n if (hex) return `FF${hex[1]!.toUpperCase()}`;\n const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(s);\n if (short) return `FF${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`.toUpperCase();\n const rgb = /^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/i.exec(s);\n if (rgb) {\n const h = (n: string) => Number(n).toString(16).padStart(2, \"0\");\n return `FF${h(rgb[1]!)}${h(rgb[2]!)}${h(rgb[3]!)}`.toUpperCase();\n }\n return undefined;\n}\n\n/** ARGB (or RGB) hex from a file -> Univer \"#rrggbb\". */\nexport function argbToColor(argb: string | undefined | null): string | undefined {\n if (!argb) return undefined;\n const v = argb.replace(/^#/, \"\");\n if (v.length === 8) return `#${v.slice(2).toLowerCase()}`;\n if (v.length === 6) return `#${v.toLowerCase()}`;\n return undefined;\n}\n\n// Univer BorderStyleTypes number <-> ExcelJS border style name.\nconst BORDER_OUT: Record<number, string> = {\n 1: \"thin\", 2: \"hair\", 3: \"dotted\", 4: \"dashed\", 5: \"dashDot\", 6: \"dashDotDot\", 7: \"double\",\n 8: \"medium\", 9: \"mediumDashed\", 10: \"mediumDashDot\", 11: \"mediumDashDotDot\", 12: \"slantDashDot\", 13: \"thick\",\n};\nexport const borderToExcel = (n: number | undefined): string | undefined =>\n n === undefined ? undefined : BORDER_OUT[n];\nexport const borderFromExcel = (name: string | undefined): number | undefined => {\n if (!name) return undefined;\n const hit = Object.entries(BORDER_OUT).find(([, v]) => v === name);\n return hit ? Number(hit[0]) : undefined;\n};\n\nexport const H_ALIGN_OUT: Record<number, string> = { 1: \"left\", 2: \"center\", 3: \"right\", 4: \"justify\", 5: \"justify\", 6: \"distributed\" };\nexport const V_ALIGN_OUT: Record<number, string> = { 1: \"top\", 2: \"middle\", 3: \"bottom\" };\nexport const H_ALIGN_IN: Record<string, number> = { left: 1, center: 2, right: 3, justify: 4, fill: 1, centerContinuous: 2, distributed: 6 };\nexport const V_ALIGN_IN: Record<string, number> = { top: 1, middle: 2, bottom: 3, distributed: 2, justify: 2 };\n\n/** 0-based (row, col) -> \"A1\" (no $). */\nexport function a1(row: number, col: number): string {\n let n = col + 1;\n let letters = \"\";\n while (n > 0) {\n const m = (n - 1) % 26;\n letters = String.fromCharCode(65 + m) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return `${letters}${row + 1}`;\n}\n\nexport type RangeLike = { startRow: number; endRow: number; startColumn: number; endColumn: number };\nexport const rangeToA1 = (r: RangeLike): string =>\n r.startRow === r.endRow && r.startColumn === r.endColumn\n ? a1(r.startRow, r.startColumn)\n : `${a1(r.startRow, r.startColumn)}:${a1(r.endRow, r.endColumn)}`;\n\n/** \"A1\" or \"A1:C5\" -> range (0-based), or null. */\nexport function parseA1Range(ref: string): RangeLike | null {\n const m = /^\\$?([A-Z]+)\\$?(\\d+)(?::\\$?([A-Z]+)\\$?(\\d+))?$/i.exec(ref.trim());\n if (!m) return null;\n const col = (s: string) => [...s.toUpperCase()].reduce((acc, ch) => acc * 26 + ch.charCodeAt(0) - 64, 0) - 1;\n const sc = col(m[1]!);\n const sr = Number(m[2]!) - 1;\n return { startRow: sr, startColumn: sc, endRow: m[4] ? Number(m[4]) - 1 : sr, endColumn: m[3] ? col(m[3]) : sc };\n}\n"],"mappings":"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","names":[]}