@ai-matrx/office 0.8.12 → 0.8.13
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.
- package/CHANGELOG.md +2 -5
- package/dist/collab-sheets-transform.cjs +457 -39
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.d.cts +65 -7
- package/dist/collab-sheets-transform.d.ts +65 -7
- package/dist/collab-sheets-transform.js +463 -36
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/docs.cjs +30 -20
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.cts +22 -0
- package/dist/docs.d.ts +22 -0
- package/dist/docs.js +11 -1
- package/dist/docs.js.map +1 -1
- package/dist/univer-collab.cjs +201 -5
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +71 -2
- package/dist/univer-collab.d.ts +71 -2
- package/dist/univer-collab.js +201 -5
- package/dist/univer-collab.js.map +1 -1
- package/dist/univer.cjs +4 -0
- package/dist/univer.cjs.map +1 -1
- package/dist/univer.d.cts +3 -1
- package/dist/univer.d.ts +3 -1
- package/dist/univer.js +4 -0
- package/dist/univer.js.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.8.
|
|
3
|
+
## 0.8.13
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/office/src`.
|
|
7
|
-
|
|
8
|
-
## 0.8.11
|
|
5
|
+
- **`/collab/sheets-transform` covers formulas (C5b; still inert, no consumer).** A formula typed on one seat now has its references rewritten by a concurrent row/column insert, removal or move and by a concurrent sheet rename, in both commit orders, exactly as Univer's own `@univerjs/sheets-formula` interceptor rewrites them: A1 references, ranges, absolute and mixed markers, whole rows and columns, cross-sheet references, references into a removed range (`#REF!`), array formulas (`ref` range moves; dynamic arrays are plain formulas). Defined names (`formula.mutation.set-defined-name` / `remove-defined-name`) are covered: their ranges follow structural edits and renames, a renamed name is renamed inside concurrent formulas, a removed one becomes `#REF!`. A rewrite a structural op carries for formulas that already existed (`derived`) never outranks a person's concurrent write to the same cell or name. Shared formulas (`si`) stay barriers (the failing case is in `sheet-formula-hard-cases.test.ts`). Rewrites match real sheets-formula 1.0.4 on 476 oracle cases (`fixtures/sheets-formula-oracle.json`, made by `spikes/c5b-probe/oracle.mjs`). Pairwise TP1 fuzz: 20 families (210 pairs) at 4,000 seeds each, both orders, 0 divergences, 0 throws. New exports: `annotateFormulas`, `forApply`, `SIDE_CAR_PARAMS`, `rewriteFormula`, `formulaBarrier`, `isFormulaText`, `refSheetsFor`, `refSheetsAfter`, `REF_ERROR` and the `RefChange`/`RefSheets`/`FormulaCtx` types. `CONTENT_KEYS` gains `ref`, `xf`, `ft`, `fd`; `SHEET_TRANSFORMER_VERSION` is `c5b-1`. `@univerjs/engine-formula` moves from devDependencies to dependencies (the lexer runs in shipped code). Consumer action: none (nothing imports this section yet). For C6: capture must call `annotateFormulas` on each group (sheet id → name, defined-name id → name, read before the command) and apply through `forApply`; the canonical sheet hash must sort the defined-names resource by id.
|
|
9
6
|
|
|
10
7
|
- Docs co-editing (C3): a collaborator's edit now moves this seat's caret with the characters (§6.8). The view port gains an optional `selection { get, set }`; `DocumentModel` moves body ranges through each applied remote edit (`moveRangesThroughBodyEdit`). Found in the live two-browser run: with the caret left at its old offset, the next keystrokes landed scattered. Consumer action: pass `selection` from Univer's `DocSelectionManagerService` in the view port.
|
|
11
8
|
|
|
@@ -22,15 +22,24 @@ var transform_exports = {};
|
|
|
22
22
|
__export(transform_exports, {
|
|
23
23
|
CONTENT_KEYS: () => CONTENT_KEYS,
|
|
24
24
|
PAIR_BARRIERS: () => PAIR_BARRIERS,
|
|
25
|
+
REF_ERROR: () => REF_ERROR,
|
|
25
26
|
SHEET_MUTATIONS: () => SHEET_MUTATIONS,
|
|
26
27
|
SHEET_TRANSFORMER_VERSION: () => SHEET_TRANSFORMER_VERSION,
|
|
28
|
+
SIDE_CAR_PARAMS: () => SIDE_CAR_PARAMS,
|
|
27
29
|
allowParams: () => allowParams,
|
|
30
|
+
annotateFormulas: () => annotateFormulas,
|
|
28
31
|
cellRef: () => cellRef,
|
|
29
32
|
completeCellContent: () => completeCellContent,
|
|
30
33
|
exactMergeRemovals: () => exactMergeRemovals,
|
|
34
|
+
forApply: () => forApply,
|
|
35
|
+
formulaBarrier: () => formulaBarrier,
|
|
31
36
|
isBarrier: () => isBarrier,
|
|
37
|
+
isFormulaText: () => isFormulaText,
|
|
32
38
|
mapIndex: () => mapIndex,
|
|
33
39
|
mergeThrough: () => mergeThrough,
|
|
40
|
+
refSheetsAfter: () => refSheetsAfter,
|
|
41
|
+
refSheetsFor: () => refSheetsFor,
|
|
42
|
+
rewriteFormula: () => rewriteFormula,
|
|
34
43
|
sheetTransformer: () => sheetTransformer,
|
|
35
44
|
transformAxis: () => transformAxis,
|
|
36
45
|
transformGroup: () => transformGroup,
|
|
@@ -46,12 +55,11 @@ var covered = (family, ...allow) => ({ kind: "covered", family, allow: ["subUnit
|
|
|
46
55
|
var never = (reason) => ({ kind: "never-travels", reason });
|
|
47
56
|
var barrier = (until, reason) => ({ kind: "barrier", until, reason });
|
|
48
57
|
var FORMULA_RESULT = "formula engine output; every seat computes it (dropped at capture)";
|
|
49
|
-
var FORMULA = "formula state; C5b rewrites references";
|
|
50
58
|
var RESOURCE = "ranged resource keyed by id; C5c";
|
|
51
59
|
var UNIVER_COMMENTS = "Univer's own thread-comment store; our comments anchor elsewhere (design \xA78)";
|
|
52
60
|
var SHEET_MUTATIONS = {
|
|
53
61
|
// ── covered (C5a) ────────────────────────────────────────────────────────────────────────────────
|
|
54
|
-
"sheet.mutation.set-range-values": covered("cell", "cellValue"),
|
|
62
|
+
"sheet.mutation.set-range-values": covered("cell", "cellValue", "refSheets", "derived"),
|
|
55
63
|
"sheet.mutation.insert-row": covered("structure", "range", "rowInfo"),
|
|
56
64
|
"sheet.mutation.remove-rows": covered("structure", "range"),
|
|
57
65
|
"sheet.mutation.insert-col": covered("structure", "range", "colInfo"),
|
|
@@ -128,16 +136,16 @@ var SHEET_MUTATIONS = {
|
|
|
128
136
|
"sheet.mutation.set-worksheet-protection": barrier("X", "permissions: not in C5a"),
|
|
129
137
|
"sheet.mutation.delete-worksheet-protection": barrier("X", "permissions: not in C5a"),
|
|
130
138
|
"sheet.mutation.set-worksheet-permission-points": barrier("X", "permissions: not in C5a"),
|
|
131
|
-
// ──
|
|
132
|
-
"formula.mutation.set-defined-name":
|
|
133
|
-
"formula.mutation.remove-defined-name":
|
|
134
|
-
"formula.mutation.set-feature-calculation": barrier("
|
|
135
|
-
"formula.mutation.remove-feature-calculation": barrier("
|
|
136
|
-
"formula.mutation.set-other-formula": barrier("
|
|
137
|
-
"formula.mutation.remove-other-formula": barrier("
|
|
138
|
-
"formula.mutation.set-super-table": barrier("
|
|
139
|
-
"formula.mutation.remove-super-table": barrier("
|
|
140
|
-
"formula.mutation.set-super-table-option": barrier("
|
|
139
|
+
// ── formulas (C5b) ───────────────────────────────────────────────────────────────────────────────
|
|
140
|
+
"formula.mutation.set-defined-name": covered("defname", "id", "name", "formulaOrRefString", "formulaOrRefStringWithPrefix", "comment", "localSheetId", "hidden", "refSheets", "previousName", "derived"),
|
|
141
|
+
"formula.mutation.remove-defined-name": covered("defname", "id", "name"),
|
|
142
|
+
"formula.mutation.set-feature-calculation": barrier("X", "a plugin's registered calculation (feature id + dependency ranges); no transform yet"),
|
|
143
|
+
"formula.mutation.remove-feature-calculation": barrier("X", "a plugin's registered calculation; no transform yet"),
|
|
144
|
+
"formula.mutation.set-other-formula": barrier("C5c", "formulas owned by conditional formats and data validation travel with their rule"),
|
|
145
|
+
"formula.mutation.remove-other-formula": barrier("C5c", "formulas owned by conditional formats and data validation travel with their rule"),
|
|
146
|
+
"formula.mutation.set-super-table": barrier("C5c", "table names in structured references belong to tables (C5c)"),
|
|
147
|
+
"formula.mutation.remove-super-table": barrier("C5c", "table names in structured references belong to tables (C5c)"),
|
|
148
|
+
"formula.mutation.set-super-table-option": barrier("C5c", "table names in structured references belong to tables (C5c)"),
|
|
141
149
|
// ── barriers until C5c (ranged resources) ────────────────────────────────────────────────────────
|
|
142
150
|
"sheet.mutation.add-conditional-rule": barrier("C5c", RESOURCE),
|
|
143
151
|
"sheet.mutation.set-conditional-rule": barrier("C5c", RESOURCE),
|
|
@@ -181,7 +189,7 @@ function allowParams(id, params) {
|
|
|
181
189
|
}
|
|
182
190
|
|
|
183
191
|
// src/collab/sheets/transform/transform.ts
|
|
184
|
-
var
|
|
192
|
+
var import_sheets2 = require("@univerjs/sheets");
|
|
185
193
|
|
|
186
194
|
// src/collab/sheets/transform/axis.ts
|
|
187
195
|
function isNoopMove(op) {
|
|
@@ -294,8 +302,228 @@ function transformAxis(x, y, side) {
|
|
|
294
302
|
}
|
|
295
303
|
}
|
|
296
304
|
|
|
305
|
+
// src/collab/sheets/transform/formula.ts
|
|
306
|
+
var import_core = require("@univerjs/core");
|
|
307
|
+
var import_engine_formula = require("@univerjs/engine-formula");
|
|
308
|
+
var import_sheets = require("@univerjs/sheets");
|
|
309
|
+
var REF_ERROR = "#REF!";
|
|
310
|
+
var FULL = 16383 * 64;
|
|
311
|
+
var lexer = null;
|
|
312
|
+
var lex = (body) => (lexer ??= new import_engine_formula.LexerTreeBuilder()).sequenceNodesBuilder(body);
|
|
313
|
+
var isFormulaText = (f) => typeof f === "string" && f.length > 1 && f.startsWith("=");
|
|
314
|
+
var IDENT = /^[A-Za-z_\\][A-Za-z0-9_.\\]*$/;
|
|
315
|
+
var ERROR_TOKEN = /^(?:[^!]+!)?#(?:REF!|NAME\?|VALUE!|DIV\/0!|N\/A|NUM!|NULL!|SPILL!|CALC!)$/i;
|
|
316
|
+
function parse(text) {
|
|
317
|
+
const prefix = text.startsWith("=") ? "=" : "";
|
|
318
|
+
const nodes = lex(text.slice(prefix.length));
|
|
319
|
+
if (!nodes) return "the formula lexer could not read the text";
|
|
320
|
+
for (const n of nodes) {
|
|
321
|
+
if (typeof n === "string") continue;
|
|
322
|
+
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)";
|
|
323
|
+
if (n.nodeType === import_engine_formula.sequenceNodeType.FUNCTION && !IDENT.test(n.token) && !ERROR_TOKEN.test(n.token))
|
|
324
|
+
return `the lexer read "${n.token}" as one name (an intersection or a reference it cannot split)`;
|
|
325
|
+
if (n.nodeType === import_engine_formula.sequenceNodeType.REFERENCE) {
|
|
326
|
+
const d = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
|
|
327
|
+
if (d.unitId) return "a reference into another workbook";
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return { prefix, nodes };
|
|
331
|
+
}
|
|
332
|
+
function targetSheet(sheetName, ctx) {
|
|
333
|
+
if (!sheetName) return ctx.ownSheet;
|
|
334
|
+
const id = ctx.refSheets?.[sheetName];
|
|
335
|
+
if (id === void 0) return void 0;
|
|
336
|
+
return id ?? "";
|
|
337
|
+
}
|
|
338
|
+
function formulaBarrier(text, ctx) {
|
|
339
|
+
const p = parse(text);
|
|
340
|
+
if (typeof p === "string") return p;
|
|
341
|
+
for (const n of p.nodes) {
|
|
342
|
+
if (typeof n === "string" || n.nodeType !== import_engine_formula.sequenceNodeType.REFERENCE) continue;
|
|
343
|
+
const { sheetName } = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
|
|
344
|
+
if (targetSheet(sheetName, ctx) === void 0) return `sheet "${sheetName}" is not in refSheets (capture must call annotateRefSheets)`;
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
function referencedSheetNames(text) {
|
|
349
|
+
const p = parse(text);
|
|
350
|
+
if (typeof p === "string") return [];
|
|
351
|
+
const out = /* @__PURE__ */ new Set();
|
|
352
|
+
for (const n of p.nodes) if (typeof n !== "string" && n.nodeType === import_engine_formula.sequenceNodeType.REFERENCE) {
|
|
353
|
+
const { sheetName } = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
|
|
354
|
+
if (sheetName) out.add(sheetName);
|
|
355
|
+
}
|
|
356
|
+
return [...out];
|
|
357
|
+
}
|
|
358
|
+
var fullRowsRange = (start, count) => ({ startRow: start, endRow: start + count - 1, startColumn: 0, endColumn: FULL, rangeType: import_core.RANGE_TYPE.ROW });
|
|
359
|
+
var fullColsRange = (start, count) => ({ startRow: 0, endRow: FULL, startColumn: start, endColumn: start + count - 1, rangeType: import_core.RANGE_TYPE.COLUMN });
|
|
360
|
+
var startV = (v) => Number.isNaN(v) || v == null ? -Infinity : v;
|
|
361
|
+
var endV = (v) => Number.isNaN(v) || v == null ? Infinity : v;
|
|
362
|
+
function startEnd(r) {
|
|
363
|
+
return { ...r, startRow: startV(r.startRow), endRow: endV(r.endRow), startColumn: startV(r.startColumn), endColumn: endV(r.endColumn) };
|
|
364
|
+
}
|
|
365
|
+
function checkMoveEdge(origin, from) {
|
|
366
|
+
const startRow = startV(origin.startRow), endRow = endV(origin.endRow), startColumn = startV(origin.startColumn), endColumn = endV(origin.endColumn);
|
|
367
|
+
const fromStartRow = startV(from.startRow), fromEndRow = endV(from.endRow), fromStartColumn = startV(from.startColumn), fromEndColumn = endV(from.endColumn);
|
|
368
|
+
const rowsCover = () => origin.rangeType === import_core.RANGE_TYPE.COLUMN && from.rangeType === import_core.RANGE_TYPE.COLUMN || startRow >= fromStartRow && endRow <= fromEndRow;
|
|
369
|
+
const columnsCover = () => origin.rangeType === import_core.RANGE_TYPE.ROW && from.rangeType === import_core.RANGE_TYPE.ROW || startColumn >= fromStartColumn && endColumn <= fromEndColumn;
|
|
370
|
+
const allCover = () => origin.rangeType === import_core.RANGE_TYPE.ALL && from.rangeType === import_core.RANGE_TYPE.ALL;
|
|
371
|
+
if (rowsCover() && columnsCover() || allCover()) return 4;
|
|
372
|
+
if (columnsCover() && startRow >= fromStartRow && startRow <= fromEndRow && endRow > fromEndRow) return 0;
|
|
373
|
+
if (columnsCover() && endRow >= fromStartRow && endRow <= fromEndRow && startRow < fromStartRow) return 1;
|
|
374
|
+
if (rowsCover() && startColumn >= fromStartColumn && startColumn <= fromEndColumn && endColumn > fromEndColumn) return 2;
|
|
375
|
+
if (rowsCover() && endColumn >= fromStartColumn && endColumn <= fromEndColumn && startColumn < fromStartColumn) return 3;
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
function getMoveNewRange(moveEdge, result, from, to, origin, remain) {
|
|
379
|
+
const { startRow, endRow, startColumn, endColumn, rangeType } = startEnd(result);
|
|
380
|
+
const f = startEnd(from);
|
|
381
|
+
const fromRangeType = from.rangeType ?? import_core.RANGE_TYPE.NORMAL;
|
|
382
|
+
const t = startEnd(to);
|
|
383
|
+
const rm = startEnd(remain);
|
|
384
|
+
const o = startEnd(origin);
|
|
385
|
+
const originRangeType = origin.rangeType ?? import_core.RANGE_TYPE.NORMAL;
|
|
386
|
+
const newRange = { ...origin };
|
|
387
|
+
const rowsCover = () => rangeType === import_core.RANGE_TYPE.COLUMN && originRangeType === import_core.RANGE_TYPE.COLUMN || startColumn >= o.startColumn && endColumn <= o.endColumn;
|
|
388
|
+
const columnsCover = () => rangeType === import_core.RANGE_TYPE.ROW && originRangeType === import_core.RANGE_TYPE.ROW || startRow >= o.startRow && endRow <= o.endRow;
|
|
389
|
+
if (moveEdge === 0) {
|
|
390
|
+
if (!rowsCover()) return void 0;
|
|
391
|
+
if (startRow < o.startRow) newRange.startRow = startRow;
|
|
392
|
+
else if (startRow >= o.endRow) newRange.endRow -= f.endRow + 1 - o.startRow;
|
|
393
|
+
else return void 0;
|
|
394
|
+
} else if (moveEdge === 1) {
|
|
395
|
+
if (!rowsCover()) return void 0;
|
|
396
|
+
if (endRow > o.endRow) newRange.endRow = endRow;
|
|
397
|
+
else if (endRow <= o.startRow) newRange.startRow += o.endRow - f.startRow + 1;
|
|
398
|
+
else return void 0;
|
|
399
|
+
} else if (moveEdge === 2) {
|
|
400
|
+
if (!columnsCover()) return void 0;
|
|
401
|
+
if (startColumn < o.startColumn) newRange.startColumn = startColumn;
|
|
402
|
+
else if (startColumn >= o.endColumn) newRange.endColumn -= f.endColumn + 1 - o.startColumn;
|
|
403
|
+
else return void 0;
|
|
404
|
+
} else if (moveEdge === 3) {
|
|
405
|
+
if (!columnsCover()) return void 0;
|
|
406
|
+
if (endColumn > o.endColumn) newRange.endColumn = endColumn;
|
|
407
|
+
else if (endColumn <= o.startColumn) newRange.startColumn += o.endColumn - f.startColumn + 1;
|
|
408
|
+
else return void 0;
|
|
409
|
+
} else if (moveEdge === 4) {
|
|
410
|
+
Object.assign(newRange, { startRow, startColumn, endRow, endColumn });
|
|
411
|
+
} else if (f.startColumn <= o.startColumn && f.endColumn >= o.endColumn || fromRangeType === import_core.RANGE_TYPE.ROW && originRangeType === import_core.RANGE_TYPE.ROW) {
|
|
412
|
+
const n = f.endRow - f.startRow + 1;
|
|
413
|
+
if (from.endRow < o.startRow) {
|
|
414
|
+
if (t.startRow >= o.startRow) newRange.startRow -= n;
|
|
415
|
+
if (t.startRow >= o.endRow) newRange.endRow -= n;
|
|
416
|
+
} else if (from.startRow > o.endRow) {
|
|
417
|
+
if (t.endRow <= o.endRow) newRange.endRow += n;
|
|
418
|
+
if (t.endRow <= o.startRow) newRange.startRow += n;
|
|
419
|
+
} else if (from.startRow >= o.startRow && from.endRow <= o.endRow) {
|
|
420
|
+
if (t.startRow <= o.startRow) newRange.startRow += n;
|
|
421
|
+
else if (t.startRow >= o.endRow) newRange.endRow -= n;
|
|
422
|
+
}
|
|
423
|
+
} else if (f.startRow <= o.startRow && f.endRow >= o.endRow || fromRangeType === import_core.RANGE_TYPE.COLUMN && originRangeType === import_core.RANGE_TYPE.COLUMN) {
|
|
424
|
+
const n = f.endColumn - f.startColumn + 1;
|
|
425
|
+
if (from.endColumn < o.startColumn) {
|
|
426
|
+
if (t.startColumn >= o.startColumn) newRange.startColumn -= n;
|
|
427
|
+
if (t.startColumn >= o.endColumn) newRange.endColumn -= n;
|
|
428
|
+
} else if (from.startColumn > o.endColumn) {
|
|
429
|
+
if (t.endColumn <= o.endColumn) newRange.endColumn += n;
|
|
430
|
+
if (t.endColumn <= o.startColumn) newRange.startColumn += n;
|
|
431
|
+
} else if (from.startColumn >= o.startColumn && from.endColumn <= o.endColumn) {
|
|
432
|
+
if (t.startColumn <= o.startColumn) newRange.startColumn += n;
|
|
433
|
+
else if (t.startColumn >= o.endColumn) newRange.endColumn -= n;
|
|
434
|
+
}
|
|
435
|
+
} else {
|
|
436
|
+
Object.assign(newRange, { startRow, startColumn, endRow, endColumn });
|
|
437
|
+
void rm;
|
|
438
|
+
}
|
|
439
|
+
return newRange;
|
|
440
|
+
}
|
|
441
|
+
function moveRange(range, axis, op) {
|
|
442
|
+
const isRow = axis === "row";
|
|
443
|
+
if (op.kind === "insert") {
|
|
444
|
+
const r = isRow ? fullRowsRange(op.at, op.count) : fullColsRange(op.at, op.count);
|
|
445
|
+
const ops2 = isRow ? (0, import_sheets.handleInsertRow)({ id: import_sheets.EffectRefRangId.InsertRowCommandId, params: { range: r, unitId: "", subUnitId: "", direction: import_core.Direction.DOWN } }, range) : (0, import_sheets.handleInsertCol)({ id: import_sheets.EffectRefRangId.InsertColCommandId, params: { range: r, unitId: "", subUnitId: "", direction: import_core.Direction.RIGHT } }, range);
|
|
446
|
+
const res2 = (0, import_sheets.runRefRangeMutations)(ops2, range);
|
|
447
|
+
return res2 == null ? void 0 : { ...range, ...res2 };
|
|
448
|
+
}
|
|
449
|
+
if (op.kind === "remove") {
|
|
450
|
+
const r = isRow ? fullRowsRange(op.start, op.count) : fullColsRange(op.start, op.count);
|
|
451
|
+
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);
|
|
452
|
+
const res2 = (0, import_sheets.runRefRangeMutations)(ops2, range);
|
|
453
|
+
return res2 == null ? REF_ERROR : { ...range, ...res2 };
|
|
454
|
+
}
|
|
455
|
+
const from = isRow ? fullRowsRange(op.from, op.count) : fullColsRange(op.from, op.count);
|
|
456
|
+
const to = isRow ? fullRowsRange(op.to, op.count) : fullColsRange(op.to, op.count);
|
|
457
|
+
const moveEdge = checkMoveEdge(range, from);
|
|
458
|
+
let remain = (0, import_core.getIntersectRange)(range, from);
|
|
459
|
+
if (isRow) {
|
|
460
|
+
if (remain == null && (from.endRow < range.startRow && to.endRow <= range.startRow || from.startRow > range.endRow && to.startRow > range.endRow)) return void 0;
|
|
461
|
+
} else if (remain == null && (from.endColumn < range.startColumn && to.endColumn <= range.startColumn || from.startColumn > range.endColumn && to.startColumn > range.endColumn)) return void 0;
|
|
462
|
+
remain ??= { startRow: range.startRow, endRow: range.endRow, startColumn: range.startColumn, endColumn: range.endColumn, rangeType: import_core.RANGE_TYPE.NORMAL };
|
|
463
|
+
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);
|
|
464
|
+
const res = (0, import_sheets.runRefRangeMutations)(ops, remain);
|
|
465
|
+
if (res == null) return REF_ERROR;
|
|
466
|
+
return getMoveNewRange(moveEdge, res, from, to, range, remain);
|
|
467
|
+
}
|
|
468
|
+
function rewriteFormula(text, ctx, change) {
|
|
469
|
+
const p = parse(text);
|
|
470
|
+
if (typeof p === "string") return p;
|
|
471
|
+
const nodes = p.nodes.slice();
|
|
472
|
+
const changedIds = [];
|
|
473
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
474
|
+
const n = nodes[i];
|
|
475
|
+
if (typeof n === "string") continue;
|
|
476
|
+
if (change.kind === "defined-name") {
|
|
477
|
+
if ((n.nodeType === import_engine_formula.sequenceNodeType.DEFINED_NAME || n.nodeType === import_engine_formula.sequenceNodeType.FUNCTION) && n.token === change.from) {
|
|
478
|
+
nodes[i] = { ...n, token: change.to ?? REF_ERROR };
|
|
479
|
+
changedIds.push(i);
|
|
480
|
+
}
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (n.nodeType !== import_engine_formula.sequenceNodeType.REFERENCE) continue;
|
|
484
|
+
const { range, sheetName, unitId } = (0, import_engine_formula.deserializeRangeWithSheet)(n.token);
|
|
485
|
+
const target = targetSheet(sheetName, ctx);
|
|
486
|
+
if (target === void 0) return `sheet "${sheetName}" is not in refSheets (capture must call annotateRefSheets)`;
|
|
487
|
+
if (target !== change.sheet) continue;
|
|
488
|
+
let token;
|
|
489
|
+
if (change.kind === "rename") {
|
|
490
|
+
if (!sheetName) continue;
|
|
491
|
+
token = (0, import_engine_formula.serializeRangeToRefString)({ range, sheetName: change.name, unitId });
|
|
492
|
+
} else {
|
|
493
|
+
const moved = moveRange(import_core.Rectangle.moveOffset(range, 0, 0), change.axis, change.op);
|
|
494
|
+
if (moved === void 0) continue;
|
|
495
|
+
token = moved === REF_ERROR ? REF_ERROR : (0, import_engine_formula.serializeRangeToRefString)({ range: moved, sheetName: target === ctx.ownSheet && !ctx.keepQualifier ? "" : sheetName, unitId });
|
|
496
|
+
}
|
|
497
|
+
nodes[i] = { ...n, token };
|
|
498
|
+
changedIds.push(i);
|
|
499
|
+
}
|
|
500
|
+
if (!changedIds.length) return { text, changed: false };
|
|
501
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
502
|
+
const n = nodes[i];
|
|
503
|
+
if (typeof n === "string" || n.nodeType !== import_engine_formula.sequenceNodeType.REFERENCE || changedIds.includes(i)) continue;
|
|
504
|
+
nodes[i] = { ...n, token: (0, import_engine_formula.serializeRangeToRefString)((0, import_engine_formula.deserializeRangeWithSheet)(n.token)) };
|
|
505
|
+
}
|
|
506
|
+
const out = p.prefix + (0, import_engine_formula.generateStringWithSequence)(nodes);
|
|
507
|
+
return { text: out, changed: out !== text };
|
|
508
|
+
}
|
|
509
|
+
function refSheetsAfter(refSheets, change) {
|
|
510
|
+
if (change.kind !== "rename" || !refSheets) return refSheets;
|
|
511
|
+
const entries = Object.entries(refSheets);
|
|
512
|
+
if (!entries.some(([name, id]) => id === change.sheet || name === change.name)) return refSheets;
|
|
513
|
+
const next = {};
|
|
514
|
+
for (const [name, id] of entries) if (id !== change.sheet && name !== change.name) next[name] = id;
|
|
515
|
+
next[change.name] = change.sheet;
|
|
516
|
+
return next;
|
|
517
|
+
}
|
|
518
|
+
function refSheetsFor(texts, sheets) {
|
|
519
|
+
const byName = new Map(Object.entries(sheets).map(([id, name]) => [name, id]));
|
|
520
|
+
const out = {};
|
|
521
|
+
for (const t of texts) for (const name of referencedSheetNames(t)) out[name] = byName.get(name) ?? null;
|
|
522
|
+
return Object.keys(out).length ? out : void 0;
|
|
523
|
+
}
|
|
524
|
+
|
|
297
525
|
// src/collab/sheets/transform/transform.ts
|
|
298
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
526
|
+
var SHEET_TRANSFORMER_VERSION = "c5b-1";
|
|
299
527
|
var ID = {
|
|
300
528
|
values: "sheet.mutation.set-range-values",
|
|
301
529
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -310,7 +538,9 @@ var ID = {
|
|
|
310
538
|
rowIsAuto: "sheet.mutation.set-worksheet-row-is-auto-height",
|
|
311
539
|
rowAutoHeight: "sheet.mutation.set-worksheet-row-auto-height",
|
|
312
540
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
313
|
-
name: "sheet.mutation.set-worksheet-name"
|
|
541
|
+
name: "sheet.mutation.set-worksheet-name",
|
|
542
|
+
setName: "formula.mutation.set-defined-name",
|
|
543
|
+
removeName: "formula.mutation.remove-defined-name"
|
|
314
544
|
};
|
|
315
545
|
var PAIR_BARRIERS = {};
|
|
316
546
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -375,9 +605,9 @@ function buildStructural(template, axis, op) {
|
|
|
375
605
|
return { id: template.id, params: { ...p, range: { ...p.range, [a0]: start, [a1]: start + op.count - 1 } } };
|
|
376
606
|
}
|
|
377
607
|
function univerMutationInfo(axis, op) {
|
|
378
|
-
const
|
|
608
|
+
const FULL2 = { startRow: 0, endRow: Number.MAX_SAFE_INTEGER, startColumn: 0, endColumn: Number.MAX_SAFE_INTEGER };
|
|
379
609
|
const start = op.kind === "insert" ? op.at : op.start;
|
|
380
|
-
const range = axis === "row" ? { ...
|
|
610
|
+
const range = axis === "row" ? { ...FULL2, startRow: start, endRow: start + op.count - 1 } : { ...FULL2, startColumn: start, endColumn: start + op.count - 1 };
|
|
381
611
|
const id = op.kind === "insert" ? axis === "row" ? ID.insertRow : ID.insertCol : axis === "row" ? ID.removeRows : ID.removeCol;
|
|
382
612
|
return { id, params: { unitId: "", subUnitId: "", range } };
|
|
383
613
|
}
|
|
@@ -390,11 +620,11 @@ function mergeThrough(s, m) {
|
|
|
390
620
|
const op = s.op;
|
|
391
621
|
if (op.kind === "insert") {
|
|
392
622
|
const fixup = lo < op.at && op.at <= hi;
|
|
393
|
-
return { range: (0,
|
|
623
|
+
return { range: (0, import_sheets2.adjustRangeOnMutation)(m, univerMutationInfo(s.axis, op)), fixup };
|
|
394
624
|
}
|
|
395
625
|
if (op.kind === "remove") {
|
|
396
626
|
const e = op.start + op.count - 1;
|
|
397
|
-
if (e < lo || op.start > hi) return { range: (0,
|
|
627
|
+
if (e < lo || op.start > hi) return { range: (0, import_sheets2.adjustRangeOnMutation)(m, univerMutationInfo(s.axis, op)), fixup: false };
|
|
398
628
|
if (op.start <= lo && e >= hi) return { range: null, fixup: true };
|
|
399
629
|
const r = { ...m };
|
|
400
630
|
if (op.start >= lo && e <= hi) r[a1] = hi - op.count;
|
|
@@ -444,8 +674,8 @@ function exactMergeRemovals(group, merges) {
|
|
|
444
674
|
var mergeRanges = (m) => m.params.ranges ?? [];
|
|
445
675
|
var withRanges = (m, ranges) => ({ id: m.id, params: { ...m.params, ranges } });
|
|
446
676
|
var mergeMutation = (id, sheet, ranges) => ({ id, params: { subUnitId: sheet, ranges } });
|
|
447
|
-
var CONTENT_KEYS = ["v", "t", "p", "f", "si", "custom"];
|
|
448
|
-
var CONTENT_TOUCH = ["v", "p", "f", "si", "custom"];
|
|
677
|
+
var CONTENT_KEYS = ["v", "t", "p", "f", "si", "custom", "ref", "xf", "ft", "fd"];
|
|
678
|
+
var CONTENT_TOUCH = ["v", "p", "f", "si", "custom", "ref", "xf", "ft", "fd"];
|
|
449
679
|
var KNOWN_CELL_KEYS = /* @__PURE__ */ new Set([...CONTENT_KEYS, "s"]);
|
|
450
680
|
function completeCellContent(entry, post) {
|
|
451
681
|
if (entry === null) return null;
|
|
@@ -475,8 +705,10 @@ function cellBarrier(m) {
|
|
|
475
705
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
476
706
|
if (why || v === null) return;
|
|
477
707
|
for (const k of Object.keys(v)) {
|
|
708
|
+
if (why) break;
|
|
478
709
|
if (!KNOWN_CELL_KEYS.has(k)) why = `cell key "${k}" is not covered`;
|
|
479
|
-
else if (
|
|
710
|
+
else if (k === "si" && v.si != null) why = "shared formula (si): its text lives in a master cell this op does not carry";
|
|
711
|
+
else if (k === "f" && isFormulaText(v.f) || k === "ref" && typeof v.ref === "string") why = formulaBarrier(v[k], formulaCtx(m));
|
|
480
712
|
}
|
|
481
713
|
if (typeof v.s === "string") why = "a style id travels (style ids are seat-local; capture must send the style object)";
|
|
482
714
|
if (!why && CONTENT_TOUCH.some((k) => k in v) && !CONTENT_KEYS.every((k) => k in v || k === "t" && v.v == null))
|
|
@@ -549,6 +781,9 @@ function transformCell(X, Y, side) {
|
|
|
549
781
|
function transformCellsOverCells(x, y, side) {
|
|
550
782
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
551
783
|
const ycells = cellsOf(y);
|
|
784
|
+
const xd = isDerived(x);
|
|
785
|
+
const yd = isDerived(y);
|
|
786
|
+
const eff = derivedSide(x, y, side);
|
|
552
787
|
const passes = [{}];
|
|
553
788
|
const lost = [];
|
|
554
789
|
const dropped = [];
|
|
@@ -560,29 +795,218 @@ function transformCellsOverCells(x, y, side) {
|
|
|
560
795
|
putCell(passes[0], r, c, X);
|
|
561
796
|
return;
|
|
562
797
|
}
|
|
563
|
-
const res = transformCell(X, yRow[c] ?? null,
|
|
798
|
+
const res = transformCell(X, yRow[c] ?? null, eff);
|
|
564
799
|
if (typeof res === "string") {
|
|
565
800
|
why = res;
|
|
566
801
|
return;
|
|
567
802
|
}
|
|
568
803
|
res.entries.forEach((e, i) => putCell(passes[i] ??= {}, r, c, e));
|
|
569
|
-
if (res.xLost) dropped.push(cellRef(sheetOf(x), r, c));
|
|
570
|
-
if (res.yLost) lost.push(cellRef(sheetOf(x), r, c));
|
|
804
|
+
if (res.xLost && !xd) dropped.push(cellRef(sheetOf(x), r, c));
|
|
805
|
+
if (res.yLost && !yd) lost.push(cellRef(sheetOf(x), r, c));
|
|
571
806
|
});
|
|
572
807
|
if (why) return barrier2(why);
|
|
573
808
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
574
809
|
return ok(op, lost, dropped);
|
|
575
810
|
}
|
|
576
|
-
|
|
811
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
812
|
+
var isDerived = (m) => m.params.derived === true;
|
|
813
|
+
function derivedSide(x, y, side) {
|
|
814
|
+
const xd = isDerived(x);
|
|
815
|
+
const yd = isDerived(y);
|
|
816
|
+
return xd === yd ? side : xd ? "right" : "left";
|
|
817
|
+
}
|
|
818
|
+
function forApply(m) {
|
|
819
|
+
if (!SIDE_CAR_PARAMS.some((k) => k in m.params)) return m;
|
|
820
|
+
const params = { ...m.params };
|
|
821
|
+
for (const k of SIDE_CAR_PARAMS) delete params[k];
|
|
822
|
+
return { id: m.id, params };
|
|
823
|
+
}
|
|
824
|
+
var refSheetsOf = (m) => m.params.refSheets;
|
|
825
|
+
var formulaCtx = (m) => ({ ownSheet: sheetOf(m), refSheets: refSheetsOf(m) });
|
|
826
|
+
function withRefSheets(params, rs) {
|
|
827
|
+
const out = { ...params };
|
|
828
|
+
if (rs) out.refSheets = rs;
|
|
829
|
+
else delete out.refSheets;
|
|
830
|
+
return out;
|
|
831
|
+
}
|
|
832
|
+
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
833
|
+
function hasFormula(m) {
|
|
834
|
+
let any = false;
|
|
835
|
+
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
836
|
+
any ||= hasFormulaText(v);
|
|
837
|
+
});
|
|
838
|
+
return any;
|
|
839
|
+
}
|
|
840
|
+
var setNameWithoutPrevious = (m) => m.id === ID.setName && !("previousName" in m.params);
|
|
841
|
+
function refChangeOf(m) {
|
|
842
|
+
const st = structuralOf(m);
|
|
843
|
+
if (st) return { kind: "axis", sheet: sheetOf(m), axis: st.axis, op: st.op };
|
|
844
|
+
if (m.id === ID.name) return { kind: "rename", sheet: sheetOf(m), name: String(m.params.name) };
|
|
845
|
+
if (m.id === ID.removeName) return { kind: "defined-name", from: String(m.params.name), to: null };
|
|
846
|
+
if (m.id === ID.setName && typeof m.params.previousName === "string" && m.params.previousName !== m.params.name)
|
|
847
|
+
return { kind: "defined-name", from: m.params.previousName, to: String(m.params.name) };
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
function rewriteEntry(v, ctx, change) {
|
|
851
|
+
let entry = v;
|
|
852
|
+
let changed = false;
|
|
853
|
+
for (const k of ["f", "ref"]) {
|
|
854
|
+
const t = v[k];
|
|
855
|
+
if (k === "f" ? !isFormulaText(t) : typeof t !== "string") continue;
|
|
856
|
+
const r = rewriteFormula(t, ctx, change);
|
|
857
|
+
if (typeof r === "string") return r;
|
|
858
|
+
if (!r.changed) continue;
|
|
859
|
+
if (k === "ref" && r.text.includes(REF_ERROR)) return "an array formula's range was removed under it";
|
|
860
|
+
entry = { ...entry, [k]: r.text };
|
|
861
|
+
changed = true;
|
|
862
|
+
}
|
|
863
|
+
return { entry, changed };
|
|
864
|
+
}
|
|
865
|
+
function cellThrough(sheet, change, r, c) {
|
|
866
|
+
if (change.kind !== "axis" || change.sheet !== sheet) return [r, c];
|
|
867
|
+
const nr = change.axis === "row" ? mapIndex(change.op, r) : r;
|
|
868
|
+
const nc = change.axis === "col" ? mapIndex(change.op, c) : c;
|
|
869
|
+
return nr === null || nc === null ? null : [nr, nc];
|
|
870
|
+
}
|
|
871
|
+
function cellsOverChange(x, change) {
|
|
872
|
+
const ctx = formulaCtx(x);
|
|
577
873
|
const out = {};
|
|
578
874
|
const dropped = [];
|
|
875
|
+
let why = null;
|
|
579
876
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
580
|
-
|
|
581
|
-
const
|
|
582
|
-
if (
|
|
583
|
-
|
|
877
|
+
if (why) return;
|
|
878
|
+
const at = cellThrough(sheetOf(x), change, r, c);
|
|
879
|
+
if (!at) {
|
|
880
|
+
dropped.push(cellRef(sheetOf(x), r, c));
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
let e = v;
|
|
884
|
+
if (hasFormulaText(v)) {
|
|
885
|
+
const res = rewriteEntry(v, ctx, change);
|
|
886
|
+
if (typeof res === "string") {
|
|
887
|
+
why = res;
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
e = res.entry;
|
|
891
|
+
}
|
|
892
|
+
putCell(out, at[0], at[1], e);
|
|
893
|
+
});
|
|
894
|
+
if (why) return barrier2(why);
|
|
895
|
+
const params = { ...withRefSheets(x.params, refSheetsAfter(ctx.refSheets, change)), cellValue: out };
|
|
896
|
+
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
897
|
+
}
|
|
898
|
+
function rewritesOf(y, change) {
|
|
899
|
+
const ctx = formulaCtx(y);
|
|
900
|
+
const out = {};
|
|
901
|
+
let why = null;
|
|
902
|
+
forEachCell(cellsOf(y), (r, c, v) => {
|
|
903
|
+
if (why || !hasFormulaText(v)) return;
|
|
904
|
+
const at = cellThrough(sheetOf(y), change, r, c);
|
|
905
|
+
if (!at) return;
|
|
906
|
+
const res = rewriteEntry(v, ctx, change);
|
|
907
|
+
if (typeof res === "string") {
|
|
908
|
+
why = res;
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
if (res.changed) putCell(out, at[0], at[1], contentOf(res.entry));
|
|
912
|
+
});
|
|
913
|
+
if (why) return why;
|
|
914
|
+
if (isEmptyMatrix(out)) return null;
|
|
915
|
+
return { id: ID.values, params: withRefSheets({ subUnitId: sheetOf(y), cellValue: out, derived: true }, refSheetsAfter(ctx.refSheets, change)) };
|
|
916
|
+
}
|
|
917
|
+
var NAME_TEXT_KEYS = ["formulaOrRefString", "formulaOrRefStringWithPrefix"];
|
|
918
|
+
function definedNameThrough(m, change) {
|
|
919
|
+
if (change.kind === "defined-name" || m.id !== ID.setName) return { op: m, changed: false };
|
|
920
|
+
const ctx = { ownSheet: change.sheet, refSheets: refSheetsOf(m), keepQualifier: true };
|
|
921
|
+
const params = { ...m.params };
|
|
922
|
+
let changed = false;
|
|
923
|
+
for (const k of NAME_TEXT_KEYS) {
|
|
924
|
+
if (typeof params[k] !== "string" || !params[k]) continue;
|
|
925
|
+
const r = rewriteFormula(params[k], ctx, change);
|
|
926
|
+
if (typeof r === "string") return r;
|
|
927
|
+
if (r.changed) {
|
|
928
|
+
params[k] = r.text;
|
|
929
|
+
changed = true;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return { op: { id: m.id, params: withRefSheets(params, refSheetsAfter(ctx.refSheets, change)) }, changed };
|
|
933
|
+
}
|
|
934
|
+
function asDerived(m) {
|
|
935
|
+
return { id: m.id, params: { ...m.params, derived: true } };
|
|
936
|
+
}
|
|
937
|
+
function formulaPair(x, y, side) {
|
|
938
|
+
const fx = familyOf(x.id);
|
|
939
|
+
const fy = familyOf(y.id);
|
|
940
|
+
const SET_NAME_BARRIER = "set-defined-name without previousName (capture must record the name it replaces) against formula text";
|
|
941
|
+
if (fx === "defname" && fy === "defname") {
|
|
942
|
+
if (String(x.params.id) !== String(y.params.id)) return ok([x]);
|
|
943
|
+
const eff = derivedSide(x, y, side);
|
|
944
|
+
if (eff === "left") return ok([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
|
|
945
|
+
return ok([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
|
|
946
|
+
}
|
|
947
|
+
if (fx === "defname") {
|
|
948
|
+
if (fy === "cell") {
|
|
949
|
+
if (setNameWithoutPrevious(x) && hasFormula(y)) return barrier2(SET_NAME_BARRIER);
|
|
950
|
+
const ch2 = refChangeOf(x);
|
|
951
|
+
if (!ch2) return ok([x]);
|
|
952
|
+
const add = rewritesOf(y, ch2);
|
|
953
|
+
if (typeof add === "string") return barrier2(add);
|
|
954
|
+
return ok(add ? [x, add] : [x]);
|
|
955
|
+
}
|
|
956
|
+
const ch = refChangeOf(y);
|
|
957
|
+
if (!ch) return ok([x]);
|
|
958
|
+
const r = definedNameThrough(x, ch);
|
|
959
|
+
return typeof r === "string" ? barrier2(r) : ok([r.op]);
|
|
960
|
+
}
|
|
961
|
+
if (fy === "defname") {
|
|
962
|
+
if (fx === "cell") {
|
|
963
|
+
if (setNameWithoutPrevious(y) && hasFormula(x)) return barrier2(SET_NAME_BARRIER);
|
|
964
|
+
const ch2 = refChangeOf(y);
|
|
965
|
+
return ch2 ? cellsOverChange(x, ch2) : ok([x]);
|
|
966
|
+
}
|
|
967
|
+
const ch = refChangeOf(x);
|
|
968
|
+
if (!ch) return ok([x]);
|
|
969
|
+
const r = definedNameThrough(y, ch);
|
|
970
|
+
if (typeof r === "string") return barrier2(r);
|
|
971
|
+
return ok(r.changed ? [x, asDerived(r.op)] : [x]);
|
|
972
|
+
}
|
|
973
|
+
if (fx === "cell") {
|
|
974
|
+
const ch = refChangeOf(y);
|
|
975
|
+
return ch ? cellsOverChange(x, ch) : null;
|
|
976
|
+
}
|
|
977
|
+
if (fy === "cell") {
|
|
978
|
+
const ch = refChangeOf(x);
|
|
979
|
+
if (!ch) return null;
|
|
980
|
+
const lost = [];
|
|
981
|
+
forEachCell(cellsOf(y), (r, c) => {
|
|
982
|
+
if (!cellThrough(sheetOf(y), ch, r, c)) lost.push(cellRef(sheetOf(y), r, c));
|
|
983
|
+
});
|
|
984
|
+
const add = rewritesOf(y, ch);
|
|
985
|
+
if (typeof add === "string") return barrier2(add);
|
|
986
|
+
return ok(add ? [x, add] : [x], lost);
|
|
987
|
+
}
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
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;
|
|
991
|
+
function annotateFormulas(group, sheets, definedNames) {
|
|
992
|
+
let changed = false;
|
|
993
|
+
return group.map((m0) => {
|
|
994
|
+
const m = changed && (m0.id === ID.values || m0.id === ID.setName) ? asDerived(m0) : m0;
|
|
995
|
+
if (!changed && refChangeOf(withPrevious(m0, definedNames))) changed = true;
|
|
996
|
+
if (m.id === ID.values) {
|
|
997
|
+
const texts = [];
|
|
998
|
+
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
999
|
+
if (v && isFormulaText(v.f)) texts.push(v.f);
|
|
1000
|
+
if (v && typeof v.ref === "string") texts.push(v.ref);
|
|
1001
|
+
});
|
|
1002
|
+
return { id: m.id, params: withRefSheets(m.params, refSheetsFor(texts, sheets)) };
|
|
1003
|
+
}
|
|
1004
|
+
if (m.id === ID.setName) {
|
|
1005
|
+
const texts = NAME_TEXT_KEYS.map((k) => m.params[k]).filter((t) => typeof t === "string");
|
|
1006
|
+
return { id: m.id, params: { ...withRefSheets(m.params, refSheetsFor(texts, sheets)), previousName: withPrevious(m, definedNames).params.previousName } };
|
|
1007
|
+
}
|
|
1008
|
+
return m;
|
|
584
1009
|
});
|
|
585
|
-
return ok(isEmptyMatrix(out) ? [] : [cellsMutation(x, out)], [], dropped);
|
|
586
1010
|
}
|
|
587
1011
|
function sizeOf(m) {
|
|
588
1012
|
const p = m.params;
|
|
@@ -633,6 +1057,8 @@ function transformMutation(x, y, side) {
|
|
|
633
1057
|
}
|
|
634
1058
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
635
1059
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
1060
|
+
const fp = formulaPair(x, y, side);
|
|
1061
|
+
if (fp) return fp;
|
|
636
1062
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
637
1063
|
const fx = familyOf(x.id);
|
|
638
1064
|
const fy = familyOf(y.id);
|
|
@@ -646,7 +1072,6 @@ function transformMutation(x, y, side) {
|
|
|
646
1072
|
return ok(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
|
|
647
1073
|
}
|
|
648
1074
|
if (sy) {
|
|
649
|
-
if (fx === "cell") return transformCellsOverStructural(x, sy);
|
|
650
1075
|
if (fx === "merge") {
|
|
651
1076
|
const kept = [];
|
|
652
1077
|
const dropped = [];
|
|
@@ -671,13 +1096,6 @@ function transformMutation(x, y, side) {
|
|
|
671
1096
|
return ok([x]);
|
|
672
1097
|
}
|
|
673
1098
|
if (sx) {
|
|
674
|
-
if (fy === "cell") {
|
|
675
|
-
const lost = [];
|
|
676
|
-
forEachCell(cellsOf(y), (r, c) => {
|
|
677
|
-
if ((sx.axis === "row" ? mapIndex(sx.op, r) : mapIndex(sx.op, c)) === null) lost.push(cellRef(sheetOf(y), r, c));
|
|
678
|
-
});
|
|
679
|
-
return ok([x], lost);
|
|
680
|
-
}
|
|
681
1099
|
if (fy !== "merge" || y.id !== ID.addMerge) return ok([x]);
|
|
682
1100
|
const remove = [];
|
|
683
1101
|
const add = [];
|