@ai-matrx/office 0.8.21 → 0.8.23

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.
@@ -1113,25 +1113,25 @@ function rebaseUndoStack(items, remote) {
1113
1113
  let dropped = 0;
1114
1114
  for (let i = items.length - 1; i >= 0; i--) {
1115
1115
  const item = items[i];
1116
- let ok2 = true;
1116
+ let ok3 = true;
1117
1117
  for (const list of [item.undoMutations, item.redoMutations]) {
1118
1118
  for (const m of list ?? []) {
1119
1119
  if (m.id !== RICH_TEXT_EDITING) continue;
1120
1120
  try {
1121
1121
  if (touchesPageSetup(m.params.actions) && touchesPageSetup(remote)) throw new Error("page setup");
1122
1122
  const r = transformDocsOp(m.params.actions, remote, "left");
1123
- if (isNoopDocsOp(r.op)) ok2 = false;
1123
+ if (isNoopDocsOp(r.op)) ok3 = false;
1124
1124
  else {
1125
1125
  m.params = { ...m.params, actions: r.op };
1126
1126
  delete m.params.textRanges;
1127
1127
  delete m.params.layoutState;
1128
1128
  }
1129
1129
  } catch {
1130
- ok2 = false;
1130
+ ok3 = false;
1131
1131
  }
1132
1132
  }
1133
1133
  }
1134
- if (!ok2) {
1134
+ if (!ok3) {
1135
1135
  items.splice(i, 1);
1136
1136
  dropped++;
1137
1137
  }
@@ -1693,6 +1693,9 @@ var SHEET_MUTATIONS = {
1693
1693
  "sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
1694
1694
  "sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
1695
1695
  "sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
1696
+ // ── covered (C9): our own cell comment anchors (comment-anchor-transform.ts; not emitted by Univer) ──────
1697
+ "matrx.mutation.set-comment-anchor": covered("anchor", "anchorId", "cell"),
1698
+ "sheet.mutation.reorder-range": covered("sort", "range", "order"),
1696
1699
  // ── never travels ────────────────────────────────────────────────────────────────────────────────
1697
1700
  "formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
1698
1701
  "formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
@@ -1726,7 +1729,6 @@ var SHEET_MUTATIONS = {
1726
1729
  "thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
1727
1730
  "thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
1728
1731
  // ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
1729
- "sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
1730
1732
  "sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
1731
1733
  "sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
1732
1734
  "sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
@@ -2144,6 +2146,74 @@ function refSheetsFor(texts, sheets) {
2144
2146
  return Object.keys(out).length ? out : void 0;
2145
2147
  }
2146
2148
 
2149
+ // src/collab/sheets/comment-anchor-transform.ts
2150
+ var SET_SHEET_COMMENT_ANCHOR = "matrx.mutation.set-comment-anchor";
2151
+ var REMOVE_SHEET = "sheet.mutation.remove-sheet";
2152
+ function structuralAxisOp(id, params) {
2153
+ const p = params;
2154
+ switch (id) {
2155
+ case "sheet.mutation.insert-row":
2156
+ return p.range ? { axis: "row", op: { kind: "insert", at: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
2157
+ case "sheet.mutation.remove-rows":
2158
+ return p.range ? { axis: "row", op: { kind: "remove", start: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
2159
+ case "sheet.mutation.insert-col":
2160
+ return p.range ? { axis: "col", op: { kind: "insert", at: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
2161
+ case "sheet.mutation.remove-col":
2162
+ return p.range ? { axis: "col", op: { kind: "remove", start: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
2163
+ case "sheet.mutation.move-rows":
2164
+ return p.sourceRange && p.targetRange ? { axis: "row", op: { kind: "move", from: p.sourceRange.startRow, count: p.sourceRange.endRow - p.sourceRange.startRow + 1, to: p.targetRange.startRow } } : null;
2165
+ case "sheet.mutation.move-columns":
2166
+ return p.sourceRange && p.targetRange ? {
2167
+ axis: "col",
2168
+ op: { kind: "move", from: p.sourceRange.startColumn, count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1, to: p.targetRange.startColumn }
2169
+ } : null;
2170
+ default:
2171
+ return null;
2172
+ }
2173
+ }
2174
+ function moveSheetAnchorCell(cell, sheet, id, params) {
2175
+ if (String(params.subUnitId ?? "") !== sheet) return cell;
2176
+ if (id === REMOVE_SHEET) return null;
2177
+ const s = structuralAxisOp(id, params);
2178
+ if (!s) return cell;
2179
+ if (s.axis === "row") {
2180
+ const row = mapIndex(s.op, cell.row);
2181
+ return row === null ? null : row === cell.row ? cell : { row, col: cell.col };
2182
+ }
2183
+ const col = mapIndex(s.op, cell.col);
2184
+ return col === null ? null : col === cell.col ? cell : { row: cell.row, col };
2185
+ }
2186
+ function colName(c) {
2187
+ let s = "";
2188
+ for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
2189
+ return s;
2190
+ }
2191
+ var sheetCellName = (cell) => `${colName(cell.col)}${cell.row + 1}`;
2192
+ function cellOf(m) {
2193
+ const c = m.params.cell;
2194
+ return c && typeof c.row === "number" && typeof c.col === "number" ? c : null;
2195
+ }
2196
+ var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2197
+ var label = (m) => {
2198
+ const c = cellOf(m);
2199
+ return `${String(m.params.subUnitId ?? "")}!${c ? sheetCellName(c) : "?"} comment`;
2200
+ };
2201
+ function transformCommentAnchor(x, y, side) {
2202
+ const xa = x.id === SET_SHEET_COMMENT_ANCHOR;
2203
+ const ya = y.id === SET_SHEET_COMMENT_ANCHOR;
2204
+ if (!xa && !ya) return null;
2205
+ if (!xa) return ok([x]);
2206
+ if (ya) {
2207
+ if (x.params.anchorId !== y.params.anchorId || x.params.subUnitId !== y.params.subUnitId) return ok([x]);
2208
+ return side === "left" ? ok([x], [label(y)]) : ok([], [], [label(x)]);
2209
+ }
2210
+ const cell = cellOf(x);
2211
+ if (!cell) return ok([x]);
2212
+ const moved = moveSheetAnchorCell(cell, String(x.params.subUnitId ?? ""), y.id, y.params);
2213
+ if (!moved) return ok([], [], [label(x)]);
2214
+ return ok([moved === cell ? x : { id: x.id, params: { ...x.params, cell: moved } }]);
2215
+ }
2216
+
2147
2217
  // src/collab/sheets/transform/transform.ts
2148
2218
  var SHEET_TRANSFORMER_VERSION = "c5c-1";
2149
2219
  var ID = {
@@ -2169,21 +2239,22 @@ var ID = {
2169
2239
  colCount: "sheet.mutation.set-worksheet-column-count",
2170
2240
  insertSheet: "sheet.mutation.insert-sheet",
2171
2241
  removeSheet: "sheet.mutation.remove-sheet",
2172
- sheetOrder: "sheet.mutation.set-worksheet-order"
2242
+ sheetOrder: "sheet.mutation.set-worksheet-order",
2243
+ sort: "sheet.mutation.reorder-range"
2173
2244
  };
2174
2245
  var PAIR_BARRIERS = {};
2175
2246
  var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
2176
2247
  var barrier2 = (reason) => ({ barrier: true, reason });
2177
- var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2248
+ var ok2 = (op, lost = [], dropped = []) => ({ op, lost, dropped });
2178
2249
  var flip = (side) => side === "left" ? "right" : "left";
2179
2250
  var sheetOf = (m) => String(m.params.subUnitId ?? "");
2180
- function colName(c) {
2251
+ function colName2(c) {
2181
2252
  let s = "";
2182
2253
  for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
2183
2254
  return s;
2184
2255
  }
2185
- var cellRef = (sheet, row, col) => `${sheet}!${colName(col)}${row + 1}`;
2186
- var rangeRef = (sheet, r) => `${sheet}!${colName(r.startColumn)}${r.startRow + 1}:${colName(r.endColumn)}${r.endRow + 1}`;
2256
+ var cellRef = (sheet, row, col) => `${sheet}!${colName2(col)}${row + 1}`;
2257
+ var rangeRef = (sheet, r) => `${sheet}!${colName2(r.startColumn)}${r.startRow + 1}:${colName2(r.endColumn)}${r.endRow + 1}`;
2187
2258
  function structuralOf(m) {
2188
2259
  const p = m.params;
2189
2260
  switch (m.id) {
@@ -2438,9 +2509,9 @@ function transformCell(X, Y4, side) {
2438
2509
  return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
2439
2510
  }
2440
2511
  function transformCellsOverCells(x, y, side) {
2441
- if (sheetOf(x) !== sheetOf(y)) return ok([x]);
2512
+ if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
2442
2513
  const ycells = cellsOf(y);
2443
- if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
2514
+ if (!cellsOverlap(cellsOf(x), ycells)) return ok2([x]);
2444
2515
  const xd = isDerived(x);
2445
2516
  const yd = isDerived(y);
2446
2517
  const eff = derivedSide(x, y, side);
@@ -2466,7 +2537,7 @@ function transformCellsOverCells(x, y, side) {
2466
2537
  });
2467
2538
  if (why) return barrier2(why);
2468
2539
  const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
2469
- return ok(op, lost, dropped);
2540
+ return ok2(op, lost, dropped);
2470
2541
  }
2471
2542
  var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
2472
2543
  var isDerived = (m) => m.params.derived === true;
@@ -2537,7 +2608,7 @@ function cellThrough(sheet, change, r, c) {
2537
2608
  return nr === null || nc === null ? null : [nr, nc];
2538
2609
  }
2539
2610
  function cellsOverChange(x, change) {
2540
- if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
2611
+ if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok2([x]);
2541
2612
  const ctx = formulaCtx(x);
2542
2613
  const out = {};
2543
2614
  const dropped = [];
@@ -2566,9 +2637,9 @@ function cellsOverChange(x, change) {
2566
2637
  });
2567
2638
  if (why) return barrier2(why);
2568
2639
  const rsAfter = refSheetsAfter(ctx.refSheets, change);
2569
- if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
2640
+ if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok2([x]);
2570
2641
  const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
2571
- return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
2642
+ return ok2(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
2572
2643
  }
2573
2644
  function rewritesOf(y, change) {
2574
2645
  if (!hasFormula(y)) return null;
@@ -2615,36 +2686,36 @@ function formulaPair(x, y, side) {
2615
2686
  const fy = familyOf(y.id);
2616
2687
  const SET_NAME_BARRIER = "set-defined-name without previousName (capture must record the name it replaces) against formula text";
2617
2688
  if (fx === "defname" && fy === "defname") {
2618
- if (String(x.params.id) !== String(y.params.id)) return ok([x]);
2689
+ if (String(x.params.id) !== String(y.params.id)) return ok2([x]);
2619
2690
  const eff = derivedSide(x, y, side);
2620
- if (eff === "left") return ok([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
2621
- return ok([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
2691
+ if (eff === "left") return ok2([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
2692
+ return ok2([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
2622
2693
  }
2623
2694
  if (fx === "defname") {
2624
2695
  if (fy === "cell") {
2625
2696
  if (setNameWithoutPrevious(x) && hasFormula(y)) return barrier2(SET_NAME_BARRIER);
2626
2697
  const ch2 = refChangeOf(x);
2627
- if (!ch2) return ok([x]);
2698
+ if (!ch2) return ok2([x]);
2628
2699
  const add = rewritesOf(y, ch2);
2629
2700
  if (typeof add === "string") return barrier2(add);
2630
- return ok(add ? [x, add] : [x]);
2701
+ return ok2(add ? [x, add] : [x]);
2631
2702
  }
2632
2703
  const ch = refChangeOf(y);
2633
- if (!ch) return ok([x]);
2704
+ if (!ch) return ok2([x]);
2634
2705
  const r = definedNameThrough(x, ch);
2635
- return typeof r === "string" ? barrier2(r) : ok([r.op]);
2706
+ return typeof r === "string" ? barrier2(r) : ok2([r.op]);
2636
2707
  }
2637
2708
  if (fy === "defname") {
2638
2709
  if (fx === "cell") {
2639
2710
  if (setNameWithoutPrevious(y) && hasFormula(x)) return barrier2(SET_NAME_BARRIER);
2640
2711
  const ch2 = refChangeOf(y);
2641
- return ch2 ? cellsOverChange(x, ch2) : ok([x]);
2712
+ return ch2 ? cellsOverChange(x, ch2) : ok2([x]);
2642
2713
  }
2643
2714
  const ch = refChangeOf(x);
2644
- if (!ch) return ok([x]);
2715
+ if (!ch) return ok2([x]);
2645
2716
  const r = definedNameThrough(y, ch);
2646
2717
  if (typeof r === "string") return barrier2(r);
2647
- return ok(r.changed ? [x, asDerived(r.op)] : [x]);
2718
+ return ok2(r.changed ? [x, asDerived(r.op)] : [x]);
2648
2719
  }
2649
2720
  if (fx === "cell") {
2650
2721
  const ch = refChangeOf(y);
@@ -2659,7 +2730,7 @@ function formulaPair(x, y, side) {
2659
2730
  });
2660
2731
  const add = rewritesOf(y, ch);
2661
2732
  if (typeof add === "string") return barrier2(add);
2662
- return ok(add ? [x, add] : [x], lost);
2733
+ return ok2(add ? [x, add] : [x], lost);
2663
2734
  }
2664
2735
  return null;
2665
2736
  }
@@ -2807,20 +2878,20 @@ function numfmtPair(x, y, side, sx, sy) {
2807
2878
  const nx = isNumfmt(x);
2808
2879
  const ny = isNumfmt(y);
2809
2880
  if (!nx && !ny) return null;
2810
- if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
2811
- if (ny && sx) return ok([x]);
2881
+ if (nx && sy) return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
2882
+ if (ny && sx) return ok2([x]);
2812
2883
  if (nx && ny) {
2813
- if (side === "left") return ok([x]);
2884
+ if (side === "left") return ok2([x]);
2814
2885
  const ys = nfParts(y).flatMap((p) => p.ranges);
2815
- return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
2886
+ return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
2816
2887
  }
2817
2888
  if (nx && y.id === ID.values) {
2818
- if (side === "left") return ok([x]);
2889
+ if (side === "left") return ok2([x]);
2819
2890
  const ys = nWrites(y);
2820
- return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
2891
+ return ys.length ? ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok2([x]);
2821
2892
  }
2822
2893
  if (ny && x.id === ID.values) {
2823
- if (side === "left") return ok([x]);
2894
+ if (side === "left") return ok2([x]);
2824
2895
  const out = {};
2825
2896
  const tail = {};
2826
2897
  let touched = false;
@@ -2846,31 +2917,31 @@ function numfmtPair(x, y, side, sx, sy) {
2846
2917
  }
2847
2918
  putCell(out, r, c, v);
2848
2919
  });
2849
- if (!touched) return ok([x]);
2920
+ if (!touched) return ok2([x]);
2850
2921
  const ops = [];
2851
2922
  if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
2852
2923
  if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
2853
- return ok(ops);
2924
+ return ok2(ops);
2854
2925
  }
2855
- return ok([x]);
2926
+ return ok2([x]);
2856
2927
  }
2857
2928
  var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
2858
2929
  var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
2859
2930
  var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
2860
2931
  function countPair(x, y, sy) {
2861
- if (!isCount(x)) return isCount(y) ? ok([x]) : null;
2932
+ if (!isCount(x)) return isCount(y) ? ok2([x]) : null;
2862
2933
  const k = countKey(x);
2863
2934
  const v = Number(x.params[k]);
2864
2935
  if (sy) {
2865
- if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
2936
+ if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok2([x]);
2866
2937
  const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
2867
- return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
2938
+ return ok2([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
2868
2939
  }
2869
2940
  if (isCount(y) && y.id === x.id) {
2870
2941
  const w = Number(y.params[k]);
2871
- return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
2942
+ return ok2([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
2872
2943
  }
2873
- return ok([x]);
2944
+ return ok2([x]);
2874
2945
  }
2875
2946
  var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
2876
2947
  var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
@@ -2903,31 +2974,31 @@ function sheetPair(x, y, side) {
2903
2974
  const b = sheetAxisOf(y);
2904
2975
  if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
2905
2976
  if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
2906
- return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
2977
+ return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok2([]) : barrier2("the same sheet id added twice with different content");
2907
2978
  }
2908
2979
  if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
2909
2980
  const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
2910
2981
  if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
2911
2982
  const out2 = transformAxis(a, b, side);
2912
2983
  if (!out2) return barrier2("sheet order: no transform");
2913
- return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
2984
+ return ok2(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
2914
2985
  }
2915
2986
  const out = transformAxis(a, b, side);
2916
2987
  if (!out) return barrier2("sheet order: no transform");
2917
- return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
2988
+ return ok2(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
2918
2989
  }
2919
2990
  if (ys) {
2920
- if (y.id !== ID.removeSheet) return ok([x]);
2991
+ if (y.id !== ID.removeSheet) return ok2([x]);
2921
2992
  const gone2 = sheetOf(y);
2922
2993
  if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
2923
2994
  if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
2924
- return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
2925
- return ok([x]);
2995
+ return ok2([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
2996
+ return ok2([x]);
2926
2997
  }
2927
- if (x.id !== ID.removeSheet) return ok([x]);
2998
+ if (x.id !== ID.removeSheet) return ok2([x]);
2928
2999
  const gone = sheetOf(x);
2929
3000
  if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
2930
- return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
3001
+ return ok2([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
2931
3002
  }
2932
3003
  function annotateSheetOps(group, sheetOrder) {
2933
3004
  const order = [...sheetOrder];
@@ -2966,6 +3037,119 @@ function inlineSheetStyles(sheet, styleOf) {
2966
3037
  }
2967
3038
  return out;
2968
3039
  }
3040
+ var isSort = (m) => m.id === ID.sort;
3041
+ function sortOf(m) {
3042
+ const P = /* @__PURE__ */ new Map();
3043
+ for (const [t, src] of Object.entries(m.params.order ?? {})) P.set(Number(t), Number(src));
3044
+ return { range: { ...m.params.range }, P };
3045
+ }
3046
+ var sortQ = (o) => new Map([...o.P].map(([t, s0]) => [s0, t]));
3047
+ function buildSort(template, o) {
3048
+ const order = {};
3049
+ for (const [t, s0] of [...o.P].sort((a, b) => a[0] - b[0])) if (t !== s0) order[t] = s0;
3050
+ if (!Object.keys(order).length || o.range.startRow > o.range.endRow || o.range.startColumn > o.range.endColumn) return [];
3051
+ return [{ id: template.id, params: { ...template.params, range: o.range, order } }];
3052
+ }
3053
+ var inSortCols = (o, c) => c >= o.range.startColumn && c <= o.range.endColumn;
3054
+ function sortThrough(o, st) {
3055
+ const r = o.range;
3056
+ if (st.axis === "col") {
3057
+ if (st.op.kind === "move") {
3058
+ const { from, count, to } = st.op;
3059
+ const touches = !(from + count - 1 < r.startColumn || from > r.endColumn) || to > r.startColumn && to <= r.endColumn;
3060
+ if (touches) return null;
3061
+ const spans3 = spanThrough(st.op, r.startColumn, r.endColumn);
3062
+ return spans3.length === 1 ? { range: { ...r, startColumn: spans3[0][0], endColumn: spans3[0][1] }, P: o.P } : null;
3063
+ }
3064
+ const spans2 = spanThrough(st.op, r.startColumn, r.endColumn);
3065
+ if (!spans2.length) return { range: { ...r, startColumn: 1, endColumn: 0 }, P: /* @__PURE__ */ new Map() };
3066
+ return { range: { ...r, startColumn: spans2[0][0], endColumn: spans2[spans2.length - 1][1] }, P: o.P };
3067
+ }
3068
+ const op = st.op;
3069
+ if (op.kind === "move") {
3070
+ const touches = !(op.from + op.count - 1 < r.startRow || op.from > r.endRow) || op.to > r.startRow && op.to <= r.endRow;
3071
+ if (touches) return null;
3072
+ }
3073
+ if (op.kind === "insert" || op.kind === "move") {
3074
+ const P2 = /* @__PURE__ */ new Map();
3075
+ for (const [t, s0] of o.P) P2.set(mapIndex(op, t), mapIndex(op, s0));
3076
+ const spans2 = spanThrough(op, r.startRow, r.endRow);
3077
+ return { range: { ...r, startRow: spans2[0][0], endRow: spans2[spans2.length - 1][1] }, P: P2 };
3078
+ }
3079
+ const removed = (i) => i >= op.start && i < op.start + op.count;
3080
+ const Q = sortQ(o);
3081
+ const goneTargets = [];
3082
+ for (let i = op.start; i < op.start + op.count; i++) goneTargets.push(Q.get(i) ?? i);
3083
+ goneTargets.sort((a, b) => a - b);
3084
+ const compact = (t) => t - goneTargets.filter((g) => g < t).length;
3085
+ const P = /* @__PURE__ */ new Map();
3086
+ for (const [t, s0] of o.P) if (!removed(s0)) P.set(compact(t), mapIndex(op, s0));
3087
+ const spans = spanThrough(op, r.startRow, r.endRow);
3088
+ if (!spans.length) return { range: { ...r, startRow: 1, endRow: 0 }, P: /* @__PURE__ */ new Map() };
3089
+ return { range: { ...r, startRow: spans[0][0], endRow: spans[spans.length - 1][1] }, P };
3090
+ }
3091
+ function sortPair(x, y, sx, sy) {
3092
+ const xs = isSort(x);
3093
+ const ys = isSort(y);
3094
+ if (!xs && !ys) return null;
3095
+ if (xs && ys) {
3096
+ const a = sortOf(x).range;
3097
+ const b = sortOf(y).range;
3098
+ const overlap = a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
3099
+ return overlap ? barrier2("two sorts of overlapping ranges at once") : ok2([x]);
3100
+ }
3101
+ if (xs) {
3102
+ if (sy) {
3103
+ const t = sortThrough(sortOf(x), sy);
3104
+ return t ? ok2(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
3105
+ }
3106
+ return ok2([x]);
3107
+ }
3108
+ const o = sortOf(y);
3109
+ const Q = sortQ(o);
3110
+ const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
3111
+ if (sx) {
3112
+ if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok2([x]);
3113
+ if (sx.op.kind === "insert") return ok2([x]);
3114
+ if (sx.op.kind === "move") return sortThrough(o, sx) ? ok2([x]) : barrier2("a row move through a sorted range");
3115
+ const rows = [];
3116
+ let partial = false;
3117
+ for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
3118
+ if (moved(i)) partial = true;
3119
+ rows.push(Q.get(i) ?? i);
3120
+ }
3121
+ if (partial) return barrier2("a row remove against a concurrent sort of those rows");
3122
+ return ok2([x]);
3123
+ }
3124
+ if (x.id === ID.values) {
3125
+ const out = {};
3126
+ let changed = false;
3127
+ forEachCell(cellsOf(x), (r, c, v) => {
3128
+ if (inSortCols(o, c) && moved(r)) {
3129
+ putCell(out, Q.get(r), c, v);
3130
+ changed = true;
3131
+ } else putCell(out, r, c, v);
3132
+ });
3133
+ return changed ? ok2([cellsMutation(x, out)]) : ok2([x]);
3134
+ }
3135
+ if (isNumfmt(x)) {
3136
+ const parts = nfParts(x).map((p) => {
3137
+ const ranges = [];
3138
+ for (const rc of p.ranges) {
3139
+ 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) };
3140
+ if (inner.startRow > inner.endRow || inner.startColumn > inner.endColumn) {
3141
+ ranges.push(rc);
3142
+ continue;
3143
+ }
3144
+ ranges.push(...rectMinus(rc, inner));
3145
+ for (let r = inner.startRow; r <= inner.endRow; r++) ranges.push({ ...inner, startRow: Q.get(r) ?? r, endRow: Q.get(r) ?? r });
3146
+ }
3147
+ return { ...p, ranges };
3148
+ });
3149
+ return ok2(nfBuild(x, parts));
3150
+ }
3151
+ return ok2([x]);
3152
+ }
2969
3153
  function familyOf(id) {
2970
3154
  const e = SHEET_MUTATIONS[id];
2971
3155
  return e && e.kind === "covered" ? e.family : "";
@@ -2980,27 +3164,31 @@ function transformMutation(x, y, side) {
2980
3164
  if (why) return barrier2(why);
2981
3165
  }
2982
3166
  }
3167
+ const ca = transformCommentAnchor(x, y, side);
3168
+ if (ca) return ca;
2983
3169
  const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
2984
3170
  if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
2985
3171
  const sp = sheetPair(x, y, side);
2986
3172
  if (sp) return sp;
2987
3173
  const fp = formulaPair(x, y, side);
2988
3174
  if (fp) return fp;
2989
- if (sheetOf(x) !== sheetOf(y)) return ok([x]);
3175
+ if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
2990
3176
  const fx = familyOf(x.id);
2991
3177
  const fy = familyOf(y.id);
2992
3178
  const sy = structuralOf(y);
2993
3179
  const sx = structuralOf(x);
3180
+ const sortp = sortPair(x, y, sx, sy);
3181
+ if (sortp) return sortp;
2994
3182
  const cp = countPair(x, y, sy);
2995
3183
  if (cp) return cp;
2996
3184
  const np = numfmtPair(x, y, side, sx, sy);
2997
3185
  if (np) return np;
2998
3186
  if (sx && sy) {
2999
- if (sx.axis !== sy.axis) return ok([x]);
3187
+ if (sx.axis !== sy.axis) return ok2([x]);
3000
3188
  const out = transformAxis(sx.op, sy.op, side);
3001
3189
  if (!out) return barrier2(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);
3002
3190
  const dropped = out.length === 0 && sx.op.kind === "move" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];
3003
- return ok(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
3191
+ return ok2(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
3004
3192
  }
3005
3193
  if (sy) {
3006
3194
  if (fx === "merge") {
@@ -3011,23 +3199,23 @@ function transformMutation(x, y, side) {
3011
3199
  if (t) kept.push(t);
3012
3200
  else dropped.push(rangeRef(sheetOf(x), r));
3013
3201
  }
3014
- return ok(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
3202
+ return ok2(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
3015
3203
  }
3016
3204
  if (fx === "size") {
3017
3205
  const size = sizeOf(x);
3018
- if (size.axis !== sy.axis) return ok([x]);
3206
+ if (size.axis !== sy.axis) return ok2([x]);
3019
3207
  const next = /* @__PURE__ */ new Map();
3020
3208
  for (const [i, v] of size.values) {
3021
3209
  const m = mapIndex(sy.op, i);
3022
3210
  if (m !== null) next.set(m, v);
3023
3211
  }
3024
3212
  const built = buildSize(x, next);
3025
- return ok(built ? [built] : []);
3213
+ return ok2(built ? [built] : []);
3026
3214
  }
3027
- return ok([x]);
3215
+ return ok2([x]);
3028
3216
  }
3029
3217
  if (sx) {
3030
- if (fy !== "merge" || y.id !== ID.addMerge) return ok([x]);
3218
+ if (fy !== "merge" || y.id !== ID.addMerge) return ok2([x]);
3031
3219
  const remove = [];
3032
3220
  const add = [];
3033
3221
  for (const r of mergeRanges(y)) {
@@ -3037,11 +3225,11 @@ function transformMutation(x, y, side) {
3037
3225
  if (t.range) add.push(t.range);
3038
3226
  }
3039
3227
  const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));
3040
- if (!remove.length) return ok([x], lostMerges);
3228
+ if (!remove.length) return ok2([x], lostMerges);
3041
3229
  const sheet = sheetOf(x);
3042
3230
  const pre = sx.op.kind === "insert" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];
3043
3231
  const mid = sx.op.kind === "insert" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];
3044
- return ok([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
3232
+ return ok2([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
3045
3233
  }
3046
3234
  if (fx === "cell" && fy === "cell") return transformCellsOverCells(x, y, side);
3047
3235
  if (fx === "merge" && fy === "merge") {
@@ -3050,45 +3238,45 @@ function transformMutation(x, y, side) {
3050
3238
  const hit = (r) => yr.some((q) => intersects(r, q));
3051
3239
  const sheet = sheetOf(x);
3052
3240
  if (x.id === ID.addMerge && y.id === ID.addMerge) {
3053
- if (!xr.some(hit)) return ok([x]);
3241
+ if (!xr.some(hit)) return ok2([x]);
3054
3242
  if (side === "left") {
3055
3243
  const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));
3056
- return ok([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
3244
+ return ok2([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
3057
3245
  }
3058
3246
  const kept = xr.filter((r) => !hit(r));
3059
- return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3247
+ return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3060
3248
  }
3061
3249
  if (x.id === ID.addMerge && y.id === ID.removeMerge) {
3062
- 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)) : []);
3250
+ if (side === "left" || !xr.some(hit)) return ok2([x], side === "left" && xr.some(hit) ? yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q)) : []);
3063
3251
  const kept = xr.filter((r) => !hit(r));
3064
- return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3252
+ return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3065
3253
  }
3066
3254
  if (x.id === ID.removeMerge && y.id === ID.addMerge) {
3067
3255
  const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));
3068
- if (!touched.length) return ok([x]);
3069
- if (side === "left") return ok([x], touched.map((q) => rangeRef(sheet, q)));
3070
- return ok([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3256
+ if (!touched.length) return ok2([x]);
3257
+ if (side === "left") return ok2([x], touched.map((q) => rangeRef(sheet, q)));
3258
+ return ok2([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
3071
3259
  }
3072
- return ok([x]);
3260
+ return ok2([x]);
3073
3261
  }
3074
3262
  if (fx === "size" && fy === "size") {
3075
3263
  const a = sizeOf(x);
3076
3264
  const b = sizeOf(y);
3077
- if (a.axis !== b.axis || a.attr !== b.attr) return ok([x]);
3265
+ if (a.axis !== b.axis || a.attr !== b.attr) return ok2([x]);
3078
3266
  if (side === "left") {
3079
3267
  const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
3080
- return ok([x], lost);
3268
+ return ok2([x], lost);
3081
3269
  }
3082
3270
  const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));
3083
3271
  const built = buildSize(x, next);
3084
3272
  const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
3085
- return ok(built ? [built] : [], [], dropped);
3273
+ return ok2(built ? [built] : [], [], dropped);
3086
3274
  }
3087
3275
  if (fx === "name" && fy === "name") {
3088
- if (side === "left") return ok([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
3089
- return ok([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
3276
+ if (side === "left") return ok2([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
3277
+ return ok2([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
3090
3278
  }
3091
- return ok([x]);
3279
+ return ok2([x]);
3092
3280
  }
3093
3281
  var blocked = (p) => !Array.isArray(p);
3094
3282
  function tSeq(xs, ys, side, acc) {
@@ -3267,10 +3455,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3267
3455
  let dropped = 0;
3268
3456
  for (let i = items.length - 1; i >= 0; i--) {
3269
3457
  const item = items[i];
3270
- let ok2 = true;
3458
+ let ok3 = true;
3271
3459
  for (const key of ["undoMutations", "redoMutations"]) {
3272
3460
  const list = item[key];
3273
- if (!ok2 || !list?.length) continue;
3461
+ if (!ok3 || !list?.length) continue;
3274
3462
  const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
3275
3463
  const operations = list.filter((m) => isOperation(m.id));
3276
3464
  let shaped = cachedShape(list);
@@ -3279,14 +3467,14 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3279
3467
  shapedLists.set(list, { src: list.slice(), shaped });
3280
3468
  }
3281
3469
  if (shaped.some((m) => m === null)) {
3282
- ok2 = false;
3470
+ ok3 = false;
3283
3471
  continue;
3284
3472
  }
3285
3473
  if (!shaped.length) continue;
3286
3474
  try {
3287
3475
  const r = transformGroup(shaped, remote, "left");
3288
3476
  if (isBarrier(r) || r.op.length === 0) {
3289
- ok2 = false;
3477
+ ok3 = false;
3290
3478
  continue;
3291
3479
  }
3292
3480
  if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
@@ -3294,10 +3482,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3294
3482
  shapedLists.set(next, { src: next.slice(), shaped: r.op });
3295
3483
  item[key] = next;
3296
3484
  } catch {
3297
- ok2 = false;
3485
+ ok3 = false;
3298
3486
  }
3299
3487
  }
3300
- if (!ok2) {
3488
+ if (!ok3) {
3301
3489
  items.splice(i, 1);
3302
3490
  dropped++;
3303
3491
  }
@@ -3518,7 +3706,7 @@ function univerSheetsOtPort(o) {
3518
3706
  return out;
3519
3707
  };
3520
3708
  const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
3521
- const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
3709
+ const openGroup = (label2) => ({ label: label2, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
3522
3710
  const emit = (e) => {
3523
3711
  for (const l of [...listeners]) {
3524
3712
  try {
@@ -3697,6 +3885,11 @@ function univerSheetsOtPort(o) {
3697
3885
  return { m, inverse: [{ id: "sheet.mutation.remove-col", params: { subUnitId: sheet, range: json(params.range) } }] };
3698
3886
  case ADD_MERGE:
3699
3887
  return { m, inverse: [{ id: REMOVE_MERGE, params: { subUnitId: sheet, ranges: json(params.ranges) } }] };
3888
+ case "sheet.mutation.reorder-range": {
3889
+ const order = {};
3890
+ for (const [t, src] of Object.entries(params.order ?? {})) order[String(src)] = Number(t);
3891
+ return { m, inverse: [{ id: info.id, params: { subUnitId: sheet, range: json(params.range), order } }] };
3892
+ }
3700
3893
  case SHEET_NAME:
3701
3894
  return { m, inverse: before2.name !== void 0 ? [{ id: SHEET_NAME, params: { subUnitId: sheet, name: before2.name } }] : void 0 };
3702
3895
  default:
@@ -3769,8 +3962,8 @@ function univerSheetsOtPort(o) {
3769
3962
  const a = forApply(m);
3770
3963
  applying = true;
3771
3964
  try {
3772
- const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
3773
- if (ok2 === false) throw new Error(`"${m.id}" was refused by the editor`);
3965
+ const ok3 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
3966
+ if (ok3 === false) throw new Error(`"${m.id}" was refused by the editor`);
3774
3967
  } finally {
3775
3968
  applying = false;
3776
3969
  }