@ai-matrx/office 0.8.20 → 0.8.22

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.
@@ -24,6 +24,15 @@ var SHEET_MUTATIONS = {
24
24
  "sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
25
25
  "sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
26
26
  "sheet.mutation.set-worksheet-name": covered("name", "name"),
27
+ // ── covered (C5c) ────────────────────────────────────────────────────────────────────────────────
28
+ "sheet.mutation.set.numfmt": covered("numfmt", "values", "refMap"),
29
+ "sheet.mutation.remove.numfmt": covered("numfmt", "ranges"),
30
+ "sheet.mutation.set-worksheet-row-count": covered("count", "rowCount"),
31
+ "sheet.mutation.set-worksheet-column-count": covered("count", "columnCount"),
32
+ "sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
33
+ "sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
34
+ "sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
35
+ "sheet.mutation.reorder-range": covered("sort", "range", "order"),
27
36
  // ── never travels ────────────────────────────────────────────────────────────────────────────────
28
37
  "formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
29
38
  "formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
@@ -57,13 +66,7 @@ var SHEET_MUTATIONS = {
57
66
  "thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
58
67
  "thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
59
68
  // ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
60
- "sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
61
- "sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
62
- "sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
63
- "sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
64
69
  "sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
65
- "sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
66
- "sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
67
70
  "sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
68
71
  "sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
69
72
  "sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
@@ -78,8 +81,6 @@ var SHEET_MUTATIONS = {
78
81
  "sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
79
82
  "sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
80
83
  "sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
81
- "sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
82
- "sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
83
84
  "sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
84
85
  "sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
85
86
  "sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
@@ -483,7 +484,7 @@ function refSheetsFor(texts, sheets) {
483
484
  }
484
485
 
485
486
  // src/collab/sheets/transform/transform.ts
486
- var SHEET_TRANSFORMER_VERSION = "c5b-1";
487
+ var SHEET_TRANSFORMER_VERSION = "c5c-1";
487
488
  var ID = {
488
489
  values: "sheet.mutation.set-range-values",
489
490
  insertRow: "sheet.mutation.insert-row",
@@ -500,7 +501,15 @@ var ID = {
500
501
  colWidth: "sheet.mutation.set-worksheet-col-width",
501
502
  name: "sheet.mutation.set-worksheet-name",
502
503
  setName: "formula.mutation.set-defined-name",
503
- removeName: "formula.mutation.remove-defined-name"
504
+ removeName: "formula.mutation.remove-defined-name",
505
+ setNumfmt: "sheet.mutation.set.numfmt",
506
+ removeNumfmt: "sheet.mutation.remove.numfmt",
507
+ rowCount: "sheet.mutation.set-worksheet-row-count",
508
+ colCount: "sheet.mutation.set-worksheet-column-count",
509
+ insertSheet: "sheet.mutation.insert-sheet",
510
+ removeSheet: "sheet.mutation.remove-sheet",
511
+ sheetOrder: "sheet.mutation.set-worksheet-order",
512
+ sort: "sheet.mutation.reorder-range"
504
513
  };
505
514
  var PAIR_BARRIERS = {};
506
515
  var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
@@ -612,6 +621,20 @@ function mergeThrough(s, m) {
612
621
  }
613
622
  return { range: m, fixup: false };
614
623
  }
624
+ function mergeFixupsOwed(m, mergesBefore) {
625
+ const st = structuralOf(m);
626
+ if (!st) return null;
627
+ const remove = [];
628
+ const add = [];
629
+ for (const q of mergesBefore) {
630
+ const t = mergeThrough(st, q);
631
+ if (!t.fixup) continue;
632
+ remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
633
+ if (t.range) add.push({ ...t.range });
634
+ }
635
+ return remove.length ? { remove, add } : null;
636
+ }
637
+ var isStructuralMutation = (m) => structuralOf(m) !== null;
615
638
  function exactMergeRemovals(group, merges) {
616
639
  const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
617
640
  const out = [];
@@ -658,8 +681,24 @@ function cellsMutation(template, cells) {
658
681
  function putCell(cells, r, c, v) {
659
682
  (cells[r] ??= {})[c] = v;
660
683
  }
684
+ function cellsOverlap(a, b) {
685
+ for (const r of Object.keys(a)) {
686
+ const br = b[r];
687
+ if (!br) continue;
688
+ for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
689
+ }
690
+ return false;
691
+ }
661
692
  var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
693
+ var cellBarrierCache = /* @__PURE__ */ new WeakMap();
662
694
  function cellBarrier(m) {
695
+ const hit = cellBarrierCache.get(m);
696
+ if (hit !== void 0) return hit;
697
+ const why = cellBarrierOf(m);
698
+ cellBarrierCache.set(m, why);
699
+ return why;
700
+ }
701
+ function cellBarrierOf(m) {
663
702
  if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
664
703
  let why = null;
665
704
  forEachCell(cellsOf(m), (_r, _c, v) => {
@@ -741,6 +780,7 @@ function transformCell(X, Y, side) {
741
780
  function transformCellsOverCells(x, y, side) {
742
781
  if (sheetOf(x) !== sheetOf(y)) return ok([x]);
743
782
  const ycells = cellsOf(y);
783
+ if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
744
784
  const xd = isDerived(x);
745
785
  const yd = isDerived(y);
746
786
  const eff = derivedSide(x, y, side);
@@ -768,7 +808,7 @@ function transformCellsOverCells(x, y, side) {
768
808
  const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
769
809
  return ok(op, lost, dropped);
770
810
  }
771
- var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
811
+ var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
772
812
  var isDerived = (m) => m.params.derived === true;
773
813
  function derivedSide(x, y, side) {
774
814
  const xd = isDerived(x);
@@ -790,7 +830,15 @@ function withRefSheets(params, rs) {
790
830
  return out;
791
831
  }
792
832
  var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
833
+ var hasFormulaCache = /* @__PURE__ */ new WeakMap();
793
834
  function hasFormula(m) {
835
+ const hit = hasFormulaCache.get(m);
836
+ if (hit !== void 0) return hit;
837
+ const any = hasFormulaOf(m);
838
+ hasFormulaCache.set(m, any);
839
+ return any;
840
+ }
841
+ function hasFormulaOf(m) {
794
842
  let any = false;
795
843
  forEachCell(cellsOf(m), (_r, _c, v) => {
796
844
  any ||= hasFormulaText(v);
@@ -829,15 +877,18 @@ function cellThrough(sheet, change, r, c) {
829
877
  return nr === null || nc === null ? null : [nr, nc];
830
878
  }
831
879
  function cellsOverChange(x, change) {
880
+ if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
832
881
  const ctx = formulaCtx(x);
833
882
  const out = {};
834
883
  const dropped = [];
835
884
  let why = null;
885
+ let changed = false;
836
886
  forEachCell(cellsOf(x), (r, c, v) => {
837
887
  if (why) return;
838
888
  const at = cellThrough(sheetOf(x), change, r, c);
839
889
  if (!at) {
840
890
  dropped.push(cellRef(sheetOf(x), r, c));
891
+ changed = true;
841
892
  return;
842
893
  }
843
894
  let e = v;
@@ -848,14 +899,19 @@ function cellsOverChange(x, change) {
848
899
  return;
849
900
  }
850
901
  e = res.entry;
902
+ if (res.changed) changed = true;
851
903
  }
904
+ if (at[0] !== r || at[1] !== c) changed = true;
852
905
  putCell(out, at[0], at[1], e);
853
906
  });
854
907
  if (why) return barrier2(why);
855
- const params = { ...withRefSheets(x.params, refSheetsAfter(ctx.refSheets, change)), cellValue: out };
908
+ const rsAfter = refSheetsAfter(ctx.refSheets, change);
909
+ if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
910
+ const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
856
911
  return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
857
912
  }
858
913
  function rewritesOf(y, change) {
914
+ if (!hasFormula(y)) return null;
859
915
  const ctx = formulaCtx(y);
860
916
  const out = {};
861
917
  let why = null;
@@ -1001,6 +1057,368 @@ function buildSize(template, values) {
1001
1057
  const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
1002
1058
  return { id: template.id, params: { ...p, ranges, [field]: value } };
1003
1059
  }
1060
+ var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
1061
+ function nfParts(m) {
1062
+ if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
1063
+ const values = m.params.values ?? {};
1064
+ return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
1065
+ }
1066
+ function nfBuild(m, parts) {
1067
+ const keep = parts.filter((p) => p.ranges.length);
1068
+ if (!keep.length) return [];
1069
+ if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
1070
+ const values = {};
1071
+ const refMap = {};
1072
+ const srcValues = m.params.values ?? {};
1073
+ const srcRef = m.params.refMap ?? {};
1074
+ for (const p of keep) {
1075
+ values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
1076
+ refMap[p.key] = srcRef[p.key];
1077
+ }
1078
+ return [{ id: m.id, params: { ...m.params, values, refMap } }];
1079
+ }
1080
+ function nfValueAt(m, row, col) {
1081
+ for (const p of nfParts(m))
1082
+ if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
1083
+ if (p.key === null) return null;
1084
+ const ref = (m.params.refMap ?? {})[p.key];
1085
+ return { pattern: ref?.pattern };
1086
+ }
1087
+ return void 0;
1088
+ }
1089
+ function spanThrough(op, lo, hi) {
1090
+ const pieces = [];
1091
+ if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
1092
+ else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
1093
+ else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
1094
+ else if (op.to > op.from) {
1095
+ const n = op.count;
1096
+ pieces.push([0, op.from - 1, 0], [op.from, op.from + n - 1, op.to - n - op.from], [op.from + n, op.to - 1, -n], [op.to, Infinity, 0]);
1097
+ } else {
1098
+ const n = op.count;
1099
+ pieces.push([0, op.to - 1, 0], [op.to, op.from - 1, n], [op.from, op.from + n - 1, op.to - op.from], [op.from + n, Infinity, 0]);
1100
+ }
1101
+ const out = [];
1102
+ for (const [a, b, d] of pieces) {
1103
+ const x0 = Math.max(a, lo);
1104
+ const x1 = Math.min(b, hi);
1105
+ if (x0 <= x1) out.push([x0 + d, x1 + d]);
1106
+ }
1107
+ out.sort((p, q) => p[0] - q[0]);
1108
+ const merged = [];
1109
+ for (const p of out) {
1110
+ const last = merged[merged.length - 1];
1111
+ if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
1112
+ else merged.push([p[0], p[1]]);
1113
+ }
1114
+ return merged;
1115
+ }
1116
+ function rectsThrough(st, rects) {
1117
+ const [a0, a1] = S(st.axis);
1118
+ const out = [];
1119
+ for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
1120
+ return out;
1121
+ }
1122
+ function rectMinus(a, b) {
1123
+ if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
1124
+ const out = [];
1125
+ if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
1126
+ if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
1127
+ const r0 = Math.max(a.startRow, b.startRow);
1128
+ const r1 = Math.min(a.endRow, b.endRow);
1129
+ if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
1130
+ if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
1131
+ return out;
1132
+ }
1133
+ function rectsMinus(as, bs) {
1134
+ let cur = as;
1135
+ for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
1136
+ return cur;
1137
+ }
1138
+ function nWrites(m) {
1139
+ const out = [];
1140
+ forEachCell(cellsOf(m), (r, c, v) => {
1141
+ if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
1142
+ out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
1143
+ });
1144
+ return out;
1145
+ }
1146
+ function numfmtPair(x, y, side, sx, sy) {
1147
+ const nx = isNumfmt(x);
1148
+ const ny = isNumfmt(y);
1149
+ if (!nx && !ny) return null;
1150
+ if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
1151
+ if (ny && sx) return ok([x]);
1152
+ if (nx && ny) {
1153
+ if (side === "left") return ok([x]);
1154
+ const ys = nfParts(y).flatMap((p) => p.ranges);
1155
+ return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
1156
+ }
1157
+ if (nx && y.id === ID.values) {
1158
+ if (side === "left") return ok([x]);
1159
+ const ys = nWrites(y);
1160
+ return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
1161
+ }
1162
+ if (ny && x.id === ID.values) {
1163
+ if (side === "left") return ok([x]);
1164
+ const out = {};
1165
+ const tail = {};
1166
+ let touched = false;
1167
+ forEachCell(cellsOf(x), (r, c, v) => {
1168
+ const n = nfValueAt(y, r, c);
1169
+ if (n === void 0) return putCell(out, r, c, v);
1170
+ if (v === null || v.s === null) {
1171
+ putCell(out, r, c, v);
1172
+ if (n) {
1173
+ putCell(tail, r, c, { s: { n } });
1174
+ touched = true;
1175
+ }
1176
+ return;
1177
+ }
1178
+ if (v.s && typeof v.s === "object" && "n" in v.s) {
1179
+ const { n: _drop, ...rest } = v.s;
1180
+ const e = { ...v };
1181
+ if (Object.keys(rest).length) e.s = rest;
1182
+ else delete e.s;
1183
+ touched = true;
1184
+ if (Object.keys(e).length) putCell(out, r, c, e);
1185
+ return;
1186
+ }
1187
+ putCell(out, r, c, v);
1188
+ });
1189
+ if (!touched) return ok([x]);
1190
+ const ops = [];
1191
+ if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
1192
+ if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
1193
+ return ok(ops);
1194
+ }
1195
+ return ok([x]);
1196
+ }
1197
+ var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
1198
+ var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
1199
+ var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
1200
+ function countPair(x, y, sy) {
1201
+ if (!isCount(x)) return isCount(y) ? ok([x]) : null;
1202
+ const k = countKey(x);
1203
+ const v = Number(x.params[k]);
1204
+ if (sy) {
1205
+ if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
1206
+ const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
1207
+ return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
1208
+ }
1209
+ if (isCount(y) && y.id === x.id) {
1210
+ const w = Number(y.params[k]);
1211
+ return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
1212
+ }
1213
+ return ok([x]);
1214
+ }
1215
+ var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
1216
+ var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
1217
+ function sheetAxisOf(m) {
1218
+ const p = m.params;
1219
+ if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
1220
+ if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
1221
+ if (m.id === ID.sheetOrder) {
1222
+ const f = Number(p.fromOrder);
1223
+ const t = Number(p.toOrder);
1224
+ return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
1225
+ }
1226
+ return null;
1227
+ }
1228
+ function buildSheetOp(template, op) {
1229
+ if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
1230
+ if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
1231
+ return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
1232
+ }
1233
+ function namesSheet(m, id) {
1234
+ const rs = refSheetsOf(m);
1235
+ return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
1236
+ }
1237
+ function sheetPair(x, y, side) {
1238
+ const xs = isSheetOp(x);
1239
+ const ys = isSheetOp(y);
1240
+ if (!xs && !ys) return null;
1241
+ if (xs && ys) {
1242
+ const a = sheetAxisOf(x);
1243
+ const b = sheetAxisOf(y);
1244
+ if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
1245
+ if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
1246
+ return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
1247
+ }
1248
+ if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
1249
+ const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
1250
+ if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
1251
+ const out2 = transformAxis(a, b, side);
1252
+ if (!out2) return barrier2("sheet order: no transform");
1253
+ return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
1254
+ }
1255
+ const out = transformAxis(a, b, side);
1256
+ if (!out) return barrier2("sheet order: no transform");
1257
+ return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
1258
+ }
1259
+ if (ys) {
1260
+ if (y.id !== ID.removeSheet) return ok([x]);
1261
+ const gone2 = sheetOf(y);
1262
+ if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
1263
+ if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
1264
+ return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
1265
+ return ok([x]);
1266
+ }
1267
+ if (x.id !== ID.removeSheet) return ok([x]);
1268
+ const gone = sheetOf(x);
1269
+ if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
1270
+ return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
1271
+ }
1272
+ function annotateSheetOps(group, sheetOrder) {
1273
+ const order = [...sheetOrder];
1274
+ return group.map((m) => {
1275
+ if (m.id === ID.insertSheet) {
1276
+ const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
1277
+ order.splice(index, 0, sheetIdOf(m));
1278
+ return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
1279
+ }
1280
+ if (m.id === ID.removeSheet) {
1281
+ const i = order.indexOf(sheetOf(m));
1282
+ if (i >= 0) order.splice(i, 1);
1283
+ return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
1284
+ }
1285
+ if (m.id === ID.sheetOrder) {
1286
+ const f = Number(m.params.fromOrder);
1287
+ const [id] = order.splice(f, 1);
1288
+ order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
1289
+ }
1290
+ return m;
1291
+ });
1292
+ }
1293
+ function inlineSheetStyles(sheet, styleOf) {
1294
+ const out = JSON.parse(JSON.stringify(sheet));
1295
+ const fix = (o) => {
1296
+ if (o && typeof o.s === "string") {
1297
+ const st = styleOf(o.s);
1298
+ if (st) o.s = JSON.parse(JSON.stringify(st));
1299
+ }
1300
+ };
1301
+ for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
1302
+ for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
1303
+ if (typeof out.defaultStyle === "string") {
1304
+ const st = styleOf(out.defaultStyle);
1305
+ if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
1306
+ }
1307
+ return out;
1308
+ }
1309
+ var isSort = (m) => m.id === ID.sort;
1310
+ function sortOf(m) {
1311
+ const P = /* @__PURE__ */ new Map();
1312
+ for (const [t, src] of Object.entries(m.params.order ?? {})) P.set(Number(t), Number(src));
1313
+ return { range: { ...m.params.range }, P };
1314
+ }
1315
+ var sortQ = (o) => new Map([...o.P].map(([t, s0]) => [s0, t]));
1316
+ function buildSort(template, o) {
1317
+ const order = {};
1318
+ for (const [t, s0] of [...o.P].sort((a, b) => a[0] - b[0])) if (t !== s0) order[t] = s0;
1319
+ if (!Object.keys(order).length || o.range.startRow > o.range.endRow || o.range.startColumn > o.range.endColumn) return [];
1320
+ return [{ id: template.id, params: { ...template.params, range: o.range, order } }];
1321
+ }
1322
+ var inSortCols = (o, c) => c >= o.range.startColumn && c <= o.range.endColumn;
1323
+ function sortThrough(o, st) {
1324
+ const r = o.range;
1325
+ if (st.axis === "col") {
1326
+ if (st.op.kind === "move") {
1327
+ const { from, count, to } = st.op;
1328
+ const touches = !(from + count - 1 < r.startColumn || from > r.endColumn) || to > r.startColumn && to <= r.endColumn;
1329
+ if (touches) return null;
1330
+ const spans3 = spanThrough(st.op, r.startColumn, r.endColumn);
1331
+ return spans3.length === 1 ? { range: { ...r, startColumn: spans3[0][0], endColumn: spans3[0][1] }, P: o.P } : null;
1332
+ }
1333
+ const spans2 = spanThrough(st.op, r.startColumn, r.endColumn);
1334
+ if (!spans2.length) return { range: { ...r, startColumn: 1, endColumn: 0 }, P: /* @__PURE__ */ new Map() };
1335
+ return { range: { ...r, startColumn: spans2[0][0], endColumn: spans2[spans2.length - 1][1] }, P: o.P };
1336
+ }
1337
+ const op = st.op;
1338
+ if (op.kind === "move") {
1339
+ const touches = !(op.from + op.count - 1 < r.startRow || op.from > r.endRow) || op.to > r.startRow && op.to <= r.endRow;
1340
+ if (touches) return null;
1341
+ }
1342
+ if (op.kind === "insert" || op.kind === "move") {
1343
+ const P2 = /* @__PURE__ */ new Map();
1344
+ for (const [t, s0] of o.P) P2.set(mapIndex(op, t), mapIndex(op, s0));
1345
+ const spans2 = spanThrough(op, r.startRow, r.endRow);
1346
+ return { range: { ...r, startRow: spans2[0][0], endRow: spans2[spans2.length - 1][1] }, P: P2 };
1347
+ }
1348
+ const removed = (i) => i >= op.start && i < op.start + op.count;
1349
+ const Q = sortQ(o);
1350
+ const goneTargets = [];
1351
+ for (let i = op.start; i < op.start + op.count; i++) goneTargets.push(Q.get(i) ?? i);
1352
+ goneTargets.sort((a, b) => a - b);
1353
+ const compact = (t) => t - goneTargets.filter((g) => g < t).length;
1354
+ const P = /* @__PURE__ */ new Map();
1355
+ for (const [t, s0] of o.P) if (!removed(s0)) P.set(compact(t), mapIndex(op, s0));
1356
+ const spans = spanThrough(op, r.startRow, r.endRow);
1357
+ if (!spans.length) return { range: { ...r, startRow: 1, endRow: 0 }, P: /* @__PURE__ */ new Map() };
1358
+ return { range: { ...r, startRow: spans[0][0], endRow: spans[spans.length - 1][1] }, P };
1359
+ }
1360
+ function sortPair(x, y, sx, sy) {
1361
+ const xs = isSort(x);
1362
+ const ys = isSort(y);
1363
+ if (!xs && !ys) return null;
1364
+ if (xs && ys) {
1365
+ const a = sortOf(x).range;
1366
+ const b = sortOf(y).range;
1367
+ const overlap = a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
1368
+ return overlap ? barrier2("two sorts of overlapping ranges at once") : ok([x]);
1369
+ }
1370
+ if (xs) {
1371
+ if (sy) {
1372
+ const t = sortThrough(sortOf(x), sy);
1373
+ return t ? ok(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
1374
+ }
1375
+ return ok([x]);
1376
+ }
1377
+ const o = sortOf(y);
1378
+ const Q = sortQ(o);
1379
+ const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
1380
+ if (sx) {
1381
+ if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok([x]);
1382
+ if (sx.op.kind === "insert") return ok([x]);
1383
+ if (sx.op.kind === "move") return sortThrough(o, sx) ? ok([x]) : barrier2("a row move through a sorted range");
1384
+ const rows = [];
1385
+ let partial = false;
1386
+ for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
1387
+ if (moved(i)) partial = true;
1388
+ rows.push(Q.get(i) ?? i);
1389
+ }
1390
+ if (partial) return barrier2("a row remove against a concurrent sort of those rows");
1391
+ return ok([x]);
1392
+ }
1393
+ if (x.id === ID.values) {
1394
+ const out = {};
1395
+ let changed = false;
1396
+ forEachCell(cellsOf(x), (r, c, v) => {
1397
+ if (inSortCols(o, c) && moved(r)) {
1398
+ putCell(out, Q.get(r), c, v);
1399
+ changed = true;
1400
+ } else putCell(out, r, c, v);
1401
+ });
1402
+ return changed ? ok([cellsMutation(x, out)]) : ok([x]);
1403
+ }
1404
+ if (isNumfmt(x)) {
1405
+ const parts = nfParts(x).map((p) => {
1406
+ const ranges = [];
1407
+ for (const rc of p.ranges) {
1408
+ const inner = { ...rc, startRow: Math.max(rc.startRow, o.range.startRow), endRow: Math.min(rc.endRow, o.range.endRow), startColumn: Math.max(rc.startColumn, o.range.startColumn), endColumn: Math.min(rc.endColumn, o.range.endColumn) };
1409
+ if (inner.startRow > inner.endRow || inner.startColumn > inner.endColumn) {
1410
+ ranges.push(rc);
1411
+ continue;
1412
+ }
1413
+ ranges.push(...rectMinus(rc, inner));
1414
+ for (let r = inner.startRow; r <= inner.endRow; r++) ranges.push({ ...inner, startRow: Q.get(r) ?? r, endRow: Q.get(r) ?? r });
1415
+ }
1416
+ return { ...p, ranges };
1417
+ });
1418
+ return ok(nfBuild(x, parts));
1419
+ }
1420
+ return ok([x]);
1421
+ }
1004
1422
  function familyOf(id) {
1005
1423
  const e = SHEET_MUTATIONS[id];
1006
1424
  return e && e.kind === "covered" ? e.family : "";
@@ -1017,6 +1435,8 @@ function transformMutation(x, y, side) {
1017
1435
  }
1018
1436
  const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
1019
1437
  if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
1438
+ const sp = sheetPair(x, y, side);
1439
+ if (sp) return sp;
1020
1440
  const fp = formulaPair(x, y, side);
1021
1441
  if (fp) return fp;
1022
1442
  if (sheetOf(x) !== sheetOf(y)) return ok([x]);
@@ -1024,6 +1444,12 @@ function transformMutation(x, y, side) {
1024
1444
  const fy = familyOf(y.id);
1025
1445
  const sy = structuralOf(y);
1026
1446
  const sx = structuralOf(x);
1447
+ const sortp = sortPair(x, y, sx, sy);
1448
+ if (sortp) return sortp;
1449
+ const cp = countPair(x, y, sy);
1450
+ if (cp) return cp;
1451
+ const np = numfmtPair(x, y, side, sx, sy);
1452
+ if (np) return np;
1027
1453
  if (sx && sy) {
1028
1454
  if (sx.axis !== sy.axis) return ok([x]);
1029
1455
  const out = transformAxis(sx.op, sy.op, side);
@@ -1131,22 +1557,45 @@ function tSeq(xs, ys, side, acc) {
1131
1557
  acc.dropped.push(...a.dropped);
1132
1558
  return [a.op, b.op];
1133
1559
  }
1560
+ const outX = [];
1561
+ let curY = ys;
1562
+ for (const x of xs) {
1563
+ let curX = [x];
1564
+ const nextY = [];
1565
+ for (const y of curY) {
1566
+ if (curX.length === 0) {
1567
+ nextY.push(y);
1568
+ continue;
1569
+ }
1570
+ const r = tSeq(curX, [y], side, acc);
1571
+ if (blocked(r)) return r;
1572
+ curX = r[0];
1573
+ for (const m of r[1]) nextY.push(m);
1574
+ }
1575
+ for (const m of curX) outX.push(m);
1576
+ curY = nextY;
1577
+ }
1578
+ return [outX, curY];
1579
+ }
1580
+ function tSeqOld(xs, ys, side, acc) {
1581
+ if (xs.length === 0 || ys.length === 0) return [xs, ys];
1582
+ if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
1134
1583
  if (xs.length > 1) {
1135
- const first2 = tSeq([xs[0]], ys, side, acc);
1584
+ const first2 = tSeqOld([xs[0]], ys, side, acc);
1136
1585
  if (blocked(first2)) return first2;
1137
- const rest2 = tSeq(xs.slice(1), first2[1], side, acc);
1586
+ const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
1138
1587
  if (blocked(rest2)) return rest2;
1139
1588
  return [[...first2[0], ...rest2[0]], rest2[1]];
1140
1589
  }
1141
- const first = tSeq(xs, [ys[0]], side, acc);
1590
+ const first = tSeqOld(xs, [ys[0]], side, acc);
1142
1591
  if (blocked(first)) return first;
1143
- const rest = tSeq(first[0], ys.slice(1), side, acc);
1592
+ const rest = tSeqOld(first[0], ys.slice(1), side, acc);
1144
1593
  if (blocked(rest)) return rest;
1145
1594
  return [rest[0], [...first[1], ...rest[1]]];
1146
1595
  }
1147
1596
  function transformGroup(x, y, side) {
1148
1597
  const acc = { lost: [], dropped: [] };
1149
- const r = tSeq([...x], [...y], side, acc);
1598
+ const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
1150
1599
  if (blocked(r)) return r;
1151
1600
  return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
1152
1601
  }
@@ -1173,19 +1622,24 @@ export {
1173
1622
  SIDE_CAR_PARAMS,
1174
1623
  allowParams,
1175
1624
  annotateFormulas,
1625
+ annotateSheetOps,
1176
1626
  cellRef,
1177
1627
  completeCellContent,
1178
1628
  exactMergeRemovals,
1179
1629
  forApply,
1180
1630
  formulaBarrier,
1631
+ inlineSheetStyles,
1181
1632
  isBarrier,
1182
1633
  isFormulaText,
1634
+ isStructuralMutation,
1183
1635
  mapIndex,
1636
+ mergeFixupsOwed,
1184
1637
  mergeThrough,
1185
1638
  refSheetsAfter,
1186
1639
  refSheetsFor,
1187
1640
  rewriteFormula,
1188
1641
  sheetTransformer,
1642
+ spanThrough,
1189
1643
  transformAxis,
1190
1644
  transformGroup,
1191
1645
  transformMutation