@ai-matrx/office 0.8.13 → 0.8.15

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.
@@ -37,30 +37,44 @@ __export(collab_exports, {
37
37
  DOC_LOCAL_KEYS: () => DOC_LOCAL_KEYS,
38
38
  RICH_TEXT_EDITING: () => RICH_TEXT_EDITING,
39
39
  SENDER_VIEW_PARAMS: () => SENDER_VIEW_PARAMS,
40
+ SHEETS_COLLAB_PROTO: () => SHEETS_COLLAB_PROTO,
41
+ SHEETS_EDIT_GROUP: () => SHEETS_EDIT_GROUP,
40
42
  WorkbookCollabSession: () => WorkbookCollabSession,
41
43
  applyDocsOp: () => applyDocsOp,
42
44
  canonicalDocsSnapshot: () => canonicalDocsSnapshot,
43
45
  canonicalDocsString: () => canonicalDocsString,
44
46
  canonicalKeys: () => canonicalKeys,
47
+ canonicalSheet: () => canonicalSheet,
48
+ canonicalSheetString: () => canonicalSheetString,
45
49
  composeDocsOps: () => composeDocsOps,
50
+ createSheetsOtAdapter: () => createSheetsOtAdapter,
51
+ decodeSheetOp: () => decodeSheetOp,
46
52
  docsStateHash: () => docsStateHash,
47
53
  documentOtFactory: () => documentOtFactory,
48
54
  documentUsesOrderedRoom: () => documentUsesOrderedRoom,
49
55
  dropEmptyStyleRetains: () => dropEmptyStyleRetains,
56
+ encodeSheetOp: () => encodeSheetOp,
50
57
  invertDocsOp: () => invertDocsOp,
51
58
  isCellEditorScratch: () => isCellEditorScratch,
52
59
  isNoopDocsOp: () => isNoopDocsOp,
53
60
  normalizeDocsOp: () => normalizeDocsOp,
54
61
  openDocsOtRoom: () => openDocsOtRoom,
62
+ openSheetsOtRoom: () => openSheetsOtRoom,
63
+ rebaseSheetUndoStack: () => rebaseSheetUndoStack,
55
64
  rebaseUndoStack: () => rebaseUndoStack,
56
65
  restoreDocumentSnapshot: () => restoreDocumentSnapshot,
66
+ sheetsStateHash: () => sheetsStateHash,
57
67
  stampCovered: () => stampCovered,
58
68
  stampDeterministicIds: () => stampDeterministicIds,
69
+ startWorkbookOtRoom: () => startWorkbookOtRoom,
59
70
  stripSenderView: () => stripSenderView,
60
71
  takeCovered: () => takeCovered,
61
72
  transformDocsOp: () => transformDocsOp,
73
+ transformSheetOp: () => transformSheetOp,
62
74
  transformTextX: () => transformTextX,
63
- undoStacksOf: () => undoStacksOf
75
+ undoStacksOf: () => undoStacksOf,
76
+ univerSheetsOtPort: () => univerSheetsOtPort,
77
+ workbookUsesOrderedRoom: () => workbookUsesOrderedRoom
64
78
  });
65
79
  module.exports = __toCommonJS(collab_exports);
66
80
 
@@ -71,8 +85,8 @@ var import_collab = require("@ai-matrx/data/realtime/collab");
71
85
 
72
86
  // src/univer/collab/covered.ts
73
87
  var COLLAB_COVERED_KEY = "__matrxCollabCovered";
74
- function stampCovered(snapshot, covered) {
75
- return { ...snapshot, [COLLAB_COVERED_KEY]: [...covered] };
88
+ function stampCovered(snapshot, covered2) {
89
+ return { ...snapshot, [COLLAB_COVERED_KEY]: [...covered2] };
76
90
  }
77
91
  function takeCovered(snapshot) {
78
92
  if (!snapshot || typeof snapshot !== "object" || !(COLLAB_COVERED_KEY in snapshot)) {
@@ -212,10 +226,10 @@ var WorkbookCollabSession = class {
212
226
  */
213
227
  coveredNow() {
214
228
  if (!this.doc) return [];
215
- const covered = this.options.base?.covered();
229
+ const covered2 = this.options.base?.covered();
216
230
  const out = [];
217
231
  for (const op of this.doc.getArray(MUTATIONS_ARRAY_KEY).toArray()) {
218
- if (op.eid && (this.applied.has(op.eid) || covered?.has(op.eid))) out.push(op.eid);
232
+ if (op.eid && (this.applied.has(op.eid) || covered2?.has(op.eid))) out.push(op.eid);
219
233
  }
220
234
  return out;
221
235
  }
@@ -225,11 +239,11 @@ var WorkbookCollabSession = class {
225
239
  * by position — an entry that arrived while the save was in flight is not in the snapshot and stays.
226
240
  * Only the elected saver calls this; peers receive it as a delete (never replayed).
227
241
  */
228
- checkpoint(snapshotId, covered) {
242
+ checkpoint(snapshotId, covered2) {
229
243
  if (!this.doc) return;
230
244
  const yArray = this.doc.getArray(MUTATIONS_ARRAY_KEY);
231
245
  const control = this.doc.getMap(CONTROL_MAP_KEY);
232
- const drop = new Set(covered);
246
+ const drop = new Set(covered2);
233
247
  const signal = { snapshotId, by: this.options.clientId };
234
248
  this.doc.transact(() => {
235
249
  const entries = yArray.toArray();
@@ -353,10 +367,10 @@ var WorkbookCollabSession = class {
353
367
  return;
354
368
  }
355
369
  }
356
- const covered = base?.covered();
370
+ const covered2 = base?.covered();
357
371
  for (const op of entries) {
358
372
  if (op.eid) {
359
- if (this.applied.has(op.eid) || covered?.has(op.eid)) continue;
373
+ if (this.applied.has(op.eid) || covered2?.has(op.eid)) continue;
360
374
  this.applied.add(op.eid);
361
375
  } else {
362
376
  if (this.appliedRefs.has(op)) continue;
@@ -495,13 +509,13 @@ function dropEmptyStyleRetains(op) {
495
509
  e: v.e.map((a) => {
496
510
  const b = a.body;
497
511
  if (a.t !== "r" || !b || a.coverType === 1) return a;
498
- const runs = (b.textRuns ?? []).filter((r) => r.ts && Object.keys(r.ts).length);
512
+ const runs2 = (b.textRuns ?? []).filter((r) => r.ts && Object.keys(r.ts).length);
499
513
  const other = Object.keys(b).filter(
500
514
  (k) => k !== "textRuns" && k !== "dataStream" && !(Array.isArray(b[k]) && b[k].length === 0)
501
515
  );
502
- if (!runs.length && !other.length && !b.dataStream && !a.rangeUpdates?.length) return { t: "r", len: a.len };
503
- if (b.textRuns === void 0 || runs.length === b.textRuns.length) return a;
504
- return { ...a, body: { ...b, textRuns: runs } };
516
+ if (!runs2.length && !other.length && !b.dataStream && !a.rangeUpdates?.length) return { t: "r", len: a.len };
517
+ if (b.textRuns === void 0 || runs2.length === b.textRuns.length) return a;
518
+ return { ...a, body: { ...b, textRuns: runs2 } };
505
519
  })
506
520
  };
507
521
  }
@@ -825,23 +839,23 @@ function transformTextX(xIn, yIn, side, lost = []) {
825
839
  const yIds = valueIds(y);
826
840
  const conflicts = new Set([...valueIds(x)].filter((id) => yIds.has(id)));
827
841
  const X = new It(conflicts.size && !xLeft ? withoutValueRangeMetadata(x, conflicts) : x);
828
- const Y3 = new It(conflicts.size && xLeft ? withoutValueRangeMetadata(y, conflicts) : y);
842
+ const Y4 = new It(conflicts.size && xLeft ? withoutValueRangeMetadata(y, conflicts) : y);
829
843
  const decos = addedDecorations(y).map((d) => ({ ...d, pieces: [] }));
830
844
  const out = [];
831
845
  let inPos = 0;
832
846
  let outPos = 0;
833
- while (X.hasNext() || Y3.hasNext()) {
834
- if (X.peekType() === "i" && (xLeft || Y3.peekType() !== "i")) {
847
+ while (X.hasNext() || Y4.hasNext()) {
848
+ if (X.peekType() === "i" && (xLeft || Y4.peekType() !== "i")) {
835
849
  const a = X.next();
836
- if (Y3.inZone()) {
850
+ if (Y4.inZone()) {
837
851
  lost.push({ rule: "R1", side: "insert", len: a.len, ...a.body?.dataStream !== void 0 ? { text: a.body.dataStream } : {} });
838
852
  continue;
839
853
  }
840
854
  if (a.valueRangeId && conflicts.has(a.valueRangeId) && !xLeft) continue;
841
855
  push(out, a);
842
856
  outPos += a.len;
843
- } else if (Y3.peekType() === "i") {
844
- const b = Y3.next();
857
+ } else if (Y4.peekType() === "i") {
858
+ const b = Y4.next();
845
859
  if (X.inZone()) {
846
860
  push(out, { t: "d", len: b.len, tz: [[0, b.len - 1]] });
847
861
  lost.push({ rule: "R1", side: "delete", len: b.len, ...b.body?.dataStream !== void 0 ? { text: b.body.dataStream } : {} });
@@ -855,9 +869,9 @@ function transformTextX(xIn, yIn, side, lost = []) {
855
869
  }
856
870
  inPos += b.len;
857
871
  } else {
858
- const len = Math.min(X.peekLength(), Y3.peekLength());
872
+ const len = Math.min(X.peekLength(), Y4.peekLength());
859
873
  const a = X.next(len);
860
- const b = Y3.next(len);
874
+ const b = Y4.next(len);
861
875
  if (b.t === "d") continue;
862
876
  if (a.t === "d") {
863
877
  push(out, a);
@@ -952,9 +966,9 @@ function sortDeep(v) {
952
966
  return v;
953
967
  }
954
968
  var sameTs = (a, b) => JSON.stringify(sortDeep(a ?? {})) === JSON.stringify(sortDeep(b ?? {}));
955
- function canonicalRuns(runs) {
969
+ function canonicalRuns(runs2) {
956
970
  const out = [];
957
- for (const r of [...runs ?? []].sort((x, y) => x.st - y.st)) {
971
+ for (const r of [...runs2 ?? []].sort((x, y) => x.st - y.st)) {
958
972
  if (r.ed <= r.st) continue;
959
973
  const ts = sortDeep(r.ts ?? {});
960
974
  if (Object.keys(ts).length === 0) continue;
@@ -1066,25 +1080,25 @@ function rebaseUndoStack(items, remote) {
1066
1080
  let dropped = 0;
1067
1081
  for (let i = items.length - 1; i >= 0; i--) {
1068
1082
  const item = items[i];
1069
- let ok = true;
1083
+ let ok2 = true;
1070
1084
  for (const list of [item.undoMutations, item.redoMutations]) {
1071
1085
  for (const m of list ?? []) {
1072
1086
  if (m.id !== RICH_TEXT_EDITING) continue;
1073
1087
  try {
1074
1088
  if (touchesPageSetup(m.params.actions) && touchesPageSetup(remote)) throw new Error("page setup");
1075
1089
  const r = transformDocsOp(m.params.actions, remote, "left");
1076
- if (isNoopDocsOp(r.op)) ok = false;
1090
+ if (isNoopDocsOp(r.op)) ok2 = false;
1077
1091
  else {
1078
1092
  m.params = { ...m.params, actions: r.op };
1079
1093
  delete m.params.textRanges;
1080
1094
  delete m.params.layoutState;
1081
1095
  }
1082
1096
  } catch {
1083
- ok = false;
1097
+ ok2 = false;
1084
1098
  }
1085
1099
  }
1086
1100
  }
1087
- if (!ok) {
1101
+ if (!ok2) {
1088
1102
  items.splice(i, 1);
1089
1103
  dropped++;
1090
1104
  }
@@ -1608,4 +1622,1885 @@ async function restoreDocumentSnapshot(args, deps = {}) {
1608
1622
  const row = await d.saveRow(args);
1609
1623
  return { via: "saved", snapshotId: row.id };
1610
1624
  }
1625
+
1626
+ // src/univer/collab/sheets-ot/room.ts
1627
+ var import_collab5 = require("@ai-matrx/data/realtime/collab");
1628
+
1629
+ // src/collab/sheets/transform/types.ts
1630
+ var isBarrier = (r) => r.barrier === true;
1631
+
1632
+ // src/collab/sheets/transform/registry.ts
1633
+ var covered = (family, ...allow) => ({ kind: "covered", family, allow: ["subUnitId", ...allow] });
1634
+ var never = (reason) => ({ kind: "never-travels", reason });
1635
+ var barrier = (until, reason) => ({ kind: "barrier", until, reason });
1636
+ var FORMULA_RESULT = "formula engine output; every seat computes it (dropped at capture)";
1637
+ var RESOURCE = "ranged resource keyed by id; C5c";
1638
+ var UNIVER_COMMENTS = "Univer's own thread-comment store; our comments anchor elsewhere (design \xA78)";
1639
+ var SHEET_MUTATIONS = {
1640
+ // ── covered (C5a) ────────────────────────────────────────────────────────────────────────────────
1641
+ "sheet.mutation.set-range-values": covered("cell", "cellValue", "refSheets", "derived"),
1642
+ "sheet.mutation.insert-row": covered("structure", "range", "rowInfo"),
1643
+ "sheet.mutation.remove-rows": covered("structure", "range"),
1644
+ "sheet.mutation.insert-col": covered("structure", "range", "colInfo"),
1645
+ "sheet.mutation.remove-col": covered("structure", "range"),
1646
+ "sheet.mutation.move-rows": covered("structure", "sourceRange", "targetRange"),
1647
+ "sheet.mutation.move-columns": covered("structure", "sourceRange", "targetRange"),
1648
+ "sheet.mutation.add-worksheet-merge": covered("merge", "ranges"),
1649
+ "sheet.mutation.remove-worksheet-merge": covered("merge", "ranges"),
1650
+ "sheet.mutation.set-worksheet-row-height": covered("size", "ranges", "rowHeight"),
1651
+ "sheet.mutation.set-worksheet-row-is-auto-height": covered("size", "ranges", "autoHeightInfo"),
1652
+ "sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
1653
+ "sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
1654
+ "sheet.mutation.set-worksheet-name": covered("name", "name"),
1655
+ // ── never travels ────────────────────────────────────────────────────────────────────────────────
1656
+ "formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
1657
+ "formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
1658
+ "formula.mutation.set-formula-calculation-stop": never(FORMULA_RESULT),
1659
+ "formula.mutation.set-formula-calculation-notification": never(FORMULA_RESULT),
1660
+ "formula.mutation.set-formula-calculation-result": never(FORMULA_RESULT),
1661
+ "formula.mutation.set-array-formula-data": never(FORMULA_RESULT),
1662
+ "formula.mutation.set-formula-data": never(FORMULA_RESULT),
1663
+ "formula.mutation.set-image-formula-data": never(FORMULA_RESULT),
1664
+ "formula.mutation.set-formula-string-batch-calculation": never(FORMULA_RESULT),
1665
+ "formula.mutation.set-formula-string-batch-calculation-result": never(FORMULA_RESULT),
1666
+ "formula.mutation.set-formula-dependency-calculation": never(FORMULA_RESULT),
1667
+ "formula.mutation.set-formula-dependency-calculation-result": never(FORMULA_RESULT),
1668
+ "formula.mutation.set-cell-formula-dependency-calculation": never(FORMULA_RESULT),
1669
+ "formula.mutation.set-cell-formula-dependency-calculation-result": never(FORMULA_RESULT),
1670
+ "formula.mutation.set-query-formula-dependency": never(FORMULA_RESULT),
1671
+ "formula.mutation.set-query-formula-dependency-result": never(FORMULA_RESULT),
1672
+ "formula.mutation.set-query-formula-dependency-all": never(FORMULA_RESULT),
1673
+ "formula.mutation.set-query-formula-dependency-all-result": never(FORMULA_RESULT),
1674
+ "formula.mutation.register-function": never("registers a function body on this seat's engine"),
1675
+ "sheet.mutation.data-validation-formula-mark-dirty": never("dirty mark"),
1676
+ "sheet.mutation.mark-dirty-filter-change": never("dirty mark"),
1677
+ "sheet.mutation.re-calc-filter": never("filter recalculation result"),
1678
+ "sheet.mutation.toggle-note-popup": never("popup state"),
1679
+ "sheet.operation.clear-drawing-transformer": never("drawing selection handles (declared as a mutation)"),
1680
+ "sheet.mutation.copy-worksheet-end": never("end marker of a copy; the copy travels as insert-sheet"),
1681
+ "sheet.mutation.empty": never("no content"),
1682
+ "thread-comment.mutation.add-comment": never(UNIVER_COMMENTS),
1683
+ "thread-comment.mutation.update-comment": never(UNIVER_COMMENTS),
1684
+ "thread-comment.mutation.update-comment-ref": never(UNIVER_COMMENTS),
1685
+ "thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
1686
+ "thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
1687
+ // ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
1688
+ "sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
1689
+ "sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
1690
+ "sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
1691
+ "sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
1692
+ "sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
1693
+ "sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
1694
+ "sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
1695
+ "sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
1696
+ "sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
1697
+ "sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
1698
+ "sheet.mutation.set-worksheet-right-to-left": barrier("X", "sheet-level setting: not in C5a"),
1699
+ "sheet.mutation.toggle-gridlines": barrier("X", "sheet-level setting: not in C5a"),
1700
+ "sheet.mutation.set-gridlines-color": barrier("X", "sheet-level setting: not in C5a"),
1701
+ "sheet.mutation.set-worksheet-default-style": barrier("X", "sheet-level setting: not in C5a"),
1702
+ "sheet.mutation.set-frozen": barrier("X", "absolute frozen indices: not in C5a"),
1703
+ "sheet.mutation.set-row-data": barrier("X", "row properties by index: not in C5a"),
1704
+ "sheet.mutation.set-col-data": barrier("X", "column properties by index: not in C5a"),
1705
+ "sheet.mutation.set-row-hidden": barrier("X", "row visibility: not in C5a"),
1706
+ "sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
1707
+ "sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
1708
+ "sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
1709
+ "sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
1710
+ "sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
1711
+ "sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
1712
+ "sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
1713
+ "sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
1714
+ "sheet.mutation.add-worksheet-protection": barrier("X", "permissions: not in C5a"),
1715
+ "sheet.mutation.set-worksheet-protection": barrier("X", "permissions: not in C5a"),
1716
+ "sheet.mutation.delete-worksheet-protection": barrier("X", "permissions: not in C5a"),
1717
+ "sheet.mutation.set-worksheet-permission-points": barrier("X", "permissions: not in C5a"),
1718
+ // ── formulas (C5b) ───────────────────────────────────────────────────────────────────────────────
1719
+ "formula.mutation.set-defined-name": covered("defname", "id", "name", "formulaOrRefString", "formulaOrRefStringWithPrefix", "comment", "localSheetId", "hidden", "refSheets", "previousName", "derived"),
1720
+ "formula.mutation.remove-defined-name": covered("defname", "id", "name"),
1721
+ "formula.mutation.set-feature-calculation": barrier("X", "a plugin's registered calculation (feature id + dependency ranges); no transform yet"),
1722
+ "formula.mutation.remove-feature-calculation": barrier("X", "a plugin's registered calculation; no transform yet"),
1723
+ "formula.mutation.set-other-formula": barrier("C5c", "formulas owned by conditional formats and data validation travel with their rule"),
1724
+ "formula.mutation.remove-other-formula": barrier("C5c", "formulas owned by conditional formats and data validation travel with their rule"),
1725
+ "formula.mutation.set-super-table": barrier("C5c", "table names in structured references belong to tables (C5c)"),
1726
+ "formula.mutation.remove-super-table": barrier("C5c", "table names in structured references belong to tables (C5c)"),
1727
+ "formula.mutation.set-super-table-option": barrier("C5c", "table names in structured references belong to tables (C5c)"),
1728
+ // ── barriers until C5c (ranged resources) ────────────────────────────────────────────────────────
1729
+ "sheet.mutation.add-conditional-rule": barrier("C5c", RESOURCE),
1730
+ "sheet.mutation.set-conditional-rule": barrier("C5c", RESOURCE),
1731
+ "sheet.mutation.delete-conditional-rule": barrier("C5c", RESOURCE),
1732
+ "sheet.mutation.move-conditional-rule": barrier("C5c", "conditional-format priority (ordered list)"),
1733
+ "data-validation.mutation.addRule": barrier("C5c", RESOURCE),
1734
+ "data-validation.mutation.updateRule": barrier("C5c", RESOURCE),
1735
+ "data-validation.mutation.removeRule": barrier("C5c", RESOURCE),
1736
+ "sheet.mutation.set-filter-range": barrier("C5c", RESOURCE),
1737
+ "sheet.mutation.set-filter-criteria": barrier("C5c", RESOURCE),
1738
+ "sheet.mutation.remove-filter": barrier("C5c", RESOURCE),
1739
+ "sheet.mutation.add-table": barrier("C5c", RESOURCE),
1740
+ "sheet.mutation.delete-table": barrier("C5c", RESOURCE),
1741
+ "sheet.mutation.set-sheet-table": barrier("C5c", RESOURCE),
1742
+ "sheet.mutation.set-table-filter": barrier("C5c", RESOURCE),
1743
+ "sheet.mutation.move-table": barrier("C5c", RESOURCE),
1744
+ "sheets.mutation.add-hyper-link": barrier("C5c", RESOURCE),
1745
+ "sheets.mutation.remove-hyper-link": barrier("C5c", RESOURCE),
1746
+ "sheets.mutation.update-hyper-link": barrier("C5c", RESOURCE),
1747
+ "sheets.mutation.update-hyper-link-ref": barrier("C5c", RESOURCE),
1748
+ "sheets.mutation.update-rich-hyper-link": barrier("C5c", RESOURCE),
1749
+ "sheet.mutation.update-note": barrier("C5c", RESOURCE),
1750
+ "sheet.mutation.remove-note": barrier("C5c", RESOURCE),
1751
+ "sheet.mutation.update-note-position": barrier("C5c", RESOURCE),
1752
+ "sheet.mutation.set-drawing-apply": barrier("C5c", RESOURCE),
1753
+ "sheet.mutation.set-worksheet-background-image": barrier("C5c", RESOURCE),
1754
+ "sheet.mutation.add-range-theme": barrier("C5c", RESOURCE),
1755
+ "sheet.mutation.set-range-theme": barrier("C5c", RESOURCE),
1756
+ "sheet.mutation.remove-range-theme": barrier("C5c", RESOURCE),
1757
+ "sheet.mutation.set-worksheet-range-theme-style": barrier("C5c", RESOURCE),
1758
+ "sheet.mutation.remove-worksheet-range-theme-style": barrier("C5c", RESOURCE),
1759
+ "sheet.mutation.register-worksheet-range-theme-style": barrier("C5c", RESOURCE),
1760
+ "sheet.mutation.unregister-worksheet-range-theme-style": barrier("C5c", RESOURCE)
1761
+ };
1762
+ function allowParams(id, params) {
1763
+ const entry = SHEET_MUTATIONS[id];
1764
+ if (!entry || entry.kind !== "covered") return null;
1765
+ const out = {};
1766
+ for (const f of entry.allow) if (params[f] !== void 0) out[f] = params[f];
1767
+ return out;
1768
+ }
1769
+
1770
+ // src/collab/sheets/transform/transform.ts
1771
+ var import_sheets2 = require("@univerjs/sheets");
1772
+
1773
+ // src/collab/sheets/transform/axis.ts
1774
+ function isNoopMove(op) {
1775
+ return op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count;
1776
+ }
1777
+ function movedBlockStart(op) {
1778
+ return op.to > op.from ? op.to - op.count : op.to;
1779
+ }
1780
+ function mapIndex(op, i) {
1781
+ switch (op.kind) {
1782
+ case "insert":
1783
+ return i >= op.at ? i + op.count : i;
1784
+ case "remove":
1785
+ if (i < op.start) return i;
1786
+ if (i < op.start + op.count) return null;
1787
+ return i - op.count;
1788
+ case "move": {
1789
+ if (isNoopMove(op)) return i;
1790
+ const { from, count, to } = op;
1791
+ if (i >= from && i < from + count) return movedBlockStart(op) + (i - from);
1792
+ if (to > from) return i >= from + count && i < to ? i - count : i;
1793
+ return i >= to && i < from ? i + count : i;
1794
+ }
1795
+ }
1796
+ }
1797
+ function runs(indices) {
1798
+ const sorted = [...new Set(indices)].sort((a, b) => a - b);
1799
+ const out = [];
1800
+ for (const i of sorted) {
1801
+ const last = out[out.length - 1];
1802
+ if (last && last.start + last.count === i) last.count++;
1803
+ else out.push({ start: i, count: 1 });
1804
+ }
1805
+ return out;
1806
+ }
1807
+ function mapGapThroughMove(p, mv) {
1808
+ const { from, count, to } = mv;
1809
+ if (p > from && p < from + count) return movedBlockStart(mv) + (p - from);
1810
+ const g = p <= from ? p : p - count;
1811
+ const tg = to <= from ? to : to - count;
1812
+ return g <= tg ? g : g + count;
1813
+ }
1814
+ function transformAxis(x, y, side) {
1815
+ if (y.kind === "move" && isNoopMove(y)) return [x];
1816
+ if (x.kind === "move" && isNoopMove(x)) return [];
1817
+ switch (x.kind) {
1818
+ case "insert": {
1819
+ if (y.kind === "insert") {
1820
+ if (x.at < y.at || x.at === y.at && side === "left") return [x];
1821
+ return [{ ...x, at: x.at + y.count }];
1822
+ }
1823
+ if (y.kind === "remove") {
1824
+ if (x.at <= y.start) return [x];
1825
+ if (x.at >= y.start + y.count) return [{ ...x, at: x.at - y.count }];
1826
+ return [{ ...x, at: y.start }];
1827
+ }
1828
+ return [{ ...x, at: mapGapThroughMove(x.at, y) }];
1829
+ }
1830
+ case "remove": {
1831
+ const kept = [];
1832
+ for (let i = x.start; i < x.start + x.count; i++) {
1833
+ const m = mapIndex(y, i);
1834
+ if (m !== null) kept.push(m);
1835
+ }
1836
+ if (y.kind === "insert" || y.kind === "remove" || y.kind === "move") {
1837
+ return runs(kept).reverse().map((r) => ({ kind: "remove", start: r.start, count: r.count }));
1838
+ }
1839
+ return null;
1840
+ }
1841
+ case "move": {
1842
+ if (y.kind === "insert") {
1843
+ const inside = y.at > x.from && y.at < x.from + x.count;
1844
+ const from = inside || y.at > x.from ? x.from : x.from + y.count;
1845
+ const count = inside ? x.count + y.count : x.count;
1846
+ const to2 = x.to >= y.at ? x.to + y.count : x.to;
1847
+ const out2 = { kind: "move", from, count, to: to2 };
1848
+ return isNoopMove(out2) ? [] : [out2];
1849
+ }
1850
+ if (y.kind === "remove") {
1851
+ const kept = [];
1852
+ for (let i = x.from; i < x.from + x.count; i++) {
1853
+ const m = mapIndex(y, i);
1854
+ if (m !== null) kept.push(m);
1855
+ }
1856
+ if (kept.length === 0) return [];
1857
+ const r2 = runs(kept);
1858
+ if (r2.length !== 1) return null;
1859
+ const to2 = x.to <= y.start ? x.to : x.to >= y.start + y.count ? x.to - y.count : y.start;
1860
+ const out2 = { kind: "move", from: r2[0].start, count: r2[0].count, to: to2 };
1861
+ return isNoopMove(out2) ? [] : [out2];
1862
+ }
1863
+ const overlap = Math.min(x.from + x.count, y.from + y.count) - Math.max(x.from, y.from);
1864
+ if (overlap > 0) {
1865
+ if (x.from !== y.from || x.count !== y.count) return null;
1866
+ if (side === "right") return [];
1867
+ const out2 = { kind: "move", from: movedBlockStart(y), count: x.count, to: mapGapThroughMove(x.to, y) };
1868
+ return isNoopMove(out2) ? [] : [out2];
1869
+ }
1870
+ const mapped = [];
1871
+ for (let i = x.from; i < x.from + x.count; i++) mapped.push(mapIndex(y, i));
1872
+ const r = runs(mapped);
1873
+ if (r.length !== 1) return null;
1874
+ let to;
1875
+ if (x.to > y.from && x.to < y.from + y.count) to = movedBlockStart(y) + (x.to - y.from);
1876
+ else to = mapGapThroughMove(x.to, y) + (x.to === y.to && side === "right" ? y.count : 0);
1877
+ const out = { kind: "move", from: r[0].start, count: r[0].count, to };
1878
+ if (to > out.from && to < out.from + out.count) return null;
1879
+ return isNoopMove(out) ? [] : [out];
1880
+ }
1881
+ }
1882
+ }
1883
+
1884
+ // src/collab/sheets/transform/formula.ts
1885
+ var import_core3 = require("@univerjs/core");
1886
+ var import_engine_formula = require("@univerjs/engine-formula");
1887
+ var import_sheets = require("@univerjs/sheets");
1888
+ var REF_ERROR = "#REF!";
1889
+ var FULL = 16383 * 64;
1890
+ var lexer = null;
1891
+ var lex = (body) => (lexer ??= new import_engine_formula.LexerTreeBuilder()).sequenceNodesBuilder(body);
1892
+ var isFormulaText = (f) => typeof f === "string" && f.length > 1 && f.startsWith("=");
1893
+ var IDENT = /^[A-Za-z_\\][A-Za-z0-9_.\\]*$/;
1894
+ var ERROR_TOKEN = /^(?:[^!]+!)?#(?:REF!|NAME\?|VALUE!|DIV\/0!|N\/A|NUM!|NULL!|SPILL!|CALC!)$/i;
1895
+ function parse(text) {
1896
+ const prefix = text.startsWith("=") ? "=" : "";
1897
+ const nodes = lex(text.slice(prefix.length));
1898
+ if (!nodes) return "the formula lexer could not read the text";
1899
+ for (const n of nodes) {
1900
+ if (typeof n === "string") continue;
1901
+ if (n.nodeType === import_engine_formula.sequenceNodeType.TABLE || n.nodeType === import_engine_formula.sequenceNodeType.FUNCTION && n.token.includes("[")) return "a structured table reference (tables are C5c)";
1902
+ if (n.nodeType === import_engine_formula.sequenceNodeType.FUNCTION && !IDENT.test(n.token) && !ERROR_TOKEN.test(n.token))
1903
+ return `the lexer read "${n.token}" as one name (an intersection or a reference it cannot split)`;
1904
+ if (n.nodeType === import_engine_formula.sequenceNodeType.REFERENCE) {
1905
+ const d = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
1906
+ if (d.unitId) return "a reference into another workbook";
1907
+ }
1908
+ }
1909
+ return { prefix, nodes };
1910
+ }
1911
+ function targetSheet(sheetName, ctx) {
1912
+ if (!sheetName) return ctx.ownSheet;
1913
+ const id = ctx.refSheets?.[sheetName];
1914
+ if (id === void 0) return void 0;
1915
+ return id ?? "";
1916
+ }
1917
+ function formulaBarrier(text, ctx) {
1918
+ const p = parse(text);
1919
+ if (typeof p === "string") return p;
1920
+ for (const n of p.nodes) {
1921
+ if (typeof n === "string" || n.nodeType !== import_engine_formula.sequenceNodeType.REFERENCE) continue;
1922
+ const { sheetName } = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
1923
+ if (targetSheet(sheetName, ctx) === void 0) return `sheet "${sheetName}" is not in refSheets (capture must call annotateRefSheets)`;
1924
+ }
1925
+ return null;
1926
+ }
1927
+ function referencedSheetNames(text) {
1928
+ const p = parse(text);
1929
+ if (typeof p === "string") return [];
1930
+ const out = /* @__PURE__ */ new Set();
1931
+ for (const n of p.nodes) if (typeof n !== "string" && n.nodeType === import_engine_formula.sequenceNodeType.REFERENCE) {
1932
+ const { sheetName } = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
1933
+ if (sheetName) out.add(sheetName);
1934
+ }
1935
+ return [...out];
1936
+ }
1937
+ var fullRowsRange = (start, count) => ({ startRow: start, endRow: start + count - 1, startColumn: 0, endColumn: FULL, rangeType: import_core3.RANGE_TYPE.ROW });
1938
+ var fullColsRange = (start, count) => ({ startRow: 0, endRow: FULL, startColumn: start, endColumn: start + count - 1, rangeType: import_core3.RANGE_TYPE.COLUMN });
1939
+ var startV = (v) => Number.isNaN(v) || v == null ? -Infinity : v;
1940
+ var endV = (v) => Number.isNaN(v) || v == null ? Infinity : v;
1941
+ function startEnd(r) {
1942
+ return { ...r, startRow: startV(r.startRow), endRow: endV(r.endRow), startColumn: startV(r.startColumn), endColumn: endV(r.endColumn) };
1943
+ }
1944
+ function checkMoveEdge(origin, from) {
1945
+ const startRow = startV(origin.startRow), endRow = endV(origin.endRow), startColumn = startV(origin.startColumn), endColumn = endV(origin.endColumn);
1946
+ const fromStartRow = startV(from.startRow), fromEndRow = endV(from.endRow), fromStartColumn = startV(from.startColumn), fromEndColumn = endV(from.endColumn);
1947
+ const rowsCover = () => origin.rangeType === import_core3.RANGE_TYPE.COLUMN && from.rangeType === import_core3.RANGE_TYPE.COLUMN || startRow >= fromStartRow && endRow <= fromEndRow;
1948
+ const columnsCover = () => origin.rangeType === import_core3.RANGE_TYPE.ROW && from.rangeType === import_core3.RANGE_TYPE.ROW || startColumn >= fromStartColumn && endColumn <= fromEndColumn;
1949
+ const allCover = () => origin.rangeType === import_core3.RANGE_TYPE.ALL && from.rangeType === import_core3.RANGE_TYPE.ALL;
1950
+ if (rowsCover() && columnsCover() || allCover()) return 4;
1951
+ if (columnsCover() && startRow >= fromStartRow && startRow <= fromEndRow && endRow > fromEndRow) return 0;
1952
+ if (columnsCover() && endRow >= fromStartRow && endRow <= fromEndRow && startRow < fromStartRow) return 1;
1953
+ if (rowsCover() && startColumn >= fromStartColumn && startColumn <= fromEndColumn && endColumn > fromEndColumn) return 2;
1954
+ if (rowsCover() && endColumn >= fromStartColumn && endColumn <= fromEndColumn && startColumn < fromStartColumn) return 3;
1955
+ return null;
1956
+ }
1957
+ function getMoveNewRange(moveEdge, result, from, to, origin, remain) {
1958
+ const { startRow, endRow, startColumn, endColumn, rangeType } = startEnd(result);
1959
+ const f = startEnd(from);
1960
+ const fromRangeType = from.rangeType ?? import_core3.RANGE_TYPE.NORMAL;
1961
+ const t = startEnd(to);
1962
+ const rm = startEnd(remain);
1963
+ const o = startEnd(origin);
1964
+ const originRangeType = origin.rangeType ?? import_core3.RANGE_TYPE.NORMAL;
1965
+ const newRange = { ...origin };
1966
+ const rowsCover = () => rangeType === import_core3.RANGE_TYPE.COLUMN && originRangeType === import_core3.RANGE_TYPE.COLUMN || startColumn >= o.startColumn && endColumn <= o.endColumn;
1967
+ const columnsCover = () => rangeType === import_core3.RANGE_TYPE.ROW && originRangeType === import_core3.RANGE_TYPE.ROW || startRow >= o.startRow && endRow <= o.endRow;
1968
+ if (moveEdge === 0) {
1969
+ if (!rowsCover()) return void 0;
1970
+ if (startRow < o.startRow) newRange.startRow = startRow;
1971
+ else if (startRow >= o.endRow) newRange.endRow -= f.endRow + 1 - o.startRow;
1972
+ else return void 0;
1973
+ } else if (moveEdge === 1) {
1974
+ if (!rowsCover()) return void 0;
1975
+ if (endRow > o.endRow) newRange.endRow = endRow;
1976
+ else if (endRow <= o.startRow) newRange.startRow += o.endRow - f.startRow + 1;
1977
+ else return void 0;
1978
+ } else if (moveEdge === 2) {
1979
+ if (!columnsCover()) return void 0;
1980
+ if (startColumn < o.startColumn) newRange.startColumn = startColumn;
1981
+ else if (startColumn >= o.endColumn) newRange.endColumn -= f.endColumn + 1 - o.startColumn;
1982
+ else return void 0;
1983
+ } else if (moveEdge === 3) {
1984
+ if (!columnsCover()) return void 0;
1985
+ if (endColumn > o.endColumn) newRange.endColumn = endColumn;
1986
+ else if (endColumn <= o.startColumn) newRange.startColumn += o.endColumn - f.startColumn + 1;
1987
+ else return void 0;
1988
+ } else if (moveEdge === 4) {
1989
+ Object.assign(newRange, { startRow, startColumn, endRow, endColumn });
1990
+ } else if (f.startColumn <= o.startColumn && f.endColumn >= o.endColumn || fromRangeType === import_core3.RANGE_TYPE.ROW && originRangeType === import_core3.RANGE_TYPE.ROW) {
1991
+ const n = f.endRow - f.startRow + 1;
1992
+ if (from.endRow < o.startRow) {
1993
+ if (t.startRow >= o.startRow) newRange.startRow -= n;
1994
+ if (t.startRow >= o.endRow) newRange.endRow -= n;
1995
+ } else if (from.startRow > o.endRow) {
1996
+ if (t.endRow <= o.endRow) newRange.endRow += n;
1997
+ if (t.endRow <= o.startRow) newRange.startRow += n;
1998
+ } else if (from.startRow >= o.startRow && from.endRow <= o.endRow) {
1999
+ if (t.startRow <= o.startRow) newRange.startRow += n;
2000
+ else if (t.startRow >= o.endRow) newRange.endRow -= n;
2001
+ }
2002
+ } else if (f.startRow <= o.startRow && f.endRow >= o.endRow || fromRangeType === import_core3.RANGE_TYPE.COLUMN && originRangeType === import_core3.RANGE_TYPE.COLUMN) {
2003
+ const n = f.endColumn - f.startColumn + 1;
2004
+ if (from.endColumn < o.startColumn) {
2005
+ if (t.startColumn >= o.startColumn) newRange.startColumn -= n;
2006
+ if (t.startColumn >= o.endColumn) newRange.endColumn -= n;
2007
+ } else if (from.startColumn > o.endColumn) {
2008
+ if (t.endColumn <= o.endColumn) newRange.endColumn += n;
2009
+ if (t.endColumn <= o.startColumn) newRange.startColumn += n;
2010
+ } else if (from.startColumn >= o.startColumn && from.endColumn <= o.endColumn) {
2011
+ if (t.startColumn <= o.startColumn) newRange.startColumn += n;
2012
+ else if (t.startColumn >= o.endColumn) newRange.endColumn -= n;
2013
+ }
2014
+ } else {
2015
+ Object.assign(newRange, { startRow, startColumn, endRow, endColumn });
2016
+ void rm;
2017
+ }
2018
+ return newRange;
2019
+ }
2020
+ function moveRange(range, axis, op) {
2021
+ const isRow = axis === "row";
2022
+ if (op.kind === "insert") {
2023
+ const r = isRow ? fullRowsRange(op.at, op.count) : fullColsRange(op.at, op.count);
2024
+ const ops2 = isRow ? (0, import_sheets.handleInsertRow)({ id: import_sheets.EffectRefRangId.InsertRowCommandId, params: { range: r, unitId: "", subUnitId: "", direction: import_core3.Direction.DOWN } }, range) : (0, import_sheets.handleInsertCol)({ id: import_sheets.EffectRefRangId.InsertColCommandId, params: { range: r, unitId: "", subUnitId: "", direction: import_core3.Direction.RIGHT } }, range);
2025
+ const res2 = (0, import_sheets.runRefRangeMutations)(ops2, range);
2026
+ return res2 == null ? void 0 : { ...range, ...res2 };
2027
+ }
2028
+ if (op.kind === "remove") {
2029
+ const r = isRow ? fullRowsRange(op.start, op.count) : fullColsRange(op.start, op.count);
2030
+ const ops2 = isRow ? (0, import_sheets.handleIRemoveRow)({ id: import_sheets.EffectRefRangId.RemoveRowCommandId, params: { range: r } }, range, []) : (0, import_sheets.handleIRemoveCol)({ id: import_sheets.EffectRefRangId.RemoveColCommandId, params: { range: r } }, range);
2031
+ const res2 = (0, import_sheets.runRefRangeMutations)(ops2, range);
2032
+ return res2 == null ? REF_ERROR : { ...range, ...res2 };
2033
+ }
2034
+ const from = isRow ? fullRowsRange(op.from, op.count) : fullColsRange(op.from, op.count);
2035
+ const to = isRow ? fullRowsRange(op.to, op.count) : fullColsRange(op.to, op.count);
2036
+ const moveEdge = checkMoveEdge(range, from);
2037
+ let remain = (0, import_core3.getIntersectRange)(range, from);
2038
+ if (isRow) {
2039
+ if (remain == null && (from.endRow < range.startRow && to.endRow <= range.startRow || from.startRow > range.endRow && to.startRow > range.endRow)) return void 0;
2040
+ } else if (remain == null && (from.endColumn < range.startColumn && to.endColumn <= range.startColumn || from.startColumn > range.endColumn && to.startColumn > range.endColumn)) return void 0;
2041
+ remain ??= { startRow: range.startRow, endRow: range.endRow, startColumn: range.startColumn, endColumn: range.endColumn, rangeType: import_core3.RANGE_TYPE.NORMAL };
2042
+ const ops = isRow ? (0, import_sheets.handleMoveRows)({ id: import_sheets.EffectRefRangId.MoveRowsCommandId, params: { toRange: to, fromRange: from } }, remain) : (0, import_sheets.handleMoveCols)({ id: import_sheets.EffectRefRangId.MoveColsCommandId, params: { toRange: to, fromRange: from } }, remain);
2043
+ const res = (0, import_sheets.runRefRangeMutations)(ops, remain);
2044
+ if (res == null) return REF_ERROR;
2045
+ return getMoveNewRange(moveEdge, res, from, to, range, remain);
2046
+ }
2047
+ function rewriteFormula(text, ctx, change) {
2048
+ const p = parse(text);
2049
+ if (typeof p === "string") return p;
2050
+ const nodes = p.nodes.slice();
2051
+ const changedIds = [];
2052
+ for (let i = 0; i < nodes.length; i++) {
2053
+ const n = nodes[i];
2054
+ if (typeof n === "string") continue;
2055
+ if (change.kind === "defined-name") {
2056
+ if ((n.nodeType === import_engine_formula.sequenceNodeType.DEFINED_NAME || n.nodeType === import_engine_formula.sequenceNodeType.FUNCTION) && n.token === change.from) {
2057
+ nodes[i] = { ...n, token: change.to ?? REF_ERROR };
2058
+ changedIds.push(i);
2059
+ }
2060
+ continue;
2061
+ }
2062
+ if (n.nodeType !== import_engine_formula.sequenceNodeType.REFERENCE) continue;
2063
+ const { range, sheetName, unitId } = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
2064
+ const target = targetSheet(sheetName, ctx);
2065
+ if (target === void 0) return `sheet "${sheetName}" is not in refSheets (capture must call annotateRefSheets)`;
2066
+ if (target !== change.sheet) continue;
2067
+ let token;
2068
+ if (change.kind === "rename") {
2069
+ if (!sheetName) continue;
2070
+ token = (0, import_engine_formula.serializeRangeToRefString)({ range, sheetName: change.name, unitId });
2071
+ } else {
2072
+ const moved = moveRange(import_core3.Rectangle.moveOffset(range, 0, 0), change.axis, change.op);
2073
+ if (moved === void 0) continue;
2074
+ token = moved === REF_ERROR ? REF_ERROR : (0, import_engine_formula.serializeRangeToRefString)({ range: moved, sheetName: target === ctx.ownSheet && !ctx.keepQualifier ? "" : sheetName, unitId });
2075
+ }
2076
+ nodes[i] = { ...n, token };
2077
+ changedIds.push(i);
2078
+ }
2079
+ if (!changedIds.length) return { text, changed: false };
2080
+ for (let i = 0; i < nodes.length; i++) {
2081
+ const n = nodes[i];
2082
+ if (typeof n === "string" || n.nodeType !== import_engine_formula.sequenceNodeType.REFERENCE || changedIds.includes(i)) continue;
2083
+ nodes[i] = { ...n, token: (0, import_engine_formula.serializeRangeToRefString)((0, import_engine_formula.deserializeRangeWithSheet)(n.token)) };
2084
+ }
2085
+ const out = p.prefix + (0, import_engine_formula.generateStringWithSequence)(nodes);
2086
+ return { text: out, changed: out !== text };
2087
+ }
2088
+ function refSheetsAfter(refSheets, change) {
2089
+ if (change.kind !== "rename" || !refSheets) return refSheets;
2090
+ const entries = Object.entries(refSheets);
2091
+ if (!entries.some(([name, id]) => id === change.sheet || name === change.name)) return refSheets;
2092
+ const next = {};
2093
+ for (const [name, id] of entries) if (id !== change.sheet && name !== change.name) next[name] = id;
2094
+ next[change.name] = change.sheet;
2095
+ return next;
2096
+ }
2097
+ function refSheetsFor(texts, sheets) {
2098
+ const byName = new Map(Object.entries(sheets).map(([id, name]) => [name, id]));
2099
+ const out = {};
2100
+ for (const t of texts) for (const name of referencedSheetNames(t)) out[name] = byName.get(name) ?? null;
2101
+ return Object.keys(out).length ? out : void 0;
2102
+ }
2103
+
2104
+ // src/collab/sheets/transform/transform.ts
2105
+ var SHEET_TRANSFORMER_VERSION = "c5b-1";
2106
+ var ID = {
2107
+ values: "sheet.mutation.set-range-values",
2108
+ insertRow: "sheet.mutation.insert-row",
2109
+ removeRows: "sheet.mutation.remove-rows",
2110
+ insertCol: "sheet.mutation.insert-col",
2111
+ removeCol: "sheet.mutation.remove-col",
2112
+ moveRows: "sheet.mutation.move-rows",
2113
+ moveCols: "sheet.mutation.move-columns",
2114
+ addMerge: "sheet.mutation.add-worksheet-merge",
2115
+ removeMerge: "sheet.mutation.remove-worksheet-merge",
2116
+ rowHeight: "sheet.mutation.set-worksheet-row-height",
2117
+ rowIsAuto: "sheet.mutation.set-worksheet-row-is-auto-height",
2118
+ rowAutoHeight: "sheet.mutation.set-worksheet-row-auto-height",
2119
+ colWidth: "sheet.mutation.set-worksheet-col-width",
2120
+ name: "sheet.mutation.set-worksheet-name",
2121
+ setName: "formula.mutation.set-defined-name",
2122
+ removeName: "formula.mutation.remove-defined-name"
2123
+ };
2124
+ var PAIR_BARRIERS = {};
2125
+ var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
2126
+ var barrier2 = (reason) => ({ barrier: true, reason });
2127
+ var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2128
+ var flip = (side) => side === "left" ? "right" : "left";
2129
+ var sheetOf = (m) => String(m.params.subUnitId ?? "");
2130
+ function colName(c) {
2131
+ let s = "";
2132
+ for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
2133
+ return s;
2134
+ }
2135
+ var cellRef = (sheet, row, col) => `${sheet}!${colName(col)}${row + 1}`;
2136
+ var rangeRef = (sheet, r) => `${sheet}!${colName(r.startColumn)}${r.startRow + 1}:${colName(r.endColumn)}${r.endRow + 1}`;
2137
+ function structuralOf(m) {
2138
+ const p = m.params;
2139
+ switch (m.id) {
2140
+ case ID.insertRow:
2141
+ return { axis: "row", op: { kind: "insert", at: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } };
2142
+ case ID.removeRows:
2143
+ return { axis: "row", op: { kind: "remove", start: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } };
2144
+ case ID.insertCol:
2145
+ return { axis: "col", op: { kind: "insert", at: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } };
2146
+ case ID.removeCol:
2147
+ return { axis: "col", op: { kind: "remove", start: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } };
2148
+ case ID.moveRows:
2149
+ return {
2150
+ axis: "row",
2151
+ op: { kind: "move", from: p.sourceRange.startRow, count: p.sourceRange.endRow - p.sourceRange.startRow + 1, to: p.targetRange.startRow }
2152
+ };
2153
+ case ID.moveCols:
2154
+ return {
2155
+ axis: "col",
2156
+ op: {
2157
+ kind: "move",
2158
+ from: p.sourceRange.startColumn,
2159
+ count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1,
2160
+ to: p.targetRange.startColumn
2161
+ }
2162
+ };
2163
+ default:
2164
+ return null;
2165
+ }
2166
+ }
2167
+ var S = (axis) => axis === "row" ? ["startRow", "endRow"] : ["startColumn", "endColumn"];
2168
+ function buildStructural(template, axis, op) {
2169
+ const [a0, a1] = S(axis);
2170
+ const p = template.params;
2171
+ if (op.kind === "move") {
2172
+ const src = p.sourceRange;
2173
+ const tgt = p.targetRange;
2174
+ return {
2175
+ id: template.id,
2176
+ params: {
2177
+ ...p,
2178
+ sourceRange: { ...src, [a0]: op.from, [a1]: op.from + op.count - 1 },
2179
+ targetRange: { ...tgt, [a0]: op.to, [a1]: op.to + op.count - 1 }
2180
+ }
2181
+ };
2182
+ }
2183
+ const start = op.kind === "insert" ? op.at : op.start;
2184
+ return { id: template.id, params: { ...p, range: { ...p.range, [a0]: start, [a1]: start + op.count - 1 } } };
2185
+ }
2186
+ function univerMutationInfo(axis, op) {
2187
+ const FULL2 = { startRow: 0, endRow: Number.MAX_SAFE_INTEGER, startColumn: 0, endColumn: Number.MAX_SAFE_INTEGER };
2188
+ const start = op.kind === "insert" ? op.at : op.start;
2189
+ const range = axis === "row" ? { ...FULL2, startRow: start, endRow: start + op.count - 1 } : { ...FULL2, startColumn: start, endColumn: start + op.count - 1 };
2190
+ const id = op.kind === "insert" ? axis === "row" ? ID.insertRow : ID.insertCol : axis === "row" ? ID.removeRows : ID.removeCol;
2191
+ return { id, params: { unitId: "", subUnitId: "", range } };
2192
+ }
2193
+ var intersects = (a, b) => a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
2194
+ var isSingleCell = (r) => r.startRow === r.endRow && r.startColumn === r.endColumn;
2195
+ function mergeThrough(s, m) {
2196
+ const [a0, a1] = S(s.axis);
2197
+ const lo = m[a0];
2198
+ const hi = m[a1];
2199
+ const op = s.op;
2200
+ if (op.kind === "insert") {
2201
+ const fixup = lo < op.at && op.at <= hi;
2202
+ return { range: (0, import_sheets2.adjustRangeOnMutation)(m, univerMutationInfo(s.axis, op)), fixup };
2203
+ }
2204
+ if (op.kind === "remove") {
2205
+ const e = op.start + op.count - 1;
2206
+ if (e < lo || op.start > hi) return { range: (0, import_sheets2.adjustRangeOnMutation)(m, univerMutationInfo(s.axis, op)), fixup: false };
2207
+ if (op.start <= lo && e >= hi) return { range: null, fixup: true };
2208
+ const r = { ...m };
2209
+ if (op.start >= lo && e <= hi) r[a1] = hi - op.count;
2210
+ else if (op.start < lo) {
2211
+ r[a0] = op.start;
2212
+ r[a1] = hi - op.count;
2213
+ } else r[a1] = op.start - 1;
2214
+ return { range: isSingleCell(r) ? null : r, fixup: true };
2215
+ }
2216
+ const fe = op.from + op.count - 1;
2217
+ if (hi < op.from || lo > fe) {
2218
+ const r = { ...m };
2219
+ if (op.from < lo && op.to > hi) {
2220
+ r[a0] = lo - op.count;
2221
+ r[a1] = hi - op.count;
2222
+ } else if (op.from > hi && op.to <= lo) {
2223
+ r[a0] = lo + op.count;
2224
+ r[a1] = hi + op.count;
2225
+ }
2226
+ return { range: r, fixup: false };
2227
+ }
2228
+ if (lo >= op.from && hi <= fe) {
2229
+ const r = { ...m, [a0]: mapIndex(op, lo), [a1]: mapIndex(op, hi) };
2230
+ return { range: r, fixup: true };
2231
+ }
2232
+ return { range: m, fixup: false };
2233
+ }
2234
+ function exactMergeRemovals(group, merges) {
2235
+ const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
2236
+ const out = [];
2237
+ for (const m of group) {
2238
+ const sheet = sheetOf(m);
2239
+ const cur = sim.get(sheet) ?? [];
2240
+ if (m.id === ID.removeMerge) {
2241
+ const hit = cur.filter((q) => mergeRanges(m).some((r) => intersects(r, q)));
2242
+ sim.set(sheet, cur.filter((q) => !hit.includes(q)));
2243
+ if (hit.length) out.push(withRanges(m, hit.map((r) => ({ ...r }))));
2244
+ continue;
2245
+ }
2246
+ if (m.id === ID.addMerge) sim.set(sheet, [...cur, ...mergeRanges(m).map((r) => ({ ...r }))]);
2247
+ const st = structuralOf(m);
2248
+ if (st) sim.set(sheet, cur.map((q) => mergeThrough(st, q).range).filter((q) => q !== null));
2249
+ out.push(m);
2250
+ }
2251
+ return out;
2252
+ }
2253
+ var mergeRanges = (m) => m.params.ranges ?? [];
2254
+ var withRanges = (m, ranges) => ({ id: m.id, params: { ...m.params, ranges } });
2255
+ var mergeMutation = (id, sheet, ranges) => ({ id, params: { subUnitId: sheet, ranges } });
2256
+ var CONTENT_KEYS = ["v", "t", "p", "f", "si", "custom", "ref", "xf", "ft", "fd"];
2257
+ var CONTENT_TOUCH = ["v", "p", "f", "si", "custom", "ref", "xf", "ft", "fd"];
2258
+ var KNOWN_CELL_KEYS = /* @__PURE__ */ new Set([...CONTENT_KEYS, "s"]);
2259
+ function completeCellContent(entry, post) {
2260
+ if (entry === null) return null;
2261
+ if (!CONTENT_TOUCH.some((k) => k in entry)) return entry;
2262
+ const out = {};
2263
+ for (const k of CONTENT_KEYS) out[k] = post && post[k] !== void 0 ? post[k] : null;
2264
+ if (out.v === null) delete out.t;
2265
+ if ("s" in entry) out.s = entry.s;
2266
+ return out;
2267
+ }
2268
+ function cellsOf(m) {
2269
+ return m.params.cellValue ?? {};
2270
+ }
2271
+ function forEachCell(cells, fn) {
2272
+ for (const r of Object.keys(cells)) for (const c of Object.keys(cells[r] ?? {})) fn(Number(r), Number(c), cells[r][c] ?? null);
2273
+ }
2274
+ function cellsMutation(template, cells) {
2275
+ return { id: template.id, params: { ...template.params, cellValue: cells } };
2276
+ }
2277
+ function putCell(cells, r, c, v) {
2278
+ (cells[r] ??= {})[c] = v;
2279
+ }
2280
+ var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
2281
+ function cellBarrier(m) {
2282
+ if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
2283
+ let why = null;
2284
+ forEachCell(cellsOf(m), (_r, _c, v) => {
2285
+ if (why || v === null) return;
2286
+ for (const k of Object.keys(v)) {
2287
+ if (why) break;
2288
+ if (!KNOWN_CELL_KEYS.has(k)) why = `cell key "${k}" is not covered`;
2289
+ else if (k === "si" && v.si != null) why = "shared formula (si): its text lives in a master cell this op does not carry";
2290
+ else if (k === "f" && isFormulaText(v.f) || k === "ref" && typeof v.ref === "string") why = formulaBarrier(v[k], formulaCtx(m));
2291
+ }
2292
+ if (typeof v.s === "string") why = "a style id travels (style ids are seat-local; capture must send the style object)";
2293
+ if (!why && CONTENT_TOUCH.some((k) => k in v) && !CONTENT_KEYS.every((k) => k in v || k === "t" && v.v == null))
2294
+ why = "cell content is not completed (capture must call completeCellContent)";
2295
+ });
2296
+ return why;
2297
+ }
2298
+ var hasContent = (v) => CONTENT_TOUCH.some((k) => k in v);
2299
+ var contentOf = (v) => {
2300
+ const out = {};
2301
+ for (const k of Object.keys(v)) if (k !== "s") out[k] = v[k];
2302
+ return out;
2303
+ };
2304
+ var richText = (v) => v.p != null;
2305
+ function styleKeys(s) {
2306
+ const out = [];
2307
+ for (const k of Object.keys(s)) {
2308
+ if (k === "bd" && s.bd && typeof s.bd === "object") for (const side of Object.keys(s.bd)) out.push(`bd.${side}`);
2309
+ else out.push(k);
2310
+ }
2311
+ return out;
2312
+ }
2313
+ function withoutStyleKeys(s, drop) {
2314
+ const out = {};
2315
+ for (const k of Object.keys(s)) {
2316
+ if (k === "bd" && s.bd && typeof s.bd === "object") {
2317
+ const bd = {};
2318
+ for (const side of Object.keys(s.bd)) if (!drop.has(`bd.${side}`)) bd[side] = s.bd[side];
2319
+ if (Object.keys(bd).length) out.bd = bd;
2320
+ } else if (!drop.has(k)) out[k] = s[k];
2321
+ }
2322
+ return Object.keys(out).length ? out : null;
2323
+ }
2324
+ function transformCell(X, Y4, side) {
2325
+ if (X === null || Y4 === null) {
2326
+ if (side === "left") return { entries: [X], xLost: false, yLost: true };
2327
+ return X === null ? { entries: [null, Y4], xLost: true, yLost: false } : { entries: [], xLost: true, yLost: false };
2328
+ }
2329
+ if (hasContent(X) && richText(X) && "s" in Y4 || hasContent(Y4) && richText(Y4) && "s" in X)
2330
+ return "rich-text content concurrent with a style change on the same cell is not covered";
2331
+ const out = {};
2332
+ let xLost = false;
2333
+ let yLost = false;
2334
+ if (hasContent(X)) {
2335
+ if (!hasContent(Y4) || side === "left") Object.assign(out, contentOf(X));
2336
+ else xLost = true;
2337
+ if (hasContent(Y4) && side === "left") yLost = true;
2338
+ }
2339
+ const tail = [];
2340
+ if ("s" in X) {
2341
+ const xs = X.s;
2342
+ const ys = "s" in Y4 ? Y4.s : void 0;
2343
+ if (ys === void 0 || side === "left") {
2344
+ if (xs !== void 0) out.s = xs;
2345
+ if (ys !== void 0) yLost = true;
2346
+ } else if (ys === null) {
2347
+ xLost = true;
2348
+ } else if (xs === null) {
2349
+ out.s = null;
2350
+ tail.push({ s: ys });
2351
+ xLost = true;
2352
+ } else {
2353
+ const kept = withoutStyleKeys(xs, new Set(styleKeys(ys)));
2354
+ if (kept) out.s = kept;
2355
+ if (styleKeys(xs).length !== styleKeys(kept ?? {}).length) xLost = true;
2356
+ }
2357
+ }
2358
+ return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
2359
+ }
2360
+ function transformCellsOverCells(x, y, side) {
2361
+ if (sheetOf(x) !== sheetOf(y)) return ok([x]);
2362
+ const ycells = cellsOf(y);
2363
+ const xd = isDerived(x);
2364
+ const yd = isDerived(y);
2365
+ const eff = derivedSide(x, y, side);
2366
+ const passes = [{}];
2367
+ const lost = [];
2368
+ const dropped = [];
2369
+ let why = null;
2370
+ forEachCell(cellsOf(x), (r, c, X) => {
2371
+ if (why) return;
2372
+ const yRow = ycells[r];
2373
+ if (!yRow || !(String(c) in yRow)) {
2374
+ putCell(passes[0], r, c, X);
2375
+ return;
2376
+ }
2377
+ const res = transformCell(X, yRow[c] ?? null, eff);
2378
+ if (typeof res === "string") {
2379
+ why = res;
2380
+ return;
2381
+ }
2382
+ res.entries.forEach((e, i) => putCell(passes[i] ??= {}, r, c, e));
2383
+ if (res.xLost && !xd) dropped.push(cellRef(sheetOf(x), r, c));
2384
+ if (res.yLost && !yd) lost.push(cellRef(sheetOf(x), r, c));
2385
+ });
2386
+ if (why) return barrier2(why);
2387
+ const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
2388
+ return ok(op, lost, dropped);
2389
+ }
2390
+ var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
2391
+ var isDerived = (m) => m.params.derived === true;
2392
+ function derivedSide(x, y, side) {
2393
+ const xd = isDerived(x);
2394
+ const yd = isDerived(y);
2395
+ return xd === yd ? side : xd ? "right" : "left";
2396
+ }
2397
+ function forApply(m) {
2398
+ if (!SIDE_CAR_PARAMS.some((k) => k in m.params)) return m;
2399
+ const params = { ...m.params };
2400
+ for (const k of SIDE_CAR_PARAMS) delete params[k];
2401
+ return { id: m.id, params };
2402
+ }
2403
+ var refSheetsOf = (m) => m.params.refSheets;
2404
+ var formulaCtx = (m) => ({ ownSheet: sheetOf(m), refSheets: refSheetsOf(m) });
2405
+ function withRefSheets(params, rs) {
2406
+ const out = { ...params };
2407
+ if (rs) out.refSheets = rs;
2408
+ else delete out.refSheets;
2409
+ return out;
2410
+ }
2411
+ var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
2412
+ function hasFormula(m) {
2413
+ let any = false;
2414
+ forEachCell(cellsOf(m), (_r, _c, v) => {
2415
+ any ||= hasFormulaText(v);
2416
+ });
2417
+ return any;
2418
+ }
2419
+ var setNameWithoutPrevious = (m) => m.id === ID.setName && !("previousName" in m.params);
2420
+ function refChangeOf(m) {
2421
+ const st = structuralOf(m);
2422
+ if (st) return { kind: "axis", sheet: sheetOf(m), axis: st.axis, op: st.op };
2423
+ if (m.id === ID.name) return { kind: "rename", sheet: sheetOf(m), name: String(m.params.name) };
2424
+ if (m.id === ID.removeName) return { kind: "defined-name", from: String(m.params.name), to: null };
2425
+ if (m.id === ID.setName && typeof m.params.previousName === "string" && m.params.previousName !== m.params.name)
2426
+ return { kind: "defined-name", from: m.params.previousName, to: String(m.params.name) };
2427
+ return null;
2428
+ }
2429
+ function rewriteEntry(v, ctx, change) {
2430
+ let entry = v;
2431
+ let changed = false;
2432
+ for (const k of ["f", "ref"]) {
2433
+ const t = v[k];
2434
+ if (k === "f" ? !isFormulaText(t) : typeof t !== "string") continue;
2435
+ const r = rewriteFormula(t, ctx, change);
2436
+ if (typeof r === "string") return r;
2437
+ if (!r.changed) continue;
2438
+ if (k === "ref" && r.text.includes(REF_ERROR)) return "an array formula's range was removed under it";
2439
+ entry = { ...entry, [k]: r.text };
2440
+ changed = true;
2441
+ }
2442
+ return { entry, changed };
2443
+ }
2444
+ function cellThrough(sheet, change, r, c) {
2445
+ if (change.kind !== "axis" || change.sheet !== sheet) return [r, c];
2446
+ const nr = change.axis === "row" ? mapIndex(change.op, r) : r;
2447
+ const nc = change.axis === "col" ? mapIndex(change.op, c) : c;
2448
+ return nr === null || nc === null ? null : [nr, nc];
2449
+ }
2450
+ function cellsOverChange(x, change) {
2451
+ const ctx = formulaCtx(x);
2452
+ const out = {};
2453
+ const dropped = [];
2454
+ let why = null;
2455
+ forEachCell(cellsOf(x), (r, c, v) => {
2456
+ if (why) return;
2457
+ const at = cellThrough(sheetOf(x), change, r, c);
2458
+ if (!at) {
2459
+ dropped.push(cellRef(sheetOf(x), r, c));
2460
+ return;
2461
+ }
2462
+ let e = v;
2463
+ if (hasFormulaText(v)) {
2464
+ const res = rewriteEntry(v, ctx, change);
2465
+ if (typeof res === "string") {
2466
+ why = res;
2467
+ return;
2468
+ }
2469
+ e = res.entry;
2470
+ }
2471
+ putCell(out, at[0], at[1], e);
2472
+ });
2473
+ if (why) return barrier2(why);
2474
+ const params = { ...withRefSheets(x.params, refSheetsAfter(ctx.refSheets, change)), cellValue: out };
2475
+ return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
2476
+ }
2477
+ function rewritesOf(y, change) {
2478
+ const ctx = formulaCtx(y);
2479
+ const out = {};
2480
+ let why = null;
2481
+ forEachCell(cellsOf(y), (r, c, v) => {
2482
+ if (why || !hasFormulaText(v)) return;
2483
+ const at = cellThrough(sheetOf(y), change, r, c);
2484
+ if (!at) return;
2485
+ const res = rewriteEntry(v, ctx, change);
2486
+ if (typeof res === "string") {
2487
+ why = res;
2488
+ return;
2489
+ }
2490
+ if (res.changed) putCell(out, at[0], at[1], contentOf(res.entry));
2491
+ });
2492
+ if (why) return why;
2493
+ if (isEmptyMatrix(out)) return null;
2494
+ return { id: ID.values, params: withRefSheets({ subUnitId: sheetOf(y), cellValue: out, derived: true }, refSheetsAfter(ctx.refSheets, change)) };
2495
+ }
2496
+ var NAME_TEXT_KEYS = ["formulaOrRefString", "formulaOrRefStringWithPrefix"];
2497
+ function definedNameThrough(m, change) {
2498
+ if (change.kind === "defined-name" || m.id !== ID.setName) return { op: m, changed: false };
2499
+ const ctx = { ownSheet: change.sheet, refSheets: refSheetsOf(m), keepQualifier: true };
2500
+ const params = { ...m.params };
2501
+ let changed = false;
2502
+ for (const k of NAME_TEXT_KEYS) {
2503
+ if (typeof params[k] !== "string" || !params[k]) continue;
2504
+ const r = rewriteFormula(params[k], ctx, change);
2505
+ if (typeof r === "string") return r;
2506
+ if (r.changed) {
2507
+ params[k] = r.text;
2508
+ changed = true;
2509
+ }
2510
+ }
2511
+ return { op: { id: m.id, params: withRefSheets(params, refSheetsAfter(ctx.refSheets, change)) }, changed };
2512
+ }
2513
+ function asDerived(m) {
2514
+ return { id: m.id, params: { ...m.params, derived: true } };
2515
+ }
2516
+ function formulaPair(x, y, side) {
2517
+ const fx = familyOf(x.id);
2518
+ const fy = familyOf(y.id);
2519
+ const SET_NAME_BARRIER = "set-defined-name without previousName (capture must record the name it replaces) against formula text";
2520
+ if (fx === "defname" && fy === "defname") {
2521
+ if (String(x.params.id) !== String(y.params.id)) return ok([x]);
2522
+ const eff = derivedSide(x, y, side);
2523
+ if (eff === "left") return ok([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
2524
+ return ok([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
2525
+ }
2526
+ if (fx === "defname") {
2527
+ if (fy === "cell") {
2528
+ if (setNameWithoutPrevious(x) && hasFormula(y)) return barrier2(SET_NAME_BARRIER);
2529
+ const ch2 = refChangeOf(x);
2530
+ if (!ch2) return ok([x]);
2531
+ const add = rewritesOf(y, ch2);
2532
+ if (typeof add === "string") return barrier2(add);
2533
+ return ok(add ? [x, add] : [x]);
2534
+ }
2535
+ const ch = refChangeOf(y);
2536
+ if (!ch) return ok([x]);
2537
+ const r = definedNameThrough(x, ch);
2538
+ return typeof r === "string" ? barrier2(r) : ok([r.op]);
2539
+ }
2540
+ if (fy === "defname") {
2541
+ if (fx === "cell") {
2542
+ if (setNameWithoutPrevious(y) && hasFormula(x)) return barrier2(SET_NAME_BARRIER);
2543
+ const ch2 = refChangeOf(y);
2544
+ return ch2 ? cellsOverChange(x, ch2) : ok([x]);
2545
+ }
2546
+ const ch = refChangeOf(x);
2547
+ if (!ch) return ok([x]);
2548
+ const r = definedNameThrough(y, ch);
2549
+ if (typeof r === "string") return barrier2(r);
2550
+ return ok(r.changed ? [x, asDerived(r.op)] : [x]);
2551
+ }
2552
+ if (fx === "cell") {
2553
+ const ch = refChangeOf(y);
2554
+ return ch ? cellsOverChange(x, ch) : null;
2555
+ }
2556
+ if (fy === "cell") {
2557
+ const ch = refChangeOf(x);
2558
+ if (!ch) return null;
2559
+ const lost = [];
2560
+ forEachCell(cellsOf(y), (r, c) => {
2561
+ if (!cellThrough(sheetOf(y), ch, r, c)) lost.push(cellRef(sheetOf(y), r, c));
2562
+ });
2563
+ const add = rewritesOf(y, ch);
2564
+ if (typeof add === "string") return barrier2(add);
2565
+ return ok(add ? [x, add] : [x], lost);
2566
+ }
2567
+ return null;
2568
+ }
2569
+ var withPrevious = (m, definedNames) => m.id === ID.setName && !("previousName" in m.params) ? { id: m.id, params: { ...m.params, previousName: definedNames[String(m.params.id)] ?? null } } : m;
2570
+ function annotateFormulas(group, sheets, definedNames) {
2571
+ let changed = false;
2572
+ return group.map((m0) => {
2573
+ const m = changed && (m0.id === ID.values || m0.id === ID.setName) ? asDerived(m0) : m0;
2574
+ if (!changed && refChangeOf(withPrevious(m0, definedNames))) changed = true;
2575
+ if (m.id === ID.values) {
2576
+ const texts = [];
2577
+ forEachCell(cellsOf(m), (_r, _c, v) => {
2578
+ if (v && isFormulaText(v.f)) texts.push(v.f);
2579
+ if (v && typeof v.ref === "string") texts.push(v.ref);
2580
+ });
2581
+ return { id: m.id, params: withRefSheets(m.params, refSheetsFor(texts, sheets)) };
2582
+ }
2583
+ if (m.id === ID.setName) {
2584
+ const texts = NAME_TEXT_KEYS.map((k) => m.params[k]).filter((t) => typeof t === "string");
2585
+ return { id: m.id, params: { ...withRefSheets(m.params, refSheetsFor(texts, sheets)), previousName: withPrevious(m, definedNames).params.previousName } };
2586
+ }
2587
+ return m;
2588
+ });
2589
+ }
2590
+ function sizeOf(m) {
2591
+ const p = m.params;
2592
+ const values = /* @__PURE__ */ new Map();
2593
+ if (m.id === ID.rowAutoHeight) {
2594
+ for (const { row, autoHeight } of p.rowsAutoHeightInfo ?? []) values.set(row, autoHeight);
2595
+ return { axis: "row", attr: "ah", values };
2596
+ }
2597
+ const axis = m.id === ID.colWidth ? "col" : "row";
2598
+ const field = m.id === ID.colWidth ? "colWidth" : m.id === ID.rowHeight ? "rowHeight" : "autoHeightInfo";
2599
+ const value = p[field];
2600
+ const [a0, a1] = S(axis);
2601
+ for (const r of p.ranges ?? [])
2602
+ for (let i = r[a0]; i <= r[a1]; i++) {
2603
+ if (typeof value === "number") values.set(i, value);
2604
+ else if (m.id === ID.rowIsAuto) values.set(i, value?.[i]);
2605
+ else if (value?.[i] != null) values.set(i, value[i]);
2606
+ }
2607
+ return { axis, attr: m.id === ID.colWidth ? "w" : m.id === ID.rowHeight ? "h" : "ia", values };
2608
+ }
2609
+ function buildSize(template, values) {
2610
+ if (values.size === 0) return null;
2611
+ const p = template.params;
2612
+ if (template.id === ID.rowAutoHeight)
2613
+ return { id: template.id, params: { ...p, rowsAutoHeightInfo: [...values].sort((a, b) => a[0] - b[0]).map(([row, autoHeight]) => ({ row, autoHeight })) } };
2614
+ const axis = template.id === ID.colWidth ? "col" : "row";
2615
+ const field = template.id === ID.colWidth ? "colWidth" : template.id === ID.rowHeight ? "rowHeight" : "autoHeightInfo";
2616
+ const [a0, a1] = S(axis);
2617
+ const first = (p.ranges ?? [])[0] ?? { startRow: 0, endRow: 0, startColumn: 0, endColumn: 0 };
2618
+ const ranges = runs(values.keys()).map((r) => ({ ...first, [a0]: r.start, [a1]: r.start + r.count - 1 }));
2619
+ const uniform = typeof p[field] === "number" ? p[field] : void 0;
2620
+ const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
2621
+ return { id: template.id, params: { ...p, ranges, [field]: value } };
2622
+ }
2623
+ function familyOf(id) {
2624
+ const e = SHEET_MUTATIONS[id];
2625
+ return e && e.kind === "covered" ? e.family : "";
2626
+ }
2627
+ function transformMutation(x, y, side) {
2628
+ for (const m of [x, y]) {
2629
+ const e = SHEET_MUTATIONS[m.id];
2630
+ if (!e) return barrier2(`${m.id} is not in the registry`);
2631
+ if (e.kind !== "covered") return barrier2(`${m.id}: ${e.kind === "barrier" ? `barrier until ${e.until} (${e.reason})` : "never travels"}`);
2632
+ if (m.id === ID.values) {
2633
+ const why = cellBarrier(m);
2634
+ if (why) return barrier2(why);
2635
+ }
2636
+ }
2637
+ const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
2638
+ if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
2639
+ const fp = formulaPair(x, y, side);
2640
+ if (fp) return fp;
2641
+ if (sheetOf(x) !== sheetOf(y)) return ok([x]);
2642
+ const fx = familyOf(x.id);
2643
+ const fy = familyOf(y.id);
2644
+ const sy = structuralOf(y);
2645
+ const sx = structuralOf(x);
2646
+ if (sx && sy) {
2647
+ if (sx.axis !== sy.axis) return ok([x]);
2648
+ const out = transformAxis(sx.op, sy.op, side);
2649
+ if (!out) return barrier2(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);
2650
+ const dropped = out.length === 0 && sx.op.kind === "move" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];
2651
+ return ok(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
2652
+ }
2653
+ if (sy) {
2654
+ if (fx === "merge") {
2655
+ const kept = [];
2656
+ const dropped = [];
2657
+ for (const r of mergeRanges(x)) {
2658
+ const t = mergeThrough(sy, r).range;
2659
+ if (t) kept.push(t);
2660
+ else dropped.push(rangeRef(sheetOf(x), r));
2661
+ }
2662
+ return ok(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
2663
+ }
2664
+ if (fx === "size") {
2665
+ const size = sizeOf(x);
2666
+ if (size.axis !== sy.axis) return ok([x]);
2667
+ const next = /* @__PURE__ */ new Map();
2668
+ for (const [i, v] of size.values) {
2669
+ const m = mapIndex(sy.op, i);
2670
+ if (m !== null) next.set(m, v);
2671
+ }
2672
+ const built = buildSize(x, next);
2673
+ return ok(built ? [built] : []);
2674
+ }
2675
+ return ok([x]);
2676
+ }
2677
+ if (sx) {
2678
+ if (fy !== "merge" || y.id !== ID.addMerge) return ok([x]);
2679
+ const remove = [];
2680
+ const add = [];
2681
+ for (const r of mergeRanges(y)) {
2682
+ const t = mergeThrough(sx, r);
2683
+ if (!t.fixup) continue;
2684
+ remove.push(r);
2685
+ if (t.range) add.push(t.range);
2686
+ }
2687
+ const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));
2688
+ if (!remove.length) return ok([x], lostMerges);
2689
+ const sheet = sheetOf(x);
2690
+ const pre = sx.op.kind === "insert" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];
2691
+ const mid = sx.op.kind === "insert" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];
2692
+ return ok([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
2693
+ }
2694
+ if (fx === "cell" && fy === "cell") return transformCellsOverCells(x, y, side);
2695
+ if (fx === "merge" && fy === "merge") {
2696
+ const xr = mergeRanges(x);
2697
+ const yr = mergeRanges(y);
2698
+ const hit = (r) => yr.some((q) => intersects(r, q));
2699
+ const sheet = sheetOf(x);
2700
+ if (x.id === ID.addMerge && y.id === ID.addMerge) {
2701
+ if (!xr.some(hit)) return ok([x]);
2702
+ if (side === "left") {
2703
+ const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));
2704
+ return ok([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
2705
+ }
2706
+ const kept = xr.filter((r) => !hit(r));
2707
+ return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
2708
+ }
2709
+ if (x.id === ID.addMerge && y.id === ID.removeMerge) {
2710
+ if (side === "left" || !xr.some(hit)) return ok([x], side === "left" && xr.some(hit) ? yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q)) : []);
2711
+ const kept = xr.filter((r) => !hit(r));
2712
+ return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
2713
+ }
2714
+ if (x.id === ID.removeMerge && y.id === ID.addMerge) {
2715
+ const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));
2716
+ if (!touched.length) return ok([x]);
2717
+ if (side === "left") return ok([x], touched.map((q) => rangeRef(sheet, q)));
2718
+ return ok([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
2719
+ }
2720
+ return ok([x]);
2721
+ }
2722
+ if (fx === "size" && fy === "size") {
2723
+ const a = sizeOf(x);
2724
+ const b = sizeOf(y);
2725
+ if (a.axis !== b.axis || a.attr !== b.attr) return ok([x]);
2726
+ if (side === "left") {
2727
+ const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
2728
+ return ok([x], lost);
2729
+ }
2730
+ const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));
2731
+ const built = buildSize(x, next);
2732
+ const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
2733
+ return ok(built ? [built] : [], [], dropped);
2734
+ }
2735
+ if (fx === "name" && fy === "name") {
2736
+ if (side === "left") return ok([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
2737
+ return ok([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
2738
+ }
2739
+ return ok([x]);
2740
+ }
2741
+ var blocked = (p) => !Array.isArray(p);
2742
+ function tSeq(xs, ys, side, acc) {
2743
+ if (xs.length === 0 || ys.length === 0) return [xs, ys];
2744
+ if (xs.length === 1 && ys.length === 1) {
2745
+ const a = transformMutation(xs[0], ys[0], side);
2746
+ if (isBarrier(a)) return a;
2747
+ const b = transformMutation(ys[0], xs[0], flip(side));
2748
+ if (isBarrier(b)) return b;
2749
+ acc.lost.push(...a.lost);
2750
+ acc.dropped.push(...a.dropped);
2751
+ return [a.op, b.op];
2752
+ }
2753
+ if (xs.length > 1) {
2754
+ const first2 = tSeq([xs[0]], ys, side, acc);
2755
+ if (blocked(first2)) return first2;
2756
+ const rest2 = tSeq(xs.slice(1), first2[1], side, acc);
2757
+ if (blocked(rest2)) return rest2;
2758
+ return [[...first2[0], ...rest2[0]], rest2[1]];
2759
+ }
2760
+ const first = tSeq(xs, [ys[0]], side, acc);
2761
+ if (blocked(first)) return first;
2762
+ const rest = tSeq(first[0], ys.slice(1), side, acc);
2763
+ if (blocked(rest)) return rest;
2764
+ return [rest[0], [...first[1], ...rest[1]]];
2765
+ }
2766
+ function transformGroup(x, y, side) {
2767
+ const acc = { lost: [], dropped: [] };
2768
+ const r = tSeq([...x], [...y], side, acc);
2769
+ if (blocked(r)) return r;
2770
+ return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
2771
+ }
2772
+
2773
+ // src/univer/collab/sheets-ot/state-hash.ts
2774
+ var SHEET_LOCAL_SHEET_KEYS = ["zoomRatio", "scrollTop", "scrollLeft", "selections", "__collab"];
2775
+ var SHEET_LOCAL_KEYS = ["id", "rev", "__matrxCollabCovered", "__collab"];
2776
+ function sortDeep2(v) {
2777
+ if (Array.isArray(v)) return v.map(sortDeep2);
2778
+ if (v && typeof v === "object") {
2779
+ const out = {};
2780
+ for (const k of Object.keys(v).sort()) {
2781
+ const x = v[k];
2782
+ if (x === void 0 || x === null) continue;
2783
+ if (Array.isArray(x) && x.length === 0) continue;
2784
+ if (x && typeof x === "object" && !Array.isArray(x) && Object.keys(x).length === 0) continue;
2785
+ out[k] = sortDeep2(x);
2786
+ }
2787
+ return out;
2788
+ }
2789
+ return v;
2790
+ }
2791
+ function parsedResource(data) {
2792
+ if (typeof data !== "string") return data;
2793
+ try {
2794
+ return JSON.parse(data);
2795
+ } catch {
2796
+ return data;
2797
+ }
2798
+ }
2799
+ function canonicalSheet(snapshot) {
2800
+ const s = structuredClone(snapshot ?? {});
2801
+ for (const k of SHEET_LOCAL_KEYS) delete s[k];
2802
+ const styles = s.styles ?? {};
2803
+ const deref = (v) => typeof v === "string" && styles[v] ? sortDeep2(styles[v]) : v;
2804
+ delete s.styles;
2805
+ for (const sheet of Object.values(s.sheets ?? {})) {
2806
+ for (const k of SHEET_LOCAL_SHEET_KEYS) delete sheet[k];
2807
+ if (sheet.defaultStyle) sheet.defaultStyle = deref(sheet.defaultStyle);
2808
+ for (const key of ["rowData", "columnData"]) for (const v of Object.values(sheet[key] ?? {})) if (v?.s) v.s = deref(v.s);
2809
+ const cd = sheet.cellData ?? {};
2810
+ for (const row of Object.keys(cd)) {
2811
+ for (const col of Object.keys(cd[row] ?? {})) {
2812
+ const c = cd[row][col];
2813
+ if (c?.s) c.s = deref(c.s);
2814
+ if (c && (c.f || c.si)) {
2815
+ delete c.v;
2816
+ delete c.t;
2817
+ }
2818
+ if (!c || Object.keys(sortDeep2(c)).length === 0) delete cd[row][col];
2819
+ }
2820
+ if (Object.keys(cd[row] ?? {}).length === 0) delete cd[row];
2821
+ }
2822
+ if (Array.isArray(sheet.mergeData))
2823
+ sheet.mergeData = sheet.mergeData.map((m) => JSON.stringify(sortDeep2(m))).sort().map((j) => JSON.parse(j));
2824
+ }
2825
+ if (Array.isArray(s.resources))
2826
+ s.resources = s.resources.map((r) => ({ name: r.name, data: sortDeep2(parsedResource(r.data)) })).filter((r) => r.data != null && r.data !== "" && !(typeof r.data === "object" && Object.keys(r.data).length === 0)).sort((a, b) => String(a.name).localeCompare(String(b.name)));
2827
+ if (Array.isArray(s.definedNames)) s.definedNames = [...s.definedNames].sort((x, y) => String(x.id).localeCompare(String(y.id)));
2828
+ return sortDeep2(s);
2829
+ }
2830
+ var canonicalSheetString = (snapshot) => JSON.stringify(canonicalSheet(snapshot));
2831
+ async function sheetsStateHash(snapshot) {
2832
+ const bytes = new TextEncoder().encode(canonicalSheetString(snapshot));
2833
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
2834
+ return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("");
2835
+ }
2836
+
2837
+ // src/univer/collab/sheets-ot/room.ts
2838
+ var SHEETS_COLLAB_PROTO = 1;
2839
+ var SHEETS_EDIT_GROUP = "sheets.edit";
2840
+ var flip2 = (side) => side === "left" ? "right" : "left";
2841
+ var isNoopSheetOp = (op) => op == null || op.length === 0;
2842
+ function transformSheetOp(x, y, side) {
2843
+ if (isNoopSheetOp(x) || isNoopSheetOp(y)) return { op: isNoopSheetOp(x) ? null : x, lost: [], dropped: [] };
2844
+ const r = transformGroup(x, y, side);
2845
+ if (isBarrier(r)) return r;
2846
+ const back = transformGroup(y, x, flip2(side));
2847
+ const lost = [.../* @__PURE__ */ new Set([...r.lost, ...isBarrier(back) ? [] : back.dropped])];
2848
+ return { op: r.op.length ? r.op : null, lost, dropped: r.dropped };
2849
+ }
2850
+ function encodeSheetOp(op) {
2851
+ return canonicalKeys([{ cmd: SHEETS_EDIT_GROUP, mutations: (op ?? []).map((m) => ({ id: m.id, params: m.params })) }]);
2852
+ }
2853
+ function decodeSheetOp(groups) {
2854
+ const out = [];
2855
+ for (const g of groups) for (const m of g.mutations) out.push({ id: m.id, params: m.params ?? {} });
2856
+ return out.length ? out : null;
2857
+ }
2858
+ function undoStacksOf2(service) {
2859
+ const s = service;
2860
+ if (!s || !(s._undoStacks instanceof Map) || !(s._redoStacks instanceof Map)) return null;
2861
+ return { undo: s._undoStacks, redo: s._redoStacks };
2862
+ }
2863
+ var CONTENT_TOUCH2 = CONTENT_KEYS.filter((k) => k !== "t");
2864
+ function travelingShape(m) {
2865
+ const params = allowParams(m.id, m.params);
2866
+ if (!params) return null;
2867
+ if (m.params.isOverrideStyle) return null;
2868
+ if (m.id === "sheet.mutation.set-range-values") {
2869
+ const cells = structuredClone(params.cellValue ?? {});
2870
+ for (const row of Object.values(cells))
2871
+ for (const [c, v] of Object.entries(row)) {
2872
+ if (!v) continue;
2873
+ if (typeof v.s === "string") return null;
2874
+ if (!CONTENT_TOUCH2.some((k) => k in v)) continue;
2875
+ const full = {};
2876
+ for (const k of CONTENT_KEYS) full[k] = v[k] !== void 0 ? v[k] : null;
2877
+ if (full.v === null) delete full.t;
2878
+ if ("s" in v) full.s = v.s;
2879
+ row[c] = full;
2880
+ }
2881
+ return { id: m.id, params: { ...params, cellValue: cells } };
2882
+ }
2883
+ return { id: m.id, params };
2884
+ }
2885
+ function rebaseSheetUndoStack(items, remote, unitId) {
2886
+ if (isNoopSheetOp(remote)) return 0;
2887
+ let dropped = 0;
2888
+ for (let i = items.length - 1; i >= 0; i--) {
2889
+ const item = items[i];
2890
+ let ok2 = true;
2891
+ for (const key of ["undoMutations", "redoMutations"]) {
2892
+ const list = item[key];
2893
+ if (!ok2 || !list?.length) continue;
2894
+ const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
2895
+ const operations = list.filter((m) => isOperation(m.id));
2896
+ const shaped = list.filter((m) => !isOperation(m.id)).map(travelingShape);
2897
+ if (shaped.some((m) => m === null)) {
2898
+ ok2 = false;
2899
+ continue;
2900
+ }
2901
+ if (!shaped.length) continue;
2902
+ try {
2903
+ const r = transformGroup(shaped, remote, "left");
2904
+ if (isBarrier(r) || r.op.length === 0) {
2905
+ ok2 = false;
2906
+ continue;
2907
+ }
2908
+ if (JSON.stringify(r.op) === JSON.stringify(shaped)) continue;
2909
+ item[key] = [...r.op.map((m) => ({ id: m.id, params: { ...forApply(m).params, unitId } })), ...operations];
2910
+ } catch {
2911
+ ok2 = false;
2912
+ }
2913
+ }
2914
+ if (!ok2) {
2915
+ items.splice(i, 1);
2916
+ dropped++;
2917
+ }
2918
+ }
2919
+ return dropped;
2920
+ }
2921
+ function createSheetsOtAdapter(port, hooks = {}) {
2922
+ let queue = [];
2923
+ let draining = false;
2924
+ const applyNow = (op) => {
2925
+ for (const m of op) port.applyRemote(m);
2926
+ let dropped = 0;
2927
+ for (const t of port.undoTargets()) {
2928
+ const stacks = undoStacksOf2(t.service);
2929
+ if (!stacks) continue;
2930
+ for (const map of [stacks.undo, stacks.redo]) {
2931
+ const items = map.get(t.unitId);
2932
+ if (items?.length) dropped += rebaseSheetUndoStack(items, op, t.unitId);
2933
+ }
2934
+ }
2935
+ hooks.onUndoRebased?.(dropped);
2936
+ port.markDirty();
2937
+ };
2938
+ const adapter = {
2939
+ version: SHEET_TRANSFORMER_VERSION,
2940
+ transform: (x, y, side) => transformSheetOp(x, y, side),
2941
+ compose: (a, b) => [...a ?? [], ...b ?? []],
2942
+ isNoop: isNoopSheetOp,
2943
+ encode: encodeSheetOp,
2944
+ decode: decodeSheetOp,
2945
+ apply(op) {
2946
+ if (isNoopSheetOp(op)) return true;
2947
+ if (port.busy() || queue.length) {
2948
+ queue.push(op);
2949
+ if (!draining) {
2950
+ draining = true;
2951
+ port.whenIdle(() => {
2952
+ draining = false;
2953
+ const held = queue;
2954
+ queue = [];
2955
+ for (const q of held) applyNow(q);
2956
+ });
2957
+ }
2958
+ return true;
2959
+ }
2960
+ applyNow(op);
2961
+ return true;
2962
+ },
2963
+ async load(snapshot) {
2964
+ queue = [];
2965
+ const current = port.snapshot();
2966
+ if (!(current && snapshot && canonicalSheetString(current) === canonicalSheetString(snapshot))) port.load(snapshot);
2967
+ for (const t of port.undoTargets()) {
2968
+ const stacks = undoStacksOf2(t.service);
2969
+ stacks?.undo.delete(t.unitId);
2970
+ stacks?.redo.delete(t.unitId);
2971
+ }
2972
+ },
2973
+ snapshot: () => port.snapshot(),
2974
+ async hash() {
2975
+ if (port.busy() || queue.length) {
2976
+ await new Promise((resolve) => {
2977
+ const done = setTimeout(resolve, 5e3);
2978
+ port.whenIdle(() => {
2979
+ clearTimeout(done);
2980
+ setTimeout(resolve, 0);
2981
+ });
2982
+ });
2983
+ }
2984
+ return sheetsStateHash(port.snapshot());
2985
+ },
2986
+ held: () => queue.length,
2987
+ rebaseLocalOverHeld(local) {
2988
+ let op = local;
2989
+ const next = [];
2990
+ for (const q of queue) {
2991
+ const l2 = transformSheetOp(op, q, "left");
2992
+ const q2 = transformSheetOp(q, op, "right");
2993
+ if ("barrier" in l2 || "barrier" in q2) return "barrier";
2994
+ op = l2.op ?? [];
2995
+ if (q2.op?.length) next.push(q2.op);
2996
+ }
2997
+ queue = next;
2998
+ return op;
2999
+ },
3000
+ clearHeld() {
3001
+ queue = [];
3002
+ }
3003
+ };
3004
+ return adapter;
3005
+ }
3006
+ function openSheetsOtRoom(o) {
3007
+ const { port } = o;
3008
+ let session = null;
3009
+ const adapter = createSheetsOtAdapter(port);
3010
+ const notice = (n) => {
3011
+ try {
3012
+ o.onNotice?.(n);
3013
+ } catch (err) {
3014
+ console.warn("[sheets-ot] notice handler failed", err);
3015
+ }
3016
+ };
3017
+ const onLocal = (e) => {
3018
+ if (!session) return;
3019
+ if (e.kind === "not_shared") {
3020
+ notice({ kind: "not_shared", mutationId: e.mutationId });
3021
+ adapter.clearHeld();
3022
+ session.rebuild(`not_shared:${e.mutationId}`);
3023
+ return;
3024
+ }
3025
+ if (!e.mutations.length) return;
3026
+ for (const m of e.mutations) {
3027
+ if (SHEET_MUTATIONS[m.id]?.kind !== "covered") {
3028
+ notice({ kind: "not_shared", mutationId: m.id });
3029
+ adapter.clearHeld();
3030
+ session.rebuild(`not_shared:${m.id}`);
3031
+ return;
3032
+ }
3033
+ }
3034
+ let op = e.mutations;
3035
+ let inverse = e.inverse;
3036
+ if (adapter.held()) {
3037
+ inverse = void 0;
3038
+ const r = adapter.rebaseLocalOverHeld(op);
3039
+ if (r === "barrier") {
3040
+ adapter.clearHeld();
3041
+ session.rebuild("held_barrier");
3042
+ return;
3043
+ }
3044
+ op = r;
3045
+ if (!op.length) return;
3046
+ }
3047
+ if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: e.label ?? SHEETS_EDIT_GROUP })) notice({ kind: "not_live" });
3048
+ };
3049
+ const unsubLocal = port.onLocal(onLocal);
3050
+ session = (0, import_collab5.openOpSession)({
3051
+ transport: o.transport,
3052
+ adapter,
3053
+ proto: SHEETS_COLLAB_PROTO,
3054
+ clientId: o.clientId,
3055
+ ...o.presence ? { presence: o.presence } : {},
3056
+ onNotice: (n) => notice(n),
3057
+ ...o.onIncident ? { onIncident: o.onIncident } : {},
3058
+ ...o.onStatus ? { onStatus: o.onStatus } : {}
3059
+ });
3060
+ const isSaver = () => {
3061
+ if (!o.presence) return true;
3062
+ return o.presence.peers().every((p) => p.clientId === o.clientId || p.clientId > o.clientId);
3063
+ };
3064
+ return {
3065
+ session,
3066
+ isSaver,
3067
+ async write(reason) {
3068
+ if (!session) return false;
3069
+ if (reason !== "manual" && !isSaver()) return false;
3070
+ const out = await session.save();
3071
+ if (out.saved) return true;
3072
+ if (out.reason === "not_quiet" || out.reason === "changed") setTimeout(() => port.markDirty(), 1500);
3073
+ return false;
3074
+ },
3075
+ async replace(snapshot) {
3076
+ port.load(snapshot);
3077
+ const loaded = port.snapshot();
3078
+ if (!loaded) throw new Error("The workbook is not open in this tab.");
3079
+ const stateHash = await sheetsStateHash(loaded);
3080
+ await o.replace({ snapshot: loaded, stateHash, clientId: o.clientId });
3081
+ },
3082
+ stop() {
3083
+ unsubLocal();
3084
+ session?.close();
3085
+ }
3086
+ };
3087
+ }
3088
+
3089
+ // src/univer/collab/sheets-ot/univer-port.ts
3090
+ var COMMAND = 0;
3091
+ var MUTATION = 2;
3092
+ var VALUES = "sheet.mutation.set-range-values";
3093
+ var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
3094
+ var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
3095
+ var SHEET_NAME = "sheet.mutation.set-worksheet-name";
3096
+ var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
3097
+ var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
3098
+ var flagged = (options) => {
3099
+ const o = options;
3100
+ return !!(o?.onlyLocal || o?.fromCollab);
3101
+ };
3102
+ function univerSheetsOtPort(o) {
3103
+ const cs = o.commandService;
3104
+ const listeners = /* @__PURE__ */ new Set();
3105
+ const idle = [];
3106
+ const pre = /* @__PURE__ */ new WeakMap();
3107
+ const tracker = { stack: [], settle: () => settle() };
3108
+ let group = null;
3109
+ let applying = false;
3110
+ const unitId = () => o.workbook()?.getUnitId() ?? null;
3111
+ const mine = (params) => {
3112
+ const u = unitId();
3113
+ return !!u && !!params && typeof params === "object" && params.unitId === u;
3114
+ };
3115
+ const styleObject = (s) => {
3116
+ if (typeof s !== "string") return s;
3117
+ const found = o.workbook()?.getStyles().get(s);
3118
+ return found ? json(found) : s;
3119
+ };
3120
+ const sheetNames = () => {
3121
+ const out = {};
3122
+ for (const ws of o.workbook()?.getSheets() ?? []) out[ws.getSheetId()] = ws.getName();
3123
+ return out;
3124
+ };
3125
+ const definedNames = () => {
3126
+ const u = unitId();
3127
+ const map = u && o.definedNames?.(u) || {};
3128
+ const out = {};
3129
+ for (const [id, d] of Object.entries(map)) out[id] = String(d?.name ?? "");
3130
+ return out;
3131
+ };
3132
+ const openGroup = (label) => ({ label, sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
3133
+ const emit = (e) => {
3134
+ for (const l of [...listeners]) {
3135
+ try {
3136
+ l(e);
3137
+ } catch (err) {
3138
+ console.warn("[sheets-ot] local change handler failed", err);
3139
+ }
3140
+ }
3141
+ };
3142
+ const flush = () => {
3143
+ const g = group;
3144
+ group = null;
3145
+ if (!g) return;
3146
+ if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
3147
+ else if (g.mutations.length) {
3148
+ const mutations = annotateFormulas(g.mutations, g.sheets, g.names);
3149
+ const known = g.inverses.every((i) => i !== void 0);
3150
+ const inverse = known ? annotateFormulas(g.inverses.slice().reverse().flat(), g.sheets, g.names) : void 0;
3151
+ emit({ kind: "group", mutations, ...inverse !== void 0 ? { inverse } : {}, label: g.label });
3152
+ }
3153
+ };
3154
+ function settle() {
3155
+ if (tracker.stack.length === 0) flush();
3156
+ if (tracker.stack.length === 0 && !group) for (const fn of idle.splice(0)) fn();
3157
+ }
3158
+ const before = cs.beforeCommandExecuted((info, options) => {
3159
+ if (info.type === COMMAND) {
3160
+ if (tracker.stack.length === 0 && !group) group = openGroup(info.id);
3161
+ tracker.stack.push(info.id);
3162
+ return;
3163
+ }
3164
+ if (info.type !== MUTATION || applying || flagged(options) || !mine(info.params)) return;
3165
+ const p = info.params;
3166
+ const ws = o.workbook()?.getSheetBySheetId(String(p.subUnitId ?? ""));
3167
+ if (!ws) return;
3168
+ const record = { merges: json(ws.getMergeData() ?? []) };
3169
+ if (info.id === VALUES) {
3170
+ record.cells = /* @__PURE__ */ new Map();
3171
+ const cells = p.cellValue ?? {};
3172
+ for (const r of Object.keys(cells))
3173
+ for (const c of Object.keys(cells[r] ?? {})) {
3174
+ const raw = ws.getCellRaw(Number(r), Number(c));
3175
+ const copy = raw ? json(raw) : null;
3176
+ if (copy && "s" in copy) copy.s = styleObject(copy.s);
3177
+ record.cells.set(`${r}:${c}`, copy);
3178
+ }
3179
+ }
3180
+ if (info.id === SHEET_NAME) record.name = ws.getName();
3181
+ pre.set(p, record);
3182
+ });
3183
+ const after = cs.onCommandExecuted((info) => {
3184
+ if (info.type !== COMMAND) return;
3185
+ const at = tracker.stack.lastIndexOf(info.id);
3186
+ if (at >= 0) tracker.stack.splice(at, 1);
3187
+ settle();
3188
+ });
3189
+ const guarded = cs;
3190
+ if (!guarded[DEPTH_GUARD] && typeof cs.executeCommand === "function") {
3191
+ const trackers = /* @__PURE__ */ new Set();
3192
+ guarded[DEPTH_GUARD] = trackers;
3193
+ const original = cs.executeCommand.bind(cs);
3194
+ cs.executeCommand = async (id, params, options) => {
3195
+ const depths = new Map([...trackers].map((t) => [t, t.stack.length]));
3196
+ try {
3197
+ return await original(id, params, options);
3198
+ } finally {
3199
+ for (const [t, d] of depths) {
3200
+ if (t.stack.length > d) {
3201
+ t.stack.length = d;
3202
+ t.settle();
3203
+ }
3204
+ }
3205
+ }
3206
+ };
3207
+ }
3208
+ guarded[DEPTH_GUARD]?.add(tracker);
3209
+ const capture = (info) => {
3210
+ const entry = SHEET_MUTATIONS[info.id];
3211
+ if (!entry) {
3212
+ console.warn(`[sheets-ot] ${info.id} is not in the sheet mutation registry; it cannot be shared`);
3213
+ return { m: null, inverse: void 0, notShared: info.id };
3214
+ }
3215
+ if (entry.kind === "never-travels") return { m: null, inverse: void 0 };
3216
+ if (entry.kind === "barrier") return { m: null, inverse: void 0, notShared: info.id };
3217
+ const raw = json(info.params);
3218
+ const before2 = pre.get(info.params) ?? {};
3219
+ const params = allowParams(info.id, raw);
3220
+ if (!params) return { m: null, inverse: void 0, notShared: info.id };
3221
+ const sheet = String(params.subUnitId ?? "");
3222
+ const ws = o.workbook()?.getSheetBySheetId(sheet);
3223
+ if (info.id === VALUES) {
3224
+ const cells = params.cellValue ?? {};
3225
+ const invCells = {};
3226
+ let invKnown = !!before2.cells;
3227
+ for (const r of Object.keys(cells))
3228
+ for (const c of Object.keys(cells[r] ?? {})) {
3229
+ let e = cells[r][c] ?? null;
3230
+ const p = before2.cells?.get(`${r}:${c}`) ?? null;
3231
+ if (e && "s" in e) {
3232
+ e = { ...e, s: styleObject(e.s) };
3233
+ if (raw.isOverrideStyle) {
3234
+ const next = e.s && typeof e.s === "object" ? e.s : {};
3235
+ const prev = p?.s && typeof p.s === "object" ? p.s : {};
3236
+ const merged = { ...next };
3237
+ for (const k of Object.keys(prev)) if (!(k in next)) merged[k] = null;
3238
+ e.s = Object.keys(merged).length ? merged : null;
3239
+ }
3240
+ }
3241
+ const post = ws?.getCellRaw(Number(r), Number(c)) ?? null;
3242
+ const done = completeCellContent(e, post ? json(post) : null);
3243
+ cells[r][c] = done;
3244
+ if (!invKnown) continue;
3245
+ let inv;
3246
+ if (done === null) inv = p ? { ...fullContent(p), ...p.s !== void 0 ? { s: p.s } : {} } : null;
3247
+ else {
3248
+ inv = {};
3249
+ if (CONTENT_KEYS.some((k) => k !== "t" && k in done)) Object.assign(inv, fullContent(p));
3250
+ if ("s" in done) inv.s = p?.s ?? null;
3251
+ }
3252
+ (invCells[r] ??= {})[c] = inv;
3253
+ }
3254
+ return {
3255
+ m: { id: info.id, params: { ...params, cellValue: cells } },
3256
+ inverse: invKnown ? [{ id: VALUES, params: { subUnitId: sheet, cellValue: invCells } }] : void 0
3257
+ };
3258
+ }
3259
+ if (info.id === REMOVE_MERGE) {
3260
+ const exact = exactMergeRemovals([{ id: info.id, params }], { [sheet]: before2.merges ?? ws?.getMergeData() ?? [] });
3261
+ const m2 = exact[0] ?? null;
3262
+ if (!m2) return { m: null, inverse: void 0 };
3263
+ return { m: m2, inverse: [{ id: ADD_MERGE, params: { subUnitId: sheet, ranges: json(m2.params.ranges) } }] };
3264
+ }
3265
+ const m = { id: info.id, params };
3266
+ switch (info.id) {
3267
+ case "sheet.mutation.insert-row":
3268
+ return { m, inverse: [{ id: "sheet.mutation.remove-rows", params: { subUnitId: sheet, range: json(params.range) } }] };
3269
+ case "sheet.mutation.insert-col":
3270
+ return { m, inverse: [{ id: "sheet.mutation.remove-col", params: { subUnitId: sheet, range: json(params.range) } }] };
3271
+ case ADD_MERGE:
3272
+ return { m, inverse: [{ id: REMOVE_MERGE, params: { subUnitId: sheet, ranges: json(params.ranges) } }] };
3273
+ case SHEET_NAME:
3274
+ return { m, inverse: before2.name !== void 0 ? [{ id: SHEET_NAME, params: { subUnitId: sheet, name: before2.name } }] : void 0 };
3275
+ default:
3276
+ return { m, inverse: void 0 };
3277
+ }
3278
+ };
3279
+ const collab = cs.onMutationExecutedForCollab((info, options) => {
3280
+ if (applying || flagged(options) || !mine(info.params)) return;
3281
+ const lone = !group;
3282
+ if (lone) group = openGroup(null);
3283
+ const g = group;
3284
+ if (!g.notShared) {
3285
+ const r = capture(info);
3286
+ if (r.notShared) g.notShared = r.notShared;
3287
+ else if (r.m) {
3288
+ g.mutations.push(r.m);
3289
+ g.inverses.push(r.inverse);
3290
+ }
3291
+ }
3292
+ if (lone && tracker.stack.length === 0) settle();
3293
+ });
3294
+ return {
3295
+ onLocal(listener) {
3296
+ listeners.add(listener);
3297
+ return () => void listeners.delete(listener);
3298
+ },
3299
+ busy: () => tracker.stack.length > 0 || group !== null,
3300
+ whenIdle(fn) {
3301
+ if (tracker.stack.length === 0 && !group) fn();
3302
+ else idle.push(fn);
3303
+ },
3304
+ applyRemote(m) {
3305
+ const u = unitId();
3306
+ if (!u) throw new Error("no workbook is mounted");
3307
+ const a = forApply(m);
3308
+ applying = true;
3309
+ try {
3310
+ const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { onlyLocal: true, fromCollab: true });
3311
+ if (ok2 === false) throw new Error(`"${m.id}" was refused by the editor`);
3312
+ } finally {
3313
+ applying = false;
3314
+ }
3315
+ },
3316
+ snapshot() {
3317
+ const wb = o.workbook();
3318
+ if (!wb) return null;
3319
+ const saved = o.saveUnit?.(wb.getUnitId()) ?? wb.getSnapshot();
3320
+ return saved ? json(saved) : null;
3321
+ },
3322
+ load(snapshot) {
3323
+ group = null;
3324
+ applying = true;
3325
+ try {
3326
+ o.load(snapshot);
3327
+ } finally {
3328
+ applying = false;
3329
+ }
3330
+ },
3331
+ undoTargets() {
3332
+ const u = unitId();
3333
+ const service = o.undoRedo?.();
3334
+ return u && service ? [{ service, unitId: u }] : [];
3335
+ },
3336
+ markDirty: () => o.markDirty(),
3337
+ dispose() {
3338
+ before.dispose();
3339
+ after.dispose();
3340
+ collab.dispose();
3341
+ guarded[DEPTH_GUARD]?.delete(tracker);
3342
+ listeners.clear();
3343
+ }
3344
+ };
3345
+ }
3346
+ function fullContent(cell) {
3347
+ const out = {};
3348
+ for (const k of CONTENT_KEYS) out[k] = cell && cell[k] !== void 0 ? cell[k] : null;
3349
+ if (out.v === null) delete out.t;
3350
+ return out;
3351
+ }
3352
+
3353
+ // src/sheets/workbook-ot-room.ts
3354
+ var Y3 = __toESM(require("yjs"), 1);
3355
+ var import_awareness3 = require("y-protocols/awareness");
3356
+ var import_collab6 = require("@ai-matrx/data/realtime/collab");
3357
+
3358
+ // src/sheets/ports.ts
3359
+ var SLOT2 = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets-host");
3360
+ var slot2 = () => {
3361
+ const g = globalThis;
3362
+ return g[SLOT2] ??= {};
3363
+ };
3364
+ function getSheetsHost() {
3365
+ const ports = slot2().ports;
3366
+ if (!ports) throw new Error("@ai-matrx/office/sheets: configureSheetsHost(ports) was not called before the workbook service ran.");
3367
+ return ports;
3368
+ }
3369
+
3370
+ // src/sheets/workbook-service.ts
3371
+ var import_api2 = require("@ai-matrx/api");
3372
+ var import_auth2 = require("@ai-matrx/auth");
3373
+ var import_db2 = require("@ai-matrx/data/db");
3374
+ var db3 = () => getSheetsHost().getSupabase();
3375
+ async function getLatestSnapshot(workbookId) {
3376
+ const { data, error } = await db3().schema("workbench").from("udt_workbook_snapshots").select("*").eq("workbook_id", workbookId).order("created_at", { ascending: false }).limit(1).maybeSingle();
3377
+ if (error) return { success: false, error: error.message };
3378
+ return { success: true, data: data ?? null };
3379
+ }
3380
+ async function saveSnapshot(args) {
3381
+ const { data: userData } = await (0, import_auth2.getClaimsUser)(db3());
3382
+ const { data: workbook, error: workbookError } = await db3().schema("workbench").from("udt_workbooks").select("organization_id").eq("id", args.workbookId).single();
3383
+ if (workbookError) return { success: false, error: workbookError.message };
3384
+ const { data, error } = await db3().schema("workbench").from("udt_workbook_snapshots").insert({
3385
+ organization_id: workbook.organization_id,
3386
+ workbook_id: args.workbookId,
3387
+ snapshot: args.snapshot,
3388
+ label: args.label ?? null,
3389
+ origin: args.origin ?? "autosave",
3390
+ created_by: userData?.user?.id ?? null
3391
+ }).select("*").single();
3392
+ if (error) return { success: false, error: error.message };
3393
+ await db3().schema("workbench").from("udt_workbooks").update({ updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", args.workbookId);
3394
+ return { success: true, data };
3395
+ }
3396
+
3397
+ // src/sheets/workbook-ot-room.ts
3398
+ var db4 = () => getSheetsHost().getSupabase();
3399
+ async function loadSnapshotRow2(workbookId, ref) {
3400
+ if (ref === "none") {
3401
+ const res = await getLatestSnapshot(workbookId);
3402
+ if (!res.success) throw new Error(res.error);
3403
+ return res.data?.snapshot ?? null;
3404
+ }
3405
+ const { data, error } = await getSheetsHost().getSupabase().schema("workbench").from("udt_workbook_snapshots").select("snapshot").eq("id", ref).maybeSingle();
3406
+ if (error) throw new Error(error.message);
3407
+ if (!data) throw new Error(`The saved version ${ref} of this workbook is missing.`);
3408
+ return data.snapshot ?? null;
3409
+ }
3410
+ async function workbookUsesOrderedRoom(workbookId, knob, isNewWorkbook) {
3411
+ try {
3412
+ if (await (0, import_collab6.collabRoomExists)(db4(), workbookId)) return true;
3413
+ } catch (err) {
3414
+ console.warn("[workbook] could not ask whether this workbook has a co-editing room; opening the relay room", err);
3415
+ return false;
3416
+ }
3417
+ if (knob === "all") return true;
3418
+ if (knob === "new") return isNewWorkbook();
3419
+ return false;
3420
+ }
3421
+ function pickColor3(uid) {
3422
+ const palette = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6", "#f97316"];
3423
+ let h = 2166136261;
3424
+ for (let i = 0; i < uid.length; i++) {
3425
+ h ^= uid.charCodeAt(i);
3426
+ h = Math.imul(h, 16777619);
3427
+ }
3428
+ return palette[Math.abs(h) % palette.length] ?? "#ec4899";
3429
+ }
3430
+ async function startWorkbookOtRoom(port, o) {
3431
+ const latest = await getLatestSnapshot(o.workbookId);
3432
+ if (!latest.success) throw new Error(latest.error);
3433
+ if (!latest.data) {
3434
+ const mounted = port.snapshot();
3435
+ if (mounted) {
3436
+ const saved = await saveSnapshot({ workbookId: o.workbookId, snapshot: mounted, origin: "autosave" });
3437
+ if (!saved.success) throw new Error(saved.error);
3438
+ }
3439
+ }
3440
+ const doc = new Y3.Doc();
3441
+ const awareness = new import_awareness3.Awareness(doc);
3442
+ awareness.setLocalState({
3443
+ uid: o.uid,
3444
+ clientId: o.clientId,
3445
+ name: o.displayName ?? o.uid.slice(0, 8),
3446
+ color: pickColor3(o.uid),
3447
+ sheetId: null,
3448
+ row: null,
3449
+ col: null,
3450
+ ts: Date.now()
3451
+ });
3452
+ const publishAwareness = () => o.onAwareness?.(new Map(awareness.getStates()));
3453
+ awareness.on("change", publishAwareness);
3454
+ const provider = new import_collab6.SupabaseYjsProvider({
3455
+ workbookId: o.workbookId,
3456
+ clientId: o.clientId,
3457
+ doc,
3458
+ awareness,
3459
+ ...o.readAntiEntropyIntervalMs ? { readAntiEntropyIntervalMs: o.readAntiEntropyIntervalMs } : {}
3460
+ });
3461
+ await provider.connect();
3462
+ publishAwareness();
3463
+ const client = db4();
3464
+ const room = openSheetsOtRoom({
3465
+ port,
3466
+ clientId: o.clientId,
3467
+ presence: (0, import_collab6.awarenessOpPresence)(awareness),
3468
+ transport: (0, import_collab6.supabaseOpTransport)({
3469
+ client,
3470
+ roomId: o.workbookId,
3471
+ kind: "univer_sheet",
3472
+ store: {
3473
+ loadSnapshot: (ref) => loadSnapshotRow2(o.workbookId, ref),
3474
+ async writeSnapshot(snapshot) {
3475
+ const res = await saveSnapshot({ workbookId: o.workbookId, snapshot, origin: "autosave" });
3476
+ if (!res.success) throw new Error(res.error);
3477
+ return res.data.id;
3478
+ }
3479
+ }
3480
+ }),
3481
+ replace: ({ snapshot, stateHash, clientId }) => (0, import_collab6.collabReplace)(client, { roomId: o.workbookId, snapshot, stateHash, origin: "restore", clientId }),
3482
+ ...o.onNotice ? { onNotice: o.onNotice } : {},
3483
+ ...o.onIncident ? { onIncident: o.onIncident } : {},
3484
+ ...o.onStatus ? { onStatus: o.onStatus } : {}
3485
+ });
3486
+ await room.session.ready;
3487
+ return {
3488
+ session: room.session,
3489
+ isSaver: () => room.isSaver(),
3490
+ write: (reason) => room.write(reason),
3491
+ replace: (snapshot) => room.replace(snapshot),
3492
+ setCursor(c) {
3493
+ const current = awareness.getLocalState() ?? {};
3494
+ awareness.setLocalState({ ...current, sheetId: c.sheetId, row: c.row, col: c.col, ts: Date.now() });
3495
+ },
3496
+ stop() {
3497
+ room.stop();
3498
+ port.dispose?.();
3499
+ awareness.off("change", publishAwareness);
3500
+ provider.disconnect();
3501
+ awareness.destroy();
3502
+ doc.destroy();
3503
+ }
3504
+ };
3505
+ }
1611
3506
  //# sourceMappingURL=univer-collab.cjs.map