@ai-matrx/office 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/collab-sheets-transform.cjs +789 -0
- package/dist/collab-sheets-transform.cjs.map +1 -0
- package/dist/collab-sheets-transform.d.cts +159 -0
- package/dist/collab-sheets-transform.d.ts +159 -0
- package/dist/collab-sheets-transform.js +766 -0
- package/dist/collab-sheets-transform.js.map +1 -0
- package/dist/docs.cjs +178 -29
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.cts +83 -2
- package/dist/docs.d.ts +83 -2
- package/dist/docs.js +155 -6
- package/dist/docs.js.map +1 -1
- package/dist/univer-collab.cjs +1017 -4
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +259 -1
- package/dist/univer-collab.d.ts +259 -1
- package/dist/univer-collab.js +1023 -4
- package/dist/univer-collab.js.map +1 -1
- package/package.json +19 -5
|
@@ -0,0 +1,789 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/collab/sheets/transform/index.ts
|
|
21
|
+
var transform_exports = {};
|
|
22
|
+
__export(transform_exports, {
|
|
23
|
+
CONTENT_KEYS: () => CONTENT_KEYS,
|
|
24
|
+
PAIR_BARRIERS: () => PAIR_BARRIERS,
|
|
25
|
+
SHEET_MUTATIONS: () => SHEET_MUTATIONS,
|
|
26
|
+
SHEET_TRANSFORMER_VERSION: () => SHEET_TRANSFORMER_VERSION,
|
|
27
|
+
allowParams: () => allowParams,
|
|
28
|
+
cellRef: () => cellRef,
|
|
29
|
+
completeCellContent: () => completeCellContent,
|
|
30
|
+
exactMergeRemovals: () => exactMergeRemovals,
|
|
31
|
+
isBarrier: () => isBarrier,
|
|
32
|
+
mapIndex: () => mapIndex,
|
|
33
|
+
mergeThrough: () => mergeThrough,
|
|
34
|
+
sheetTransformer: () => sheetTransformer,
|
|
35
|
+
transformAxis: () => transformAxis,
|
|
36
|
+
transformGroup: () => transformGroup,
|
|
37
|
+
transformMutation: () => transformMutation
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(transform_exports);
|
|
40
|
+
|
|
41
|
+
// src/collab/sheets/transform/types.ts
|
|
42
|
+
var isBarrier = (r) => r.barrier === true;
|
|
43
|
+
|
|
44
|
+
// src/collab/sheets/transform/registry.ts
|
|
45
|
+
var covered = (family, ...allow) => ({ kind: "covered", family, allow: ["subUnitId", ...allow] });
|
|
46
|
+
var never = (reason) => ({ kind: "never-travels", reason });
|
|
47
|
+
var barrier = (until, reason) => ({ kind: "barrier", until, reason });
|
|
48
|
+
var FORMULA_RESULT = "formula engine output; every seat computes it (dropped at capture)";
|
|
49
|
+
var FORMULA = "formula state; C5b rewrites references";
|
|
50
|
+
var RESOURCE = "ranged resource keyed by id; C5c";
|
|
51
|
+
var UNIVER_COMMENTS = "Univer's own thread-comment store; our comments anchor elsewhere (design \xA78)";
|
|
52
|
+
var SHEET_MUTATIONS = {
|
|
53
|
+
// ── covered (C5a) ────────────────────────────────────────────────────────────────────────────────
|
|
54
|
+
"sheet.mutation.set-range-values": covered("cell", "cellValue"),
|
|
55
|
+
"sheet.mutation.insert-row": covered("structure", "range", "rowInfo"),
|
|
56
|
+
"sheet.mutation.remove-rows": covered("structure", "range"),
|
|
57
|
+
"sheet.mutation.insert-col": covered("structure", "range", "colInfo"),
|
|
58
|
+
"sheet.mutation.remove-col": covered("structure", "range"),
|
|
59
|
+
"sheet.mutation.move-rows": covered("structure", "sourceRange", "targetRange"),
|
|
60
|
+
"sheet.mutation.move-columns": covered("structure", "sourceRange", "targetRange"),
|
|
61
|
+
"sheet.mutation.add-worksheet-merge": covered("merge", "ranges"),
|
|
62
|
+
"sheet.mutation.remove-worksheet-merge": covered("merge", "ranges"),
|
|
63
|
+
"sheet.mutation.set-worksheet-row-height": covered("size", "ranges", "rowHeight"),
|
|
64
|
+
"sheet.mutation.set-worksheet-row-is-auto-height": covered("size", "ranges", "autoHeightInfo"),
|
|
65
|
+
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
66
|
+
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
67
|
+
"sheet.mutation.set-worksheet-name": covered("name", "name"),
|
|
68
|
+
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
69
|
+
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
70
|
+
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
71
|
+
"formula.mutation.set-formula-calculation-stop": never(FORMULA_RESULT),
|
|
72
|
+
"formula.mutation.set-formula-calculation-notification": never(FORMULA_RESULT),
|
|
73
|
+
"formula.mutation.set-formula-calculation-result": never(FORMULA_RESULT),
|
|
74
|
+
"formula.mutation.set-array-formula-data": never(FORMULA_RESULT),
|
|
75
|
+
"formula.mutation.set-formula-data": never(FORMULA_RESULT),
|
|
76
|
+
"formula.mutation.set-image-formula-data": never(FORMULA_RESULT),
|
|
77
|
+
"formula.mutation.set-formula-string-batch-calculation": never(FORMULA_RESULT),
|
|
78
|
+
"formula.mutation.set-formula-string-batch-calculation-result": never(FORMULA_RESULT),
|
|
79
|
+
"formula.mutation.set-formula-dependency-calculation": never(FORMULA_RESULT),
|
|
80
|
+
"formula.mutation.set-formula-dependency-calculation-result": never(FORMULA_RESULT),
|
|
81
|
+
"formula.mutation.set-cell-formula-dependency-calculation": never(FORMULA_RESULT),
|
|
82
|
+
"formula.mutation.set-cell-formula-dependency-calculation-result": never(FORMULA_RESULT),
|
|
83
|
+
"formula.mutation.set-query-formula-dependency": never(FORMULA_RESULT),
|
|
84
|
+
"formula.mutation.set-query-formula-dependency-result": never(FORMULA_RESULT),
|
|
85
|
+
"formula.mutation.set-query-formula-dependency-all": never(FORMULA_RESULT),
|
|
86
|
+
"formula.mutation.set-query-formula-dependency-all-result": never(FORMULA_RESULT),
|
|
87
|
+
"formula.mutation.register-function": never("registers a function body on this seat's engine"),
|
|
88
|
+
"sheet.mutation.data-validation-formula-mark-dirty": never("dirty mark"),
|
|
89
|
+
"sheet.mutation.mark-dirty-filter-change": never("dirty mark"),
|
|
90
|
+
"sheet.mutation.re-calc-filter": never("filter recalculation result"),
|
|
91
|
+
"sheet.mutation.toggle-note-popup": never("popup state"),
|
|
92
|
+
"sheet.operation.clear-drawing-transformer": never("drawing selection handles (declared as a mutation)"),
|
|
93
|
+
"sheet.mutation.copy-worksheet-end": never("end marker of a copy; the copy travels as insert-sheet"),
|
|
94
|
+
"sheet.mutation.empty": never("no content"),
|
|
95
|
+
"thread-comment.mutation.add-comment": never(UNIVER_COMMENTS),
|
|
96
|
+
"thread-comment.mutation.update-comment": never(UNIVER_COMMENTS),
|
|
97
|
+
"thread-comment.mutation.update-comment-ref": never(UNIVER_COMMENTS),
|
|
98
|
+
"thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
|
|
99
|
+
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
100
|
+
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
101
|
+
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
102
|
+
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
103
|
+
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
104
|
+
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
105
|
+
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
106
|
+
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
107
|
+
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
108
|
+
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
109
|
+
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
110
|
+
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
111
|
+
"sheet.mutation.set-worksheet-right-to-left": barrier("X", "sheet-level setting: not in C5a"),
|
|
112
|
+
"sheet.mutation.toggle-gridlines": barrier("X", "sheet-level setting: not in C5a"),
|
|
113
|
+
"sheet.mutation.set-gridlines-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
114
|
+
"sheet.mutation.set-worksheet-default-style": barrier("X", "sheet-level setting: not in C5a"),
|
|
115
|
+
"sheet.mutation.set-frozen": barrier("X", "absolute frozen indices: not in C5a"),
|
|
116
|
+
"sheet.mutation.set-row-data": barrier("X", "row properties by index: not in C5a"),
|
|
117
|
+
"sheet.mutation.set-col-data": barrier("X", "column properties by index: not in C5a"),
|
|
118
|
+
"sheet.mutation.set-row-hidden": barrier("X", "row visibility: not in C5a"),
|
|
119
|
+
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
120
|
+
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
121
|
+
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
122
|
+
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
123
|
+
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
124
|
+
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
125
|
+
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
126
|
+
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
127
|
+
"sheet.mutation.add-worksheet-protection": barrier("X", "permissions: not in C5a"),
|
|
128
|
+
"sheet.mutation.set-worksheet-protection": barrier("X", "permissions: not in C5a"),
|
|
129
|
+
"sheet.mutation.delete-worksheet-protection": barrier("X", "permissions: not in C5a"),
|
|
130
|
+
"sheet.mutation.set-worksheet-permission-points": barrier("X", "permissions: not in C5a"),
|
|
131
|
+
// ── barriers until C5b (formulas) ────────────────────────────────────────────────────────────────
|
|
132
|
+
"formula.mutation.set-defined-name": barrier("C5b", FORMULA),
|
|
133
|
+
"formula.mutation.remove-defined-name": barrier("C5b", FORMULA),
|
|
134
|
+
"formula.mutation.set-feature-calculation": barrier("C5b", FORMULA),
|
|
135
|
+
"formula.mutation.remove-feature-calculation": barrier("C5b", FORMULA),
|
|
136
|
+
"formula.mutation.set-other-formula": barrier("C5b", FORMULA),
|
|
137
|
+
"formula.mutation.remove-other-formula": barrier("C5b", FORMULA),
|
|
138
|
+
"formula.mutation.set-super-table": barrier("C5b", FORMULA),
|
|
139
|
+
"formula.mutation.remove-super-table": barrier("C5b", FORMULA),
|
|
140
|
+
"formula.mutation.set-super-table-option": barrier("C5b", FORMULA),
|
|
141
|
+
// ── barriers until C5c (ranged resources) ────────────────────────────────────────────────────────
|
|
142
|
+
"sheet.mutation.add-conditional-rule": barrier("C5c", RESOURCE),
|
|
143
|
+
"sheet.mutation.set-conditional-rule": barrier("C5c", RESOURCE),
|
|
144
|
+
"sheet.mutation.delete-conditional-rule": barrier("C5c", RESOURCE),
|
|
145
|
+
"sheet.mutation.move-conditional-rule": barrier("C5c", "conditional-format priority (ordered list)"),
|
|
146
|
+
"data-validation.mutation.addRule": barrier("C5c", RESOURCE),
|
|
147
|
+
"data-validation.mutation.updateRule": barrier("C5c", RESOURCE),
|
|
148
|
+
"data-validation.mutation.removeRule": barrier("C5c", RESOURCE),
|
|
149
|
+
"sheet.mutation.set-filter-range": barrier("C5c", RESOURCE),
|
|
150
|
+
"sheet.mutation.set-filter-criteria": barrier("C5c", RESOURCE),
|
|
151
|
+
"sheet.mutation.remove-filter": barrier("C5c", RESOURCE),
|
|
152
|
+
"sheet.mutation.add-table": barrier("C5c", RESOURCE),
|
|
153
|
+
"sheet.mutation.delete-table": barrier("C5c", RESOURCE),
|
|
154
|
+
"sheet.mutation.set-sheet-table": barrier("C5c", RESOURCE),
|
|
155
|
+
"sheet.mutation.set-table-filter": barrier("C5c", RESOURCE),
|
|
156
|
+
"sheet.mutation.move-table": barrier("C5c", RESOURCE),
|
|
157
|
+
"sheets.mutation.add-hyper-link": barrier("C5c", RESOURCE),
|
|
158
|
+
"sheets.mutation.remove-hyper-link": barrier("C5c", RESOURCE),
|
|
159
|
+
"sheets.mutation.update-hyper-link": barrier("C5c", RESOURCE),
|
|
160
|
+
"sheets.mutation.update-hyper-link-ref": barrier("C5c", RESOURCE),
|
|
161
|
+
"sheets.mutation.update-rich-hyper-link": barrier("C5c", RESOURCE),
|
|
162
|
+
"sheet.mutation.update-note": barrier("C5c", RESOURCE),
|
|
163
|
+
"sheet.mutation.remove-note": barrier("C5c", RESOURCE),
|
|
164
|
+
"sheet.mutation.update-note-position": barrier("C5c", RESOURCE),
|
|
165
|
+
"sheet.mutation.set-drawing-apply": barrier("C5c", RESOURCE),
|
|
166
|
+
"sheet.mutation.set-worksheet-background-image": barrier("C5c", RESOURCE),
|
|
167
|
+
"sheet.mutation.add-range-theme": barrier("C5c", RESOURCE),
|
|
168
|
+
"sheet.mutation.set-range-theme": barrier("C5c", RESOURCE),
|
|
169
|
+
"sheet.mutation.remove-range-theme": barrier("C5c", RESOURCE),
|
|
170
|
+
"sheet.mutation.set-worksheet-range-theme-style": barrier("C5c", RESOURCE),
|
|
171
|
+
"sheet.mutation.remove-worksheet-range-theme-style": barrier("C5c", RESOURCE),
|
|
172
|
+
"sheet.mutation.register-worksheet-range-theme-style": barrier("C5c", RESOURCE),
|
|
173
|
+
"sheet.mutation.unregister-worksheet-range-theme-style": barrier("C5c", RESOURCE)
|
|
174
|
+
};
|
|
175
|
+
function allowParams(id, params) {
|
|
176
|
+
const entry = SHEET_MUTATIONS[id];
|
|
177
|
+
if (!entry || entry.kind !== "covered") return null;
|
|
178
|
+
const out = {};
|
|
179
|
+
for (const f of entry.allow) if (params[f] !== void 0) out[f] = params[f];
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/collab/sheets/transform/transform.ts
|
|
184
|
+
var import_sheets = require("@univerjs/sheets");
|
|
185
|
+
|
|
186
|
+
// src/collab/sheets/transform/axis.ts
|
|
187
|
+
function isNoopMove(op) {
|
|
188
|
+
return op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count;
|
|
189
|
+
}
|
|
190
|
+
function movedBlockStart(op) {
|
|
191
|
+
return op.to > op.from ? op.to - op.count : op.to;
|
|
192
|
+
}
|
|
193
|
+
function mapIndex(op, i) {
|
|
194
|
+
switch (op.kind) {
|
|
195
|
+
case "insert":
|
|
196
|
+
return i >= op.at ? i + op.count : i;
|
|
197
|
+
case "remove":
|
|
198
|
+
if (i < op.start) return i;
|
|
199
|
+
if (i < op.start + op.count) return null;
|
|
200
|
+
return i - op.count;
|
|
201
|
+
case "move": {
|
|
202
|
+
if (isNoopMove(op)) return i;
|
|
203
|
+
const { from, count, to } = op;
|
|
204
|
+
if (i >= from && i < from + count) return movedBlockStart(op) + (i - from);
|
|
205
|
+
if (to > from) return i >= from + count && i < to ? i - count : i;
|
|
206
|
+
return i >= to && i < from ? i + count : i;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function runs(indices) {
|
|
211
|
+
const sorted = [...new Set(indices)].sort((a, b) => a - b);
|
|
212
|
+
const out = [];
|
|
213
|
+
for (const i of sorted) {
|
|
214
|
+
const last = out[out.length - 1];
|
|
215
|
+
if (last && last.start + last.count === i) last.count++;
|
|
216
|
+
else out.push({ start: i, count: 1 });
|
|
217
|
+
}
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
function mapGapThroughMove(p, mv) {
|
|
221
|
+
const { from, count, to } = mv;
|
|
222
|
+
if (p > from && p < from + count) return movedBlockStart(mv) + (p - from);
|
|
223
|
+
const g = p <= from ? p : p - count;
|
|
224
|
+
const tg = to <= from ? to : to - count;
|
|
225
|
+
return g <= tg ? g : g + count;
|
|
226
|
+
}
|
|
227
|
+
function transformAxis(x, y, side) {
|
|
228
|
+
if (y.kind === "move" && isNoopMove(y)) return [x];
|
|
229
|
+
if (x.kind === "move" && isNoopMove(x)) return [];
|
|
230
|
+
switch (x.kind) {
|
|
231
|
+
case "insert": {
|
|
232
|
+
if (y.kind === "insert") {
|
|
233
|
+
if (x.at < y.at || x.at === y.at && side === "left") return [x];
|
|
234
|
+
return [{ ...x, at: x.at + y.count }];
|
|
235
|
+
}
|
|
236
|
+
if (y.kind === "remove") {
|
|
237
|
+
if (x.at <= y.start) return [x];
|
|
238
|
+
if (x.at >= y.start + y.count) return [{ ...x, at: x.at - y.count }];
|
|
239
|
+
return [{ ...x, at: y.start }];
|
|
240
|
+
}
|
|
241
|
+
return [{ ...x, at: mapGapThroughMove(x.at, y) }];
|
|
242
|
+
}
|
|
243
|
+
case "remove": {
|
|
244
|
+
const kept = [];
|
|
245
|
+
for (let i = x.start; i < x.start + x.count; i++) {
|
|
246
|
+
const m = mapIndex(y, i);
|
|
247
|
+
if (m !== null) kept.push(m);
|
|
248
|
+
}
|
|
249
|
+
if (y.kind === "insert" || y.kind === "remove" || y.kind === "move") {
|
|
250
|
+
return runs(kept).reverse().map((r) => ({ kind: "remove", start: r.start, count: r.count }));
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
case "move": {
|
|
255
|
+
if (y.kind === "insert") {
|
|
256
|
+
const inside = y.at > x.from && y.at < x.from + x.count;
|
|
257
|
+
const from = inside || y.at > x.from ? x.from : x.from + y.count;
|
|
258
|
+
const count = inside ? x.count + y.count : x.count;
|
|
259
|
+
const to2 = x.to >= y.at ? x.to + y.count : x.to;
|
|
260
|
+
const out2 = { kind: "move", from, count, to: to2 };
|
|
261
|
+
return isNoopMove(out2) ? [] : [out2];
|
|
262
|
+
}
|
|
263
|
+
if (y.kind === "remove") {
|
|
264
|
+
const kept = [];
|
|
265
|
+
for (let i = x.from; i < x.from + x.count; i++) {
|
|
266
|
+
const m = mapIndex(y, i);
|
|
267
|
+
if (m !== null) kept.push(m);
|
|
268
|
+
}
|
|
269
|
+
if (kept.length === 0) return [];
|
|
270
|
+
const r2 = runs(kept);
|
|
271
|
+
if (r2.length !== 1) return null;
|
|
272
|
+
const to2 = x.to <= y.start ? x.to : x.to >= y.start + y.count ? x.to - y.count : y.start;
|
|
273
|
+
const out2 = { kind: "move", from: r2[0].start, count: r2[0].count, to: to2 };
|
|
274
|
+
return isNoopMove(out2) ? [] : [out2];
|
|
275
|
+
}
|
|
276
|
+
const overlap = Math.min(x.from + x.count, y.from + y.count) - Math.max(x.from, y.from);
|
|
277
|
+
if (overlap > 0) {
|
|
278
|
+
if (x.from !== y.from || x.count !== y.count) return null;
|
|
279
|
+
if (side === "right") return [];
|
|
280
|
+
const out2 = { kind: "move", from: movedBlockStart(y), count: x.count, to: mapGapThroughMove(x.to, y) };
|
|
281
|
+
return isNoopMove(out2) ? [] : [out2];
|
|
282
|
+
}
|
|
283
|
+
const mapped = [];
|
|
284
|
+
for (let i = x.from; i < x.from + x.count; i++) mapped.push(mapIndex(y, i));
|
|
285
|
+
const r = runs(mapped);
|
|
286
|
+
if (r.length !== 1) return null;
|
|
287
|
+
let to;
|
|
288
|
+
if (x.to > y.from && x.to < y.from + y.count) to = movedBlockStart(y) + (x.to - y.from);
|
|
289
|
+
else to = mapGapThroughMove(x.to, y) + (x.to === y.to && side === "right" ? y.count : 0);
|
|
290
|
+
const out = { kind: "move", from: r[0].start, count: r[0].count, to };
|
|
291
|
+
if (to > out.from && to < out.from + out.count) return null;
|
|
292
|
+
return isNoopMove(out) ? [] : [out];
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// src/collab/sheets/transform/transform.ts
|
|
298
|
+
var SHEET_TRANSFORMER_VERSION = "c5a-1";
|
|
299
|
+
var ID = {
|
|
300
|
+
values: "sheet.mutation.set-range-values",
|
|
301
|
+
insertRow: "sheet.mutation.insert-row",
|
|
302
|
+
removeRows: "sheet.mutation.remove-rows",
|
|
303
|
+
insertCol: "sheet.mutation.insert-col",
|
|
304
|
+
removeCol: "sheet.mutation.remove-col",
|
|
305
|
+
moveRows: "sheet.mutation.move-rows",
|
|
306
|
+
moveCols: "sheet.mutation.move-columns",
|
|
307
|
+
addMerge: "sheet.mutation.add-worksheet-merge",
|
|
308
|
+
removeMerge: "sheet.mutation.remove-worksheet-merge",
|
|
309
|
+
rowHeight: "sheet.mutation.set-worksheet-row-height",
|
|
310
|
+
rowIsAuto: "sheet.mutation.set-worksheet-row-is-auto-height",
|
|
311
|
+
rowAutoHeight: "sheet.mutation.set-worksheet-row-auto-height",
|
|
312
|
+
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
313
|
+
name: "sheet.mutation.set-worksheet-name"
|
|
314
|
+
};
|
|
315
|
+
var PAIR_BARRIERS = {};
|
|
316
|
+
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
317
|
+
var barrier2 = (reason) => ({ barrier: true, reason });
|
|
318
|
+
var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
|
|
319
|
+
var flip = (side) => side === "left" ? "right" : "left";
|
|
320
|
+
var sheetOf = (m) => String(m.params.subUnitId ?? "");
|
|
321
|
+
function colName(c) {
|
|
322
|
+
let s = "";
|
|
323
|
+
for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
|
|
324
|
+
return s;
|
|
325
|
+
}
|
|
326
|
+
var cellRef = (sheet, row, col) => `${sheet}!${colName(col)}${row + 1}`;
|
|
327
|
+
var rangeRef = (sheet, r) => `${sheet}!${colName(r.startColumn)}${r.startRow + 1}:${colName(r.endColumn)}${r.endRow + 1}`;
|
|
328
|
+
function structuralOf(m) {
|
|
329
|
+
const p = m.params;
|
|
330
|
+
switch (m.id) {
|
|
331
|
+
case ID.insertRow:
|
|
332
|
+
return { axis: "row", op: { kind: "insert", at: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } };
|
|
333
|
+
case ID.removeRows:
|
|
334
|
+
return { axis: "row", op: { kind: "remove", start: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } };
|
|
335
|
+
case ID.insertCol:
|
|
336
|
+
return { axis: "col", op: { kind: "insert", at: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } };
|
|
337
|
+
case ID.removeCol:
|
|
338
|
+
return { axis: "col", op: { kind: "remove", start: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } };
|
|
339
|
+
case ID.moveRows:
|
|
340
|
+
return {
|
|
341
|
+
axis: "row",
|
|
342
|
+
op: { kind: "move", from: p.sourceRange.startRow, count: p.sourceRange.endRow - p.sourceRange.startRow + 1, to: p.targetRange.startRow }
|
|
343
|
+
};
|
|
344
|
+
case ID.moveCols:
|
|
345
|
+
return {
|
|
346
|
+
axis: "col",
|
|
347
|
+
op: {
|
|
348
|
+
kind: "move",
|
|
349
|
+
from: p.sourceRange.startColumn,
|
|
350
|
+
count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1,
|
|
351
|
+
to: p.targetRange.startColumn
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
default:
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
var S = (axis) => axis === "row" ? ["startRow", "endRow"] : ["startColumn", "endColumn"];
|
|
359
|
+
function buildStructural(template, axis, op) {
|
|
360
|
+
const [a0, a1] = S(axis);
|
|
361
|
+
const p = template.params;
|
|
362
|
+
if (op.kind === "move") {
|
|
363
|
+
const src = p.sourceRange;
|
|
364
|
+
const tgt = p.targetRange;
|
|
365
|
+
return {
|
|
366
|
+
id: template.id,
|
|
367
|
+
params: {
|
|
368
|
+
...p,
|
|
369
|
+
sourceRange: { ...src, [a0]: op.from, [a1]: op.from + op.count - 1 },
|
|
370
|
+
targetRange: { ...tgt, [a0]: op.to, [a1]: op.to + op.count - 1 }
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
const start = op.kind === "insert" ? op.at : op.start;
|
|
375
|
+
return { id: template.id, params: { ...p, range: { ...p.range, [a0]: start, [a1]: start + op.count - 1 } } };
|
|
376
|
+
}
|
|
377
|
+
function univerMutationInfo(axis, op) {
|
|
378
|
+
const FULL = { startRow: 0, endRow: Number.MAX_SAFE_INTEGER, startColumn: 0, endColumn: Number.MAX_SAFE_INTEGER };
|
|
379
|
+
const start = op.kind === "insert" ? op.at : op.start;
|
|
380
|
+
const range = axis === "row" ? { ...FULL, startRow: start, endRow: start + op.count - 1 } : { ...FULL, startColumn: start, endColumn: start + op.count - 1 };
|
|
381
|
+
const id = op.kind === "insert" ? axis === "row" ? ID.insertRow : ID.insertCol : axis === "row" ? ID.removeRows : ID.removeCol;
|
|
382
|
+
return { id, params: { unitId: "", subUnitId: "", range } };
|
|
383
|
+
}
|
|
384
|
+
var intersects = (a, b) => a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
|
|
385
|
+
var isSingleCell = (r) => r.startRow === r.endRow && r.startColumn === r.endColumn;
|
|
386
|
+
function mergeThrough(s, m) {
|
|
387
|
+
const [a0, a1] = S(s.axis);
|
|
388
|
+
const lo = m[a0];
|
|
389
|
+
const hi = m[a1];
|
|
390
|
+
const op = s.op;
|
|
391
|
+
if (op.kind === "insert") {
|
|
392
|
+
const fixup = lo < op.at && op.at <= hi;
|
|
393
|
+
return { range: (0, import_sheets.adjustRangeOnMutation)(m, univerMutationInfo(s.axis, op)), fixup };
|
|
394
|
+
}
|
|
395
|
+
if (op.kind === "remove") {
|
|
396
|
+
const e = op.start + op.count - 1;
|
|
397
|
+
if (e < lo || op.start > hi) return { range: (0, import_sheets.adjustRangeOnMutation)(m, univerMutationInfo(s.axis, op)), fixup: false };
|
|
398
|
+
if (op.start <= lo && e >= hi) return { range: null, fixup: true };
|
|
399
|
+
const r = { ...m };
|
|
400
|
+
if (op.start >= lo && e <= hi) r[a1] = hi - op.count;
|
|
401
|
+
else if (op.start < lo) {
|
|
402
|
+
r[a0] = op.start;
|
|
403
|
+
r[a1] = hi - op.count;
|
|
404
|
+
} else r[a1] = op.start - 1;
|
|
405
|
+
return { range: isSingleCell(r) ? null : r, fixup: true };
|
|
406
|
+
}
|
|
407
|
+
const fe = op.from + op.count - 1;
|
|
408
|
+
if (hi < op.from || lo > fe) {
|
|
409
|
+
const r = { ...m };
|
|
410
|
+
if (op.from < lo && op.to > hi) {
|
|
411
|
+
r[a0] = lo - op.count;
|
|
412
|
+
r[a1] = hi - op.count;
|
|
413
|
+
} else if (op.from > hi && op.to <= lo) {
|
|
414
|
+
r[a0] = lo + op.count;
|
|
415
|
+
r[a1] = hi + op.count;
|
|
416
|
+
}
|
|
417
|
+
return { range: r, fixup: false };
|
|
418
|
+
}
|
|
419
|
+
if (lo >= op.from && hi <= fe) {
|
|
420
|
+
const r = { ...m, [a0]: mapIndex(op, lo), [a1]: mapIndex(op, hi) };
|
|
421
|
+
return { range: r, fixup: true };
|
|
422
|
+
}
|
|
423
|
+
return { range: m, fixup: false };
|
|
424
|
+
}
|
|
425
|
+
function exactMergeRemovals(group, merges) {
|
|
426
|
+
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
427
|
+
const out = [];
|
|
428
|
+
for (const m of group) {
|
|
429
|
+
const sheet = sheetOf(m);
|
|
430
|
+
const cur = sim.get(sheet) ?? [];
|
|
431
|
+
if (m.id === ID.removeMerge) {
|
|
432
|
+
const hit = cur.filter((q) => mergeRanges(m).some((r) => intersects(r, q)));
|
|
433
|
+
sim.set(sheet, cur.filter((q) => !hit.includes(q)));
|
|
434
|
+
if (hit.length) out.push(withRanges(m, hit.map((r) => ({ ...r }))));
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (m.id === ID.addMerge) sim.set(sheet, [...cur, ...mergeRanges(m).map((r) => ({ ...r }))]);
|
|
438
|
+
const st = structuralOf(m);
|
|
439
|
+
if (st) sim.set(sheet, cur.map((q) => mergeThrough(st, q).range).filter((q) => q !== null));
|
|
440
|
+
out.push(m);
|
|
441
|
+
}
|
|
442
|
+
return out;
|
|
443
|
+
}
|
|
444
|
+
var mergeRanges = (m) => m.params.ranges ?? [];
|
|
445
|
+
var withRanges = (m, ranges) => ({ id: m.id, params: { ...m.params, ranges } });
|
|
446
|
+
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"];
|
|
449
|
+
var KNOWN_CELL_KEYS = /* @__PURE__ */ new Set([...CONTENT_KEYS, "s"]);
|
|
450
|
+
function completeCellContent(entry, post) {
|
|
451
|
+
if (entry === null) return null;
|
|
452
|
+
if (!CONTENT_TOUCH.some((k) => k in entry)) return entry;
|
|
453
|
+
const out = {};
|
|
454
|
+
for (const k of CONTENT_KEYS) out[k] = post && post[k] !== void 0 ? post[k] : null;
|
|
455
|
+
if (out.v === null) delete out.t;
|
|
456
|
+
if ("s" in entry) out.s = entry.s;
|
|
457
|
+
return out;
|
|
458
|
+
}
|
|
459
|
+
function cellsOf(m) {
|
|
460
|
+
return m.params.cellValue ?? {};
|
|
461
|
+
}
|
|
462
|
+
function forEachCell(cells, fn) {
|
|
463
|
+
for (const r of Object.keys(cells)) for (const c of Object.keys(cells[r] ?? {})) fn(Number(r), Number(c), cells[r][c] ?? null);
|
|
464
|
+
}
|
|
465
|
+
function cellsMutation(template, cells) {
|
|
466
|
+
return { id: template.id, params: { ...template.params, cellValue: cells } };
|
|
467
|
+
}
|
|
468
|
+
function putCell(cells, r, c, v) {
|
|
469
|
+
(cells[r] ??= {})[c] = v;
|
|
470
|
+
}
|
|
471
|
+
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
472
|
+
function cellBarrier(m) {
|
|
473
|
+
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
474
|
+
let why = null;
|
|
475
|
+
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
476
|
+
if (why || v === null) return;
|
|
477
|
+
for (const k of Object.keys(v)) {
|
|
478
|
+
if (!KNOWN_CELL_KEYS.has(k)) why = `cell key "${k}" is not covered`;
|
|
479
|
+
else if ((k === "f" || k === "si") && v[k] != null) why = "formula content (f/si) belongs to C5b";
|
|
480
|
+
}
|
|
481
|
+
if (typeof v.s === "string") why = "a style id travels (style ids are seat-local; capture must send the style object)";
|
|
482
|
+
if (!why && CONTENT_TOUCH.some((k) => k in v) && !CONTENT_KEYS.every((k) => k in v || k === "t" && v.v == null))
|
|
483
|
+
why = "cell content is not completed (capture must call completeCellContent)";
|
|
484
|
+
});
|
|
485
|
+
return why;
|
|
486
|
+
}
|
|
487
|
+
var hasContent = (v) => CONTENT_TOUCH.some((k) => k in v);
|
|
488
|
+
var contentOf = (v) => {
|
|
489
|
+
const out = {};
|
|
490
|
+
for (const k of Object.keys(v)) if (k !== "s") out[k] = v[k];
|
|
491
|
+
return out;
|
|
492
|
+
};
|
|
493
|
+
var richText = (v) => v.p != null;
|
|
494
|
+
function styleKeys(s) {
|
|
495
|
+
const out = [];
|
|
496
|
+
for (const k of Object.keys(s)) {
|
|
497
|
+
if (k === "bd" && s.bd && typeof s.bd === "object") for (const side of Object.keys(s.bd)) out.push(`bd.${side}`);
|
|
498
|
+
else out.push(k);
|
|
499
|
+
}
|
|
500
|
+
return out;
|
|
501
|
+
}
|
|
502
|
+
function withoutStyleKeys(s, drop) {
|
|
503
|
+
const out = {};
|
|
504
|
+
for (const k of Object.keys(s)) {
|
|
505
|
+
if (k === "bd" && s.bd && typeof s.bd === "object") {
|
|
506
|
+
const bd = {};
|
|
507
|
+
for (const side of Object.keys(s.bd)) if (!drop.has(`bd.${side}`)) bd[side] = s.bd[side];
|
|
508
|
+
if (Object.keys(bd).length) out.bd = bd;
|
|
509
|
+
} else if (!drop.has(k)) out[k] = s[k];
|
|
510
|
+
}
|
|
511
|
+
return Object.keys(out).length ? out : null;
|
|
512
|
+
}
|
|
513
|
+
function transformCell(X, Y, side) {
|
|
514
|
+
if (X === null || Y === null) {
|
|
515
|
+
if (side === "left") return { entries: [X], xLost: false, yLost: true };
|
|
516
|
+
return X === null ? { entries: [null, Y], xLost: true, yLost: false } : { entries: [], xLost: true, yLost: false };
|
|
517
|
+
}
|
|
518
|
+
if (hasContent(X) && richText(X) && "s" in Y || hasContent(Y) && richText(Y) && "s" in X)
|
|
519
|
+
return "rich-text content concurrent with a style change on the same cell is not covered";
|
|
520
|
+
const out = {};
|
|
521
|
+
let xLost = false;
|
|
522
|
+
let yLost = false;
|
|
523
|
+
if (hasContent(X)) {
|
|
524
|
+
if (!hasContent(Y) || side === "left") Object.assign(out, contentOf(X));
|
|
525
|
+
else xLost = true;
|
|
526
|
+
if (hasContent(Y) && side === "left") yLost = true;
|
|
527
|
+
}
|
|
528
|
+
const tail = [];
|
|
529
|
+
if ("s" in X) {
|
|
530
|
+
const xs = X.s;
|
|
531
|
+
const ys = "s" in Y ? Y.s : void 0;
|
|
532
|
+
if (ys === void 0 || side === "left") {
|
|
533
|
+
if (xs !== void 0) out.s = xs;
|
|
534
|
+
if (ys !== void 0) yLost = true;
|
|
535
|
+
} else if (ys === null) {
|
|
536
|
+
xLost = true;
|
|
537
|
+
} else if (xs === null) {
|
|
538
|
+
out.s = null;
|
|
539
|
+
tail.push({ s: ys });
|
|
540
|
+
xLost = true;
|
|
541
|
+
} else {
|
|
542
|
+
const kept = withoutStyleKeys(xs, new Set(styleKeys(ys)));
|
|
543
|
+
if (kept) out.s = kept;
|
|
544
|
+
if (styleKeys(xs).length !== styleKeys(kept ?? {}).length) xLost = true;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
|
|
548
|
+
}
|
|
549
|
+
function transformCellsOverCells(x, y, side) {
|
|
550
|
+
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
551
|
+
const ycells = cellsOf(y);
|
|
552
|
+
const passes = [{}];
|
|
553
|
+
const lost = [];
|
|
554
|
+
const dropped = [];
|
|
555
|
+
let why = null;
|
|
556
|
+
forEachCell(cellsOf(x), (r, c, X) => {
|
|
557
|
+
if (why) return;
|
|
558
|
+
const yRow = ycells[r];
|
|
559
|
+
if (!yRow || !(String(c) in yRow)) {
|
|
560
|
+
putCell(passes[0], r, c, X);
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
const res = transformCell(X, yRow[c] ?? null, side);
|
|
564
|
+
if (typeof res === "string") {
|
|
565
|
+
why = res;
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
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));
|
|
571
|
+
});
|
|
572
|
+
if (why) return barrier2(why);
|
|
573
|
+
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
574
|
+
return ok(op, lost, dropped);
|
|
575
|
+
}
|
|
576
|
+
function transformCellsOverStructural(x, s) {
|
|
577
|
+
const out = {};
|
|
578
|
+
const dropped = [];
|
|
579
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
580
|
+
const nr = s.axis === "row" ? mapIndex(s.op, r) : r;
|
|
581
|
+
const nc = s.axis === "col" ? mapIndex(s.op, c) : c;
|
|
582
|
+
if (nr === null || nc === null) dropped.push(cellRef(sheetOf(x), r, c));
|
|
583
|
+
else putCell(out, nr, nc, v);
|
|
584
|
+
});
|
|
585
|
+
return ok(isEmptyMatrix(out) ? [] : [cellsMutation(x, out)], [], dropped);
|
|
586
|
+
}
|
|
587
|
+
function sizeOf(m) {
|
|
588
|
+
const p = m.params;
|
|
589
|
+
const values = /* @__PURE__ */ new Map();
|
|
590
|
+
if (m.id === ID.rowAutoHeight) {
|
|
591
|
+
for (const { row, autoHeight } of p.rowsAutoHeightInfo ?? []) values.set(row, autoHeight);
|
|
592
|
+
return { axis: "row", attr: "ah", values };
|
|
593
|
+
}
|
|
594
|
+
const axis = m.id === ID.colWidth ? "col" : "row";
|
|
595
|
+
const field = m.id === ID.colWidth ? "colWidth" : m.id === ID.rowHeight ? "rowHeight" : "autoHeightInfo";
|
|
596
|
+
const value = p[field];
|
|
597
|
+
const [a0, a1] = S(axis);
|
|
598
|
+
for (const r of p.ranges ?? [])
|
|
599
|
+
for (let i = r[a0]; i <= r[a1]; i++) {
|
|
600
|
+
if (typeof value === "number") values.set(i, value);
|
|
601
|
+
else if (m.id === ID.rowIsAuto) values.set(i, value?.[i]);
|
|
602
|
+
else if (value?.[i] != null) values.set(i, value[i]);
|
|
603
|
+
}
|
|
604
|
+
return { axis, attr: m.id === ID.colWidth ? "w" : m.id === ID.rowHeight ? "h" : "ia", values };
|
|
605
|
+
}
|
|
606
|
+
function buildSize(template, values) {
|
|
607
|
+
if (values.size === 0) return null;
|
|
608
|
+
const p = template.params;
|
|
609
|
+
if (template.id === ID.rowAutoHeight)
|
|
610
|
+
return { id: template.id, params: { ...p, rowsAutoHeightInfo: [...values].sort((a, b) => a[0] - b[0]).map(([row, autoHeight]) => ({ row, autoHeight })) } };
|
|
611
|
+
const axis = template.id === ID.colWidth ? "col" : "row";
|
|
612
|
+
const field = template.id === ID.colWidth ? "colWidth" : template.id === ID.rowHeight ? "rowHeight" : "autoHeightInfo";
|
|
613
|
+
const [a0, a1] = S(axis);
|
|
614
|
+
const first = (p.ranges ?? [])[0] ?? { startRow: 0, endRow: 0, startColumn: 0, endColumn: 0 };
|
|
615
|
+
const ranges = runs(values.keys()).map((r) => ({ ...first, [a0]: r.start, [a1]: r.start + r.count - 1 }));
|
|
616
|
+
const uniform = typeof p[field] === "number" ? p[field] : void 0;
|
|
617
|
+
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
618
|
+
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
619
|
+
}
|
|
620
|
+
function familyOf(id) {
|
|
621
|
+
const e = SHEET_MUTATIONS[id];
|
|
622
|
+
return e && e.kind === "covered" ? e.family : "";
|
|
623
|
+
}
|
|
624
|
+
function transformMutation(x, y, side) {
|
|
625
|
+
for (const m of [x, y]) {
|
|
626
|
+
const e = SHEET_MUTATIONS[m.id];
|
|
627
|
+
if (!e) return barrier2(`${m.id} is not in the registry`);
|
|
628
|
+
if (e.kind !== "covered") return barrier2(`${m.id}: ${e.kind === "barrier" ? `barrier until ${e.until} (${e.reason})` : "never travels"}`);
|
|
629
|
+
if (m.id === ID.values) {
|
|
630
|
+
const why = cellBarrier(m);
|
|
631
|
+
if (why) return barrier2(why);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
635
|
+
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
636
|
+
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
637
|
+
const fx = familyOf(x.id);
|
|
638
|
+
const fy = familyOf(y.id);
|
|
639
|
+
const sy = structuralOf(y);
|
|
640
|
+
const sx = structuralOf(x);
|
|
641
|
+
if (sx && sy) {
|
|
642
|
+
if (sx.axis !== sy.axis) return ok([x]);
|
|
643
|
+
const out = transformAxis(sx.op, sy.op, side);
|
|
644
|
+
if (!out) return barrier2(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);
|
|
645
|
+
const dropped = out.length === 0 && sx.op.kind === "move" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];
|
|
646
|
+
return ok(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
|
|
647
|
+
}
|
|
648
|
+
if (sy) {
|
|
649
|
+
if (fx === "cell") return transformCellsOverStructural(x, sy);
|
|
650
|
+
if (fx === "merge") {
|
|
651
|
+
const kept = [];
|
|
652
|
+
const dropped = [];
|
|
653
|
+
for (const r of mergeRanges(x)) {
|
|
654
|
+
const t = mergeThrough(sy, r).range;
|
|
655
|
+
if (t) kept.push(t);
|
|
656
|
+
else dropped.push(rangeRef(sheetOf(x), r));
|
|
657
|
+
}
|
|
658
|
+
return ok(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
|
|
659
|
+
}
|
|
660
|
+
if (fx === "size") {
|
|
661
|
+
const size = sizeOf(x);
|
|
662
|
+
if (size.axis !== sy.axis) return ok([x]);
|
|
663
|
+
const next = /* @__PURE__ */ new Map();
|
|
664
|
+
for (const [i, v] of size.values) {
|
|
665
|
+
const m = mapIndex(sy.op, i);
|
|
666
|
+
if (m !== null) next.set(m, v);
|
|
667
|
+
}
|
|
668
|
+
const built = buildSize(x, next);
|
|
669
|
+
return ok(built ? [built] : []);
|
|
670
|
+
}
|
|
671
|
+
return ok([x]);
|
|
672
|
+
}
|
|
673
|
+
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
|
+
if (fy !== "merge" || y.id !== ID.addMerge) return ok([x]);
|
|
682
|
+
const remove = [];
|
|
683
|
+
const add = [];
|
|
684
|
+
for (const r of mergeRanges(y)) {
|
|
685
|
+
const t = mergeThrough(sx, r);
|
|
686
|
+
if (!t.fixup) continue;
|
|
687
|
+
remove.push(r);
|
|
688
|
+
if (t.range) add.push(t.range);
|
|
689
|
+
}
|
|
690
|
+
const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));
|
|
691
|
+
if (!remove.length) return ok([x], lostMerges);
|
|
692
|
+
const sheet = sheetOf(x);
|
|
693
|
+
const pre = sx.op.kind === "insert" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];
|
|
694
|
+
const mid = sx.op.kind === "insert" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];
|
|
695
|
+
return ok([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
|
|
696
|
+
}
|
|
697
|
+
if (fx === "cell" && fy === "cell") return transformCellsOverCells(x, y, side);
|
|
698
|
+
if (fx === "merge" && fy === "merge") {
|
|
699
|
+
const xr = mergeRanges(x);
|
|
700
|
+
const yr = mergeRanges(y);
|
|
701
|
+
const hit = (r) => yr.some((q) => intersects(r, q));
|
|
702
|
+
const sheet = sheetOf(x);
|
|
703
|
+
if (x.id === ID.addMerge && y.id === ID.addMerge) {
|
|
704
|
+
if (!xr.some(hit)) return ok([x]);
|
|
705
|
+
if (side === "left") {
|
|
706
|
+
const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));
|
|
707
|
+
return ok([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
|
|
708
|
+
}
|
|
709
|
+
const kept = xr.filter((r) => !hit(r));
|
|
710
|
+
return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
711
|
+
}
|
|
712
|
+
if (x.id === ID.addMerge && y.id === ID.removeMerge) {
|
|
713
|
+
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)) : []);
|
|
714
|
+
const kept = xr.filter((r) => !hit(r));
|
|
715
|
+
return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
716
|
+
}
|
|
717
|
+
if (x.id === ID.removeMerge && y.id === ID.addMerge) {
|
|
718
|
+
const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));
|
|
719
|
+
if (!touched.length) return ok([x]);
|
|
720
|
+
if (side === "left") return ok([x], touched.map((q) => rangeRef(sheet, q)));
|
|
721
|
+
return ok([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
722
|
+
}
|
|
723
|
+
return ok([x]);
|
|
724
|
+
}
|
|
725
|
+
if (fx === "size" && fy === "size") {
|
|
726
|
+
const a = sizeOf(x);
|
|
727
|
+
const b = sizeOf(y);
|
|
728
|
+
if (a.axis !== b.axis || a.attr !== b.attr) return ok([x]);
|
|
729
|
+
if (side === "left") {
|
|
730
|
+
const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
|
|
731
|
+
return ok([x], lost);
|
|
732
|
+
}
|
|
733
|
+
const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));
|
|
734
|
+
const built = buildSize(x, next);
|
|
735
|
+
const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
|
|
736
|
+
return ok(built ? [built] : [], [], dropped);
|
|
737
|
+
}
|
|
738
|
+
if (fx === "name" && fy === "name") {
|
|
739
|
+
if (side === "left") return ok([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
|
|
740
|
+
return ok([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
|
|
741
|
+
}
|
|
742
|
+
return ok([x]);
|
|
743
|
+
}
|
|
744
|
+
var blocked = (p) => !Array.isArray(p);
|
|
745
|
+
function tSeq(xs, ys, side, acc) {
|
|
746
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
747
|
+
if (xs.length === 1 && ys.length === 1) {
|
|
748
|
+
const a = transformMutation(xs[0], ys[0], side);
|
|
749
|
+
if (isBarrier(a)) return a;
|
|
750
|
+
const b = transformMutation(ys[0], xs[0], flip(side));
|
|
751
|
+
if (isBarrier(b)) return b;
|
|
752
|
+
acc.lost.push(...a.lost);
|
|
753
|
+
acc.dropped.push(...a.dropped);
|
|
754
|
+
return [a.op, b.op];
|
|
755
|
+
}
|
|
756
|
+
if (xs.length > 1) {
|
|
757
|
+
const first2 = tSeq([xs[0]], ys, side, acc);
|
|
758
|
+
if (blocked(first2)) return first2;
|
|
759
|
+
const rest2 = tSeq(xs.slice(1), first2[1], side, acc);
|
|
760
|
+
if (blocked(rest2)) return rest2;
|
|
761
|
+
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
762
|
+
}
|
|
763
|
+
const first = tSeq(xs, [ys[0]], side, acc);
|
|
764
|
+
if (blocked(first)) return first;
|
|
765
|
+
const rest = tSeq(first[0], ys.slice(1), side, acc);
|
|
766
|
+
if (blocked(rest)) return rest;
|
|
767
|
+
return [rest[0], [...first[1], ...rest[1]]];
|
|
768
|
+
}
|
|
769
|
+
function transformGroup(x, y, side) {
|
|
770
|
+
const acc = { lost: [], dropped: [] };
|
|
771
|
+
const r = tSeq([...x], [...y], side, acc);
|
|
772
|
+
if (blocked(r)) return r;
|
|
773
|
+
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
774
|
+
}
|
|
775
|
+
var sheetTransformer = {
|
|
776
|
+
version: SHEET_TRANSFORMER_VERSION,
|
|
777
|
+
transform(x, y, side) {
|
|
778
|
+
const r = transformGroup(x, y, side);
|
|
779
|
+
if (isBarrier(r)) return r;
|
|
780
|
+
return { op: r.op.length ? r.op : null, lost: r.lost, dropped: r.dropped };
|
|
781
|
+
},
|
|
782
|
+
compose(a, b) {
|
|
783
|
+
return [...a, ...b];
|
|
784
|
+
},
|
|
785
|
+
isNoop(op) {
|
|
786
|
+
return op.length === 0;
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
//# sourceMappingURL=collab-sheets-transform.cjs.map
|