@pixerate/editor 0.21.0 → 0.22.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/README.md +20 -11
- package/dist/agent/index.cjs +8 -8
- package/dist/agent/index.d.cts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +2 -2
- package/dist/canvas/index.cjs +1269 -13
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +432 -6
- package/dist/canvas/index.d.ts +432 -6
- package/dist/canvas/index.js +1264 -8
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-U6NDQFOK.cjs → chunk-6M3BCTBD.cjs} +427 -138
- package/dist/chunk-6M3BCTBD.cjs.map +1 -0
- package/dist/{chunk-TVRC4KVT.cjs → chunk-AA4ZEVCC.cjs} +845 -90
- package/dist/chunk-AA4ZEVCC.cjs.map +1 -0
- package/dist/{chunk-LA7PEGU3.cjs → chunk-CL37JGFW.cjs} +4 -4
- package/dist/{chunk-LA7PEGU3.cjs.map → chunk-CL37JGFW.cjs.map} +1 -1
- package/dist/{chunk-A7DKIA72.js → chunk-DENSCKFC.js} +642 -69
- package/dist/chunk-DENSCKFC.js.map +1 -0
- package/dist/{chunk-4QPLEUL2.cjs → chunk-GVSMRPHB.cjs} +1046 -54
- package/dist/chunk-GVSMRPHB.cjs.map +1 -0
- package/dist/{chunk-KYRZDWM4.js → chunk-JJDLPEWL.js} +2 -2
- package/dist/{chunk-3TYMNULT.js → chunk-MJZBNWG7.js} +807 -52
- package/dist/chunk-MJZBNWG7.js.map +1 -0
- package/dist/{chunk-CYFJCKC4.js → chunk-QGHGJ56O.js} +997 -5
- package/dist/chunk-QGHGJ56O.js.map +1 -0
- package/dist/{chunk-GVW4P7BG.js → chunk-RU52I7QO.js} +305 -16
- package/dist/chunk-RU52I7QO.js.map +1 -0
- package/dist/{chunk-JYRIOFEN.cjs → chunk-SAZRENEZ.cjs} +647 -74
- package/dist/chunk-SAZRENEZ.cjs.map +1 -0
- package/dist/{controller-OUdxPY-X.d.ts → controller-B7GIybc4.d.cts} +139 -7
- package/dist/{controller-OUdxPY-X.d.cts → controller-B7GIybc4.d.ts} +139 -7
- package/dist/extensions/index.cjs +14 -4
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +3 -3
- package/dist/extensions/index.d.ts +3 -3
- package/dist/extensions/index.js +13 -3
- package/dist/{index-k3mFbPx_.d.cts → index-CCr_z9kF.d.cts} +3 -3
- package/dist/{index-Ng1pG7JE.d.ts → index-Ck6ajwXh.d.ts} +3 -3
- package/dist/index.cjs +250 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +294 -8
- package/dist/index.d.ts +294 -8
- package/dist/index.js +241 -7
- package/dist/index.js.map +1 -1
- package/dist/{registry-iAHbqkYt.d.cts → registry-GJI4gToU.d.cts} +15 -4
- package/dist/{registry-iAHbqkYt.d.ts → registry-GJI4gToU.d.ts} +15 -4
- package/dist/serializers/index.cjs +3 -3
- package/dist/serializers/index.d.cts +1 -1
- package/dist/serializers/index.d.ts +1 -1
- package/dist/serializers/index.js +2 -2
- package/dist/spreadsheet/index.cjs +7 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +33 -4
- package/dist/spreadsheet/index.d.ts +33 -4
- package/dist/spreadsheet/index.js +6 -2
- package/dist/{track-changes-G8JcWB8b.d.cts → track-changes-BSF58RK0.d.cts} +92 -9
- package/dist/{track-changes-G8JcWB8b.d.ts → track-changes-BSF58RK0.d.ts} +92 -9
- package/dist/{types-DMe0vFB1.d.cts → types-CJ4U-HHI.d.cts} +1 -1
- package/dist/{types-DMe0vFB1.d.ts → types-CJ4U-HHI.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-3TYMNULT.js.map +0 -1
- package/dist/chunk-4QPLEUL2.cjs.map +0 -1
- package/dist/chunk-A7DKIA72.js.map +0 -1
- package/dist/chunk-CYFJCKC4.js.map +0 -1
- package/dist/chunk-GVW4P7BG.js.map +0 -1
- package/dist/chunk-JYRIOFEN.cjs.map +0 -1
- package/dist/chunk-TVRC4KVT.cjs.map +0 -1
- package/dist/chunk-U6NDQFOK.cjs.map +0 -1
- /package/dist/{chunk-KYRZDWM4.js.map → chunk-JJDLPEWL.js.map} +0 -0
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var _chunkSAZRENEZcjs = require('./chunk-SAZRENEZ.cjs');
|
|
14
16
|
|
|
15
17
|
// src/spreadsheet/formula/dependency-graph.ts
|
|
16
18
|
var columnDependencyKey = (col) => `${col.toUpperCase()}:`;
|
|
@@ -19,22 +21,24 @@ function extractCellDependencies(node) {
|
|
|
19
21
|
const visit = (curr) => {
|
|
20
22
|
if (curr.type === "CellRef") {
|
|
21
23
|
deps.push({ col: curr.col, row: curr.row });
|
|
22
|
-
} else if (curr.type === "
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
} else if (curr.type === "SpillRef") {
|
|
25
|
+
deps.push({ col: curr.col, row: curr.row });
|
|
26
|
+
} else if (curr.type === "Range" && curr.endRow >= _chunkSAZRENEZcjs.WHOLE_COLUMN_END_ROW) {
|
|
27
|
+
const startC = _chunkSAZRENEZcjs.colNameToIndex.call(void 0, curr.startCol);
|
|
28
|
+
const endC = _chunkSAZRENEZcjs.colNameToIndex.call(void 0, curr.endCol);
|
|
25
29
|
for (let c = Math.min(startC, endC); c <= Math.max(startC, endC); c++) {
|
|
26
|
-
deps.push({ col:
|
|
30
|
+
deps.push({ col: _chunkSAZRENEZcjs.indexToColName.call(void 0, c), row: 0 });
|
|
27
31
|
}
|
|
28
32
|
} else if (curr.type === "Range") {
|
|
29
|
-
const startC =
|
|
30
|
-
const endC =
|
|
33
|
+
const startC = _chunkSAZRENEZcjs.colNameToIndex.call(void 0, curr.startCol);
|
|
34
|
+
const endC = _chunkSAZRENEZcjs.colNameToIndex.call(void 0, curr.endCol);
|
|
31
35
|
const minC = Math.min(startC, endC);
|
|
32
36
|
const maxC = Math.max(startC, endC);
|
|
33
37
|
const minR = Math.min(curr.startRow, curr.endRow);
|
|
34
38
|
const maxR = Math.max(curr.startRow, curr.endRow);
|
|
35
39
|
for (let c = minC; c <= maxC; c++) {
|
|
36
40
|
for (let r = minR; r <= maxR; r++) {
|
|
37
|
-
deps.push({ col:
|
|
41
|
+
deps.push({ col: _chunkSAZRENEZcjs.indexToColName.call(void 0, c), row: r });
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
} else if (curr.type === "BinaryOp") {
|
|
@@ -49,11 +53,19 @@ function extractCellDependencies(node) {
|
|
|
49
53
|
visit(node);
|
|
50
54
|
return deps;
|
|
51
55
|
}
|
|
52
|
-
var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this); }
|
|
56
|
+
var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this); }
|
|
53
57
|
// Map of cellKey (e.g. "B2") -> Set of cellKeys that this cell depends ON
|
|
54
58
|
__init() {this.dependencies = /* @__PURE__ */ new Map()}
|
|
55
59
|
// Map of cellKey (e.g. "A1") -> Set of cellKeys that depend ON this cell (dependents)
|
|
56
60
|
__init2() {this.dependents = /* @__PURE__ */ new Map()}
|
|
61
|
+
// Dynamic-array edges, set by the controller after evaluating an anchor:
|
|
62
|
+
// spilled cells depend on their anchor, and a blocked (#SPILL!) anchor
|
|
63
|
+
// depends on the cells blocking it. Kept apart from formula dependencies,
|
|
64
|
+
// so re-entering a formula doesn't drop them.
|
|
65
|
+
__init3() {this.spillDependencies = /* @__PURE__ */ new Map()}
|
|
66
|
+
__init4() {this.spillDependents = /* @__PURE__ */ new Map()}
|
|
67
|
+
// anchor -> the edges it registered (so they can be replaced).
|
|
68
|
+
__init5() {this.spillEdges = /* @__PURE__ */ new Map()}
|
|
57
69
|
setCellFormula(cellKey, formulaStr) {
|
|
58
70
|
const key = cellKey.toUpperCase();
|
|
59
71
|
const oldDeps = this.dependencies.get(key) || /* @__PURE__ */ new Set();
|
|
@@ -65,7 +77,7 @@ var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.c
|
|
|
65
77
|
return;
|
|
66
78
|
}
|
|
67
79
|
try {
|
|
68
|
-
const ast =
|
|
80
|
+
const ast = _chunkSAZRENEZcjs.parseFormula.call(void 0, formulaStr);
|
|
69
81
|
const deps = extractCellDependencies(ast);
|
|
70
82
|
const newDeps = /* @__PURE__ */ new Set();
|
|
71
83
|
for (const d of deps) {
|
|
@@ -84,12 +96,49 @@ var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.c
|
|
|
84
96
|
clear() {
|
|
85
97
|
this.dependencies.clear();
|
|
86
98
|
this.dependents.clear();
|
|
99
|
+
this.spillDependencies.clear();
|
|
100
|
+
this.spillDependents.clear();
|
|
101
|
+
this.spillEdges.clear();
|
|
87
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Records the dynamic-array edges of the anchor `anchorKey`, replacing its
|
|
105
|
+
* previous ones: every key in `spilledKeys` (cells holding its spilled
|
|
106
|
+
* values) depends on the anchor, and the anchor depends on every key in
|
|
107
|
+
* `blockingKeys` (cells that stop it spilling). Pass empty lists to remove
|
|
108
|
+
* the anchor's edges.
|
|
109
|
+
*/
|
|
110
|
+
setSpillEdges(anchorKey, spilledKeys, blockingKeys = []) {
|
|
111
|
+
const anchor = anchorKey.toUpperCase();
|
|
112
|
+
for (const [from, to] of _nullishCoalesce(this.spillEdges.get(anchor), () => ( []))) {
|
|
113
|
+
_optionalChain([this, 'access', _7 => _7.spillDependencies, 'access', _8 => _8.get, 'call', _9 => _9(from), 'optionalAccess', _10 => _10.delete, 'call', _11 => _11(to)]);
|
|
114
|
+
_optionalChain([this, 'access', _12 => _12.spillDependents, 'access', _13 => _13.get, 'call', _14 => _14(to), 'optionalAccess', _15 => _15.delete, 'call', _16 => _16(from)]);
|
|
115
|
+
}
|
|
116
|
+
const edges = [];
|
|
117
|
+
for (const key of spilledKeys) edges.push([key.toUpperCase(), anchor]);
|
|
118
|
+
for (const key of blockingKeys) edges.push([anchor, key.toUpperCase()]);
|
|
119
|
+
for (const [from, to] of edges) {
|
|
120
|
+
if (!this.spillDependencies.has(from)) this.spillDependencies.set(from, /* @__PURE__ */ new Set());
|
|
121
|
+
this.spillDependencies.get(from).add(to);
|
|
122
|
+
if (!this.spillDependents.has(to)) this.spillDependents.set(to, /* @__PURE__ */ new Set());
|
|
123
|
+
this.spillDependents.get(to).add(from);
|
|
124
|
+
}
|
|
125
|
+
if (edges.length > 0) this.spillEdges.set(anchor, edges);
|
|
126
|
+
else this.spillEdges.delete(anchor);
|
|
127
|
+
}
|
|
128
|
+
/** The spilled cells registered for `anchorKey` by `setSpillEdges`. */
|
|
129
|
+
getSpilledKeys(anchorKey) {
|
|
130
|
+
const anchor = anchorKey.toUpperCase();
|
|
131
|
+
return (_nullishCoalesce(this.spillEdges.get(anchor), () => ( []))).filter(([, to]) => to === anchor).map(([from]) => from);
|
|
132
|
+
}
|
|
133
|
+
/** Formula dependencies plus dynamic-array (spill) dependencies of a cell. */
|
|
88
134
|
getDependencies(cellKey) {
|
|
89
|
-
|
|
135
|
+
const key = cellKey.toUpperCase();
|
|
136
|
+
return unionOf(this.dependencies.get(key), this.spillDependencies.get(key));
|
|
90
137
|
}
|
|
138
|
+
/** Cells depending on `cellKey`, through formulas or spills. */
|
|
91
139
|
getDependents(cellKey) {
|
|
92
|
-
|
|
140
|
+
const key = cellKey.toUpperCase();
|
|
141
|
+
return unionOf(this.dependents.get(key), this.spillDependents.get(key));
|
|
93
142
|
}
|
|
94
143
|
/**
|
|
95
144
|
* Detects if there is a cycle containing cellKey.
|
|
@@ -101,7 +150,7 @@ var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.c
|
|
|
101
150
|
const dfs = (node) => {
|
|
102
151
|
visited.add(node);
|
|
103
152
|
recStack.add(node);
|
|
104
|
-
const deps = this.
|
|
153
|
+
const deps = this.getDependencies(node);
|
|
105
154
|
for (const neighbor of deps) {
|
|
106
155
|
if (!visited.has(neighbor)) {
|
|
107
156
|
if (dfs(neighbor)) return true;
|
|
@@ -180,6 +229,7 @@ var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.c
|
|
|
180
229
|
const node = queue.pop();
|
|
181
230
|
const direct = [
|
|
182
231
|
..._nullishCoalesce(this.dependents.get(node), () => ( [])),
|
|
232
|
+
..._nullishCoalesce(this.spillDependents.get(node), () => ( [])),
|
|
183
233
|
..._nullishCoalesce(this.dependents.get(columnDependencyKey(node.replace(/\d+$/, ""))), () => ( []))
|
|
184
234
|
];
|
|
185
235
|
for (const dep of direct) {
|
|
@@ -192,7 +242,7 @@ var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.c
|
|
|
192
242
|
}
|
|
193
243
|
const neighbors = (node) => {
|
|
194
244
|
const result = [];
|
|
195
|
-
for (const dep of
|
|
245
|
+
for (const dep of this.getDependencies(node)) {
|
|
196
246
|
if (dep.endsWith(":")) {
|
|
197
247
|
const col = dep.slice(0, -1);
|
|
198
248
|
for (const candidate of nodes) {
|
|
@@ -258,6 +308,11 @@ var DependencyGraph = (_class = class {constructor() { _class.prototype.__init.c
|
|
|
258
308
|
return { order, cyclic };
|
|
259
309
|
}
|
|
260
310
|
}, _class);
|
|
311
|
+
function unionOf(a, b) {
|
|
312
|
+
if (!b || b.size === 0) return Array.from(_nullishCoalesce(a, () => ( [])));
|
|
313
|
+
if (!a || a.size === 0) return Array.from(b);
|
|
314
|
+
return Array.from(/* @__PURE__ */ new Set([...a, ...b]));
|
|
315
|
+
}
|
|
261
316
|
|
|
262
317
|
// src/spreadsheet/formula/references.ts
|
|
263
318
|
var CELL_PART = /^(\$?)([A-Za-z]+)(\$?)(\d+)$/;
|
|
@@ -268,19 +323,19 @@ function parsePart(text) {
|
|
|
268
323
|
if (cell) {
|
|
269
324
|
return {
|
|
270
325
|
colAbs: cell[1],
|
|
271
|
-
col:
|
|
326
|
+
col: _chunkSAZRENEZcjs.colNameToIndex.call(void 0, cell[2]),
|
|
272
327
|
rowAbs: cell[3],
|
|
273
328
|
row: parseInt(cell[4], 10) - 1
|
|
274
329
|
};
|
|
275
330
|
}
|
|
276
331
|
const column = COLUMN_PART.exec(text);
|
|
277
332
|
if (column) {
|
|
278
|
-
return { colAbs: column[1], col:
|
|
333
|
+
return { colAbs: column[1], col: _chunkSAZRENEZcjs.colNameToIndex.call(void 0, column[2]), rowAbs: "", row: null };
|
|
279
334
|
}
|
|
280
335
|
return null;
|
|
281
336
|
}
|
|
282
337
|
function formatPart(part) {
|
|
283
|
-
const col = `${part.colAbs}${
|
|
338
|
+
const col = `${part.colAbs}${_chunkSAZRENEZcjs.indexToColName.call(void 0, part.col)}`;
|
|
284
339
|
return part.row === null ? col : `${col}${part.rowAbs}${part.row + 1}`;
|
|
285
340
|
}
|
|
286
341
|
function shiftCoordinate(value, change) {
|
|
@@ -327,7 +382,7 @@ function mapFormulaReferences(formula, rewrite) {
|
|
|
327
382
|
if (!formula.startsWith("=")) return formula;
|
|
328
383
|
let tokens;
|
|
329
384
|
try {
|
|
330
|
-
tokens =
|
|
385
|
+
tokens = _chunkSAZRENEZcjs.tokenizeFormula.call(void 0, formula);
|
|
331
386
|
} catch (e2) {
|
|
332
387
|
return formula;
|
|
333
388
|
}
|
|
@@ -335,11 +390,17 @@ function mapFormulaReferences(formula, rewrite) {
|
|
|
335
390
|
let cursor = 0;
|
|
336
391
|
for (let i = 0; i < tokens.length; i++) {
|
|
337
392
|
const token = tokens[i];
|
|
338
|
-
if (token.type !== "CELL_REF" && token.type !== "RANGE") continue;
|
|
339
|
-
if (_optionalChain([tokens, 'access',
|
|
393
|
+
if (token.type !== "CELL_REF" && token.type !== "RANGE" && token.type !== "SPILL_REF") continue;
|
|
394
|
+
if (_optionalChain([tokens, 'access', _17 => _17[i + 1], 'optionalAccess', _18 => _18.type]) === "LPAREN") continue;
|
|
340
395
|
let end = token.position;
|
|
341
396
|
while (end < formula.length && REF_CHAR.test(formula[end])) end++;
|
|
342
397
|
const original = formula.slice(token.position, end);
|
|
398
|
+
if (token.type === "SPILL_REF") {
|
|
399
|
+
const rewritten = rewrite(original);
|
|
400
|
+
result += formula.slice(cursor, token.position) + (rewritten === "#REF!" ? rewritten : `${rewritten}#`);
|
|
401
|
+
cursor = end + 1;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
343
404
|
result += formula.slice(cursor, token.position) + rewrite(original);
|
|
344
405
|
cursor = end;
|
|
345
406
|
}
|
|
@@ -459,7 +520,7 @@ function innermostCall(stack) {
|
|
|
459
520
|
}
|
|
460
521
|
var toSuggestion = (def) => ({
|
|
461
522
|
name: def.name,
|
|
462
|
-
signature:
|
|
523
|
+
signature: _chunkSAZRENEZcjs.getFormulaSignature.call(void 0, def),
|
|
463
524
|
description: def.description,
|
|
464
525
|
category: def.category
|
|
465
526
|
});
|
|
@@ -468,20 +529,20 @@ function getFormulaHints(input, caret = input.length, options = {}) {
|
|
|
468
529
|
let suggestions = [];
|
|
469
530
|
if (context.prefix) {
|
|
470
531
|
const query = context.prefix.text.toUpperCase();
|
|
471
|
-
suggestions =
|
|
532
|
+
suggestions = _chunkSAZRENEZcjs.searchFormulaFunctions.call(void 0, query, { limit: void 0 }).filter((def) => def.name.startsWith(query)).slice(0, _nullishCoalesce(options.limit, () => ( 8))).map(toSuggestion);
|
|
472
533
|
const followedByParen = input.slice(context.prefix.end).trimStart().startsWith("(");
|
|
473
534
|
if (followedByParen || suggestions.length === 1 && suggestions[0].name === query) suggestions = [];
|
|
474
535
|
}
|
|
475
536
|
let activeCall = null;
|
|
476
537
|
if (context.call) {
|
|
477
|
-
const def =
|
|
538
|
+
const def = _chunkSAZRENEZcjs.getFormulaFunction.call(void 0, context.call.name);
|
|
478
539
|
if (def) {
|
|
479
|
-
const specIndex =
|
|
540
|
+
const specIndex = _chunkSAZRENEZcjs.getFormulaArgumentSpecIndex.call(void 0, def, context.call.argIndex);
|
|
480
541
|
activeCall = {
|
|
481
542
|
name: def.name,
|
|
482
|
-
signature:
|
|
543
|
+
signature: _chunkSAZRENEZcjs.getFormulaSignature.call(void 0, def),
|
|
483
544
|
description: def.description,
|
|
484
|
-
parts:
|
|
545
|
+
parts: _chunkSAZRENEZcjs.getFormulaSignatureParts.call(void 0, def, context.call.argIndex),
|
|
485
546
|
argIndex: context.call.argIndex,
|
|
486
547
|
argument: specIndex >= 0 ? def.args[specIndex] : null
|
|
487
548
|
};
|
|
@@ -491,8 +552,8 @@ function getFormulaHints(input, caret = input.length, options = {}) {
|
|
|
491
552
|
}
|
|
492
553
|
function applyFormulaSuggestion(input, caret, name) {
|
|
493
554
|
const context = getFormulaCaretContext(input, caret);
|
|
494
|
-
const start = _nullishCoalesce(_optionalChain([context, 'access',
|
|
495
|
-
const end = _nullishCoalesce(_optionalChain([context, 'access',
|
|
555
|
+
const start = _nullishCoalesce(_optionalChain([context, 'access', _19 => _19.prefix, 'optionalAccess', _20 => _20.start]), () => ( caret));
|
|
556
|
+
const end = _nullishCoalesce(_optionalChain([context, 'access', _21 => _21.prefix, 'optionalAccess', _22 => _22.end]), () => ( caret));
|
|
496
557
|
const hasParen = input[end] === "(";
|
|
497
558
|
const insert = hasParen ? name.toUpperCase() : `${name.toUpperCase()}(`;
|
|
498
559
|
const value = input.slice(0, start) + insert + input.slice(end);
|
|
@@ -500,8 +561,8 @@ function applyFormulaSuggestion(input, caret, name) {
|
|
|
500
561
|
}
|
|
501
562
|
|
|
502
563
|
// src/spreadsheet/datasource/index.ts
|
|
503
|
-
var DataSourceBinder = (_class2 = class {constructor() { _class2.prototype.
|
|
504
|
-
|
|
564
|
+
var DataSourceBinder = (_class2 = class {constructor() { _class2.prototype.__init6.call(this); }
|
|
565
|
+
__init6() {this.dataSources = /* @__PURE__ */ new Map()}
|
|
505
566
|
register(dataSource) {
|
|
506
567
|
this.dataSources.set(dataSource.id, dataSource);
|
|
507
568
|
}
|
|
@@ -532,10 +593,10 @@ var DataSourceBinder = (_class2 = class {constructor() { _class2.prototype.__ini
|
|
|
532
593
|
for (const record of records) {
|
|
533
594
|
const existing = existingRecordRowMap.get(record.id);
|
|
534
595
|
nextRows.push({
|
|
535
|
-
..._optionalChain([existing, 'optionalAccess',
|
|
536
|
-
id: _optionalChain([existing, 'optionalAccess',
|
|
596
|
+
..._optionalChain([existing, 'optionalAccess', _23 => _23.hidden]) ? { hidden: true } : {},
|
|
597
|
+
id: _optionalChain([existing, 'optionalAccess', _24 => _24.id]) || `row_${record.id}`,
|
|
537
598
|
index: rowIndex++,
|
|
538
|
-
height: _optionalChain([existing, 'optionalAccess',
|
|
599
|
+
height: _optionalChain([existing, 'optionalAccess', _25 => _25.height]) || 32,
|
|
539
600
|
recordId: record.id,
|
|
540
601
|
type: "record"
|
|
541
602
|
});
|
|
@@ -991,8 +1052,8 @@ function parseHtmlTable(html) {
|
|
|
991
1052
|
while (cellMatch = cellPattern.exec(rowMatch[1])) {
|
|
992
1053
|
while (taken.has(col)) row[col++] = "";
|
|
993
1054
|
const attrs = _nullishCoalesce(cellMatch[2], () => ( ""));
|
|
994
|
-
const colspan = Math.max(1, parseInt(_nullishCoalesce(_optionalChain([/colspan\s*=\s*["']?(\d+)/i, 'access',
|
|
995
|
-
const rowspan = Math.max(1, parseInt(_nullishCoalesce(_optionalChain([/rowspan\s*=\s*["']?(\d+)/i, 'access',
|
|
1055
|
+
const colspan = Math.max(1, parseInt(_nullishCoalesce(_optionalChain([/colspan\s*=\s*["']?(\d+)/i, 'access', _26 => _26.exec, 'call', _27 => _27(attrs), 'optionalAccess', _28 => _28[1]]), () => ( "1")), 10));
|
|
1056
|
+
const rowspan = Math.max(1, parseInt(_nullishCoalesce(_optionalChain([/rowspan\s*=\s*["']?(\d+)/i, 'access', _29 => _29.exec, 'call', _30 => _30(attrs), 'optionalAccess', _31 => _31[1]]), () => ( "1")), 10));
|
|
996
1057
|
row[col] = cellHtmlToText(cellMatch[3]);
|
|
997
1058
|
for (let c = col; c < col + colspan; c++) {
|
|
998
1059
|
if (c > col) row[c] = "";
|
|
@@ -1031,7 +1092,7 @@ function readFormat(source, format) {
|
|
|
1031
1092
|
function parsePayload(json) {
|
|
1032
1093
|
try {
|
|
1033
1094
|
const payload = JSON.parse(json);
|
|
1034
|
-
if (_optionalChain([payload, 'optionalAccess',
|
|
1095
|
+
if (_optionalChain([payload, 'optionalAccess', _32 => _32.type]) !== "pixerate-spreadsheet" || !Array.isArray(payload.cells) || !payload.cells.every((row) => Array.isArray(row)) || typeof _optionalChain([payload, 'access', _33 => _33.origin, 'optionalAccess', _34 => _34.row]) !== "number" || typeof _optionalChain([payload, 'access', _35 => _35.origin, 'optionalAccess', _36 => _36.col]) !== "number") {
|
|
1035
1096
|
return null;
|
|
1036
1097
|
}
|
|
1037
1098
|
return payload;
|
|
@@ -1045,7 +1106,7 @@ function readSpreadsheetClipboard(source) {
|
|
|
1045
1106
|
return {
|
|
1046
1107
|
format: "internal",
|
|
1047
1108
|
origin: payload.origin,
|
|
1048
|
-
rows: payload.cells.map((row) => row.map((cell) => typeof _optionalChain([cell, 'optionalAccess',
|
|
1109
|
+
rows: payload.cells.map((row) => row.map((cell) => typeof _optionalChain([cell, 'optionalAccess', _37 => _37.raw]) === "string" ? cell.raw : displayText(_optionalChain([cell, 'optionalAccess', _38 => _38.value]))))
|
|
1049
1110
|
};
|
|
1050
1111
|
}
|
|
1051
1112
|
const html = readFormat(source, "text/html");
|
|
@@ -1074,8 +1135,8 @@ var DEFAULT_COLUMN_WIDTH = 130;
|
|
|
1074
1135
|
var clampCount = (value, max) => Math.max(0, Math.min(Math.floor(_nullishCoalesce(value, () => ( 0))), max));
|
|
1075
1136
|
function getTableSections(doc) {
|
|
1076
1137
|
const total = doc.rows.length;
|
|
1077
|
-
const headerRows = clampCount(_optionalChain([doc, 'access',
|
|
1078
|
-
const footerRows = clampCount(_optionalChain([doc, 'access',
|
|
1138
|
+
const headerRows = clampCount(_optionalChain([doc, 'access', _39 => _39.table, 'optionalAccess', _40 => _40.headerRowCount]), total);
|
|
1139
|
+
const footerRows = clampCount(_optionalChain([doc, 'access', _41 => _41.table, 'optionalAccess', _42 => _42.footerRowCount]), total - headerRows);
|
|
1079
1140
|
return { headerRows, footerRows };
|
|
1080
1141
|
}
|
|
1081
1142
|
function getRowSection(doc, rowIndex) {
|
|
@@ -1085,8 +1146,8 @@ function getRowSection(doc, rowIndex) {
|
|
|
1085
1146
|
return "body";
|
|
1086
1147
|
}
|
|
1087
1148
|
function rowPassesFilters(doc, rowIndex, getValue) {
|
|
1088
|
-
const filter = _optionalChain([doc, 'access',
|
|
1089
|
-
if (!_optionalChain([filter, 'optionalAccess',
|
|
1149
|
+
const filter = _optionalChain([doc, 'access', _43 => _43.table, 'optionalAccess', _44 => _44.filter]);
|
|
1150
|
+
if (!_optionalChain([filter, 'optionalAccess', _45 => _45.enabled]) || filter.rules.length === 0) return true;
|
|
1090
1151
|
if (getRowSection(doc, rowIndex) !== "body") return true;
|
|
1091
1152
|
return filter.rules.every((rule) => {
|
|
1092
1153
|
const colIndex = doc.columns.findIndex((c) => c.id === rule.colId);
|
|
@@ -1095,7 +1156,7 @@ function rowPassesFilters(doc, rowIndex, getValue) {
|
|
|
1095
1156
|
});
|
|
1096
1157
|
}
|
|
1097
1158
|
function computeRowGroups(doc, getValue) {
|
|
1098
|
-
const grouping = _optionalChain([doc, 'access',
|
|
1159
|
+
const grouping = _optionalChain([doc, 'access', _46 => _46.table, 'optionalAccess', _47 => _47.grouping]);
|
|
1099
1160
|
if (!grouping) return [];
|
|
1100
1161
|
const groupCol = doc.columns.findIndex((c) => c.id === grouping.colId);
|
|
1101
1162
|
if (groupCol === -1) return [];
|
|
@@ -1125,9 +1186,9 @@ function computeRowGroups(doc, getValue) {
|
|
|
1125
1186
|
}
|
|
1126
1187
|
function buildSpreadsheetView(doc, getValue) {
|
|
1127
1188
|
const { headerRows, footerRows } = getTableSections(doc);
|
|
1128
|
-
const frozenRows = clampCount(_optionalChain([doc, 'access',
|
|
1129
|
-
const frozenCols = clampCount(_optionalChain([doc, 'access',
|
|
1130
|
-
const headerCols = clampCount(_optionalChain([doc, 'access',
|
|
1189
|
+
const frozenRows = clampCount(_optionalChain([doc, 'access', _48 => _48.table, 'optionalAccess', _49 => _49.frozenRowCount]), doc.rows.length);
|
|
1190
|
+
const frozenCols = clampCount(_optionalChain([doc, 'access', _50 => _50.table, 'optionalAccess', _51 => _51.frozenColumnCount]), doc.columns.length);
|
|
1191
|
+
const headerCols = clampCount(_optionalChain([doc, 'access', _52 => _52.table, 'optionalAccess', _53 => _53.headerColumnCount]), doc.columns.length);
|
|
1131
1192
|
const columns = [];
|
|
1132
1193
|
let left = 0;
|
|
1133
1194
|
let hiddenColumnCount = 0;
|
|
@@ -1157,7 +1218,7 @@ function buildSpreadsheetView(doc, getValue) {
|
|
|
1157
1218
|
if (doc.rows[r].hidden) hiddenRowCount++;
|
|
1158
1219
|
else if (!rowPassesFilters(doc, r, getValue)) filteredOutCount++;
|
|
1159
1220
|
}
|
|
1160
|
-
const grouping = _optionalChain([doc, 'access',
|
|
1221
|
+
const grouping = _optionalChain([doc, 'access', _54 => _54.table, 'optionalAccess', _55 => _55.grouping]);
|
|
1161
1222
|
if (grouping && doc.columns.some((c) => c.id === grouping.colId)) {
|
|
1162
1223
|
for (const group of groups) {
|
|
1163
1224
|
rows.push({ kind: "group", group });
|
|
@@ -1191,7 +1252,7 @@ function buildSpreadsheetView(doc, getValue) {
|
|
|
1191
1252
|
while (run < visible.length && positions.get(visible[run]) === positions.get(visible[0]) + run) run++;
|
|
1192
1253
|
return { first: visible[0], run };
|
|
1193
1254
|
};
|
|
1194
|
-
for (const raw of _nullishCoalesce(_optionalChain([doc, 'access',
|
|
1255
|
+
for (const raw of _nullishCoalesce(_optionalChain([doc, 'access', _56 => _56.table, 'optionalAccess', _57 => _57.merges]), () => ( []))) {
|
|
1195
1256
|
const merge = normalizeRange(raw);
|
|
1196
1257
|
const rowIdx = [];
|
|
1197
1258
|
const colIdx = [];
|
|
@@ -1228,29 +1289,43 @@ function buildSpreadsheetView(doc, getValue) {
|
|
|
1228
1289
|
|
|
1229
1290
|
// src/spreadsheet/controller.ts
|
|
1230
1291
|
var nextIdSequence = 0;
|
|
1292
|
+
var MAX_SPILL_PASSES = 25;
|
|
1293
|
+
var spillCellId = (rowId, colId) => `${rowId}\0${colId}`;
|
|
1231
1294
|
var SpreadsheetController = (_class3 = class {
|
|
1232
1295
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1296
|
+
__init7() {this.activeCell = null}
|
|
1297
|
+
__init8() {this.selectedRange = null}
|
|
1298
|
+
__init9() {this.editingCell = null}
|
|
1299
|
+
__init10() {this.draftValue = ""}
|
|
1300
|
+
__init11() {this.binder = new DataSourceBinder()}
|
|
1301
|
+
__init12() {this.depGraph = new DependencyGraph()}
|
|
1239
1302
|
|
|
1240
1303
|
|
|
1241
1304
|
|
|
1242
1305
|
|
|
1243
1306
|
|
|
1244
1307
|
// History stack for undo/redo
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1308
|
+
__init13() {this.undoStack = []}
|
|
1309
|
+
__init14() {this.redoStack = []}
|
|
1310
|
+
__init15() {this.isApplyingHistory = false}
|
|
1248
1311
|
// Set while importing TSV: history and recalculation are done once at the end.
|
|
1249
|
-
|
|
1250
|
-
|
|
1312
|
+
__init16() {this.batching = false}
|
|
1313
|
+
__init17() {this.pendingCommits = []}
|
|
1251
1314
|
// Row being evaluated, so [property] references resolve per row.
|
|
1252
|
-
|
|
1253
|
-
|
|
1315
|
+
__init18() {this.evaluatingRowIndex = null}
|
|
1316
|
+
// Cell being evaluated, for implicit intersection (`=@A:A`).
|
|
1317
|
+
__init19() {this.evaluatingCell = null}
|
|
1318
|
+
// Dynamic arrays. Spilled values are derived state: they live here, not in
|
|
1319
|
+
// the document, and every recalculation rebuilds them.
|
|
1320
|
+
__init20() {this.spills = /* @__PURE__ */ new Map()}
|
|
1321
|
+
// anchor key -> spill
|
|
1322
|
+
__init21() {this.spilledBy = /* @__PURE__ */ new Map()}
|
|
1323
|
+
// spilled cell key -> anchor key
|
|
1324
|
+
__init22() {this.spillCells = /* @__PURE__ */ new Map()}
|
|
1325
|
+
// spillCellId -> displayed cell
|
|
1326
|
+
// Cells whose spill ownership changed during the current pass.
|
|
1327
|
+
__init23() {this.spillChanges = null}
|
|
1328
|
+
constructor(options = {}) {;_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);_class3.prototype.__init11.call(this);_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);_class3.prototype.__init21.call(this);_class3.prototype.__init22.call(this);_class3.prototype.__init23.call(this);_class3.prototype.__init24.call(this);
|
|
1254
1329
|
const defaultCols = [
|
|
1255
1330
|
{ id: "col_a", key: "A", title: "A", width: 120, type: "freeform" },
|
|
1256
1331
|
{ id: "col_b", key: "B", title: "B", width: 120, type: "freeform" },
|
|
@@ -1264,14 +1339,14 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1264
1339
|
type: "freeform"
|
|
1265
1340
|
}));
|
|
1266
1341
|
this.document = {
|
|
1267
|
-
id: _optionalChain([options, 'access',
|
|
1268
|
-
name: _optionalChain([options, 'access',
|
|
1269
|
-
columns: _optionalChain([options, 'access',
|
|
1270
|
-
rows: _optionalChain([options, 'access',
|
|
1271
|
-
cells: _optionalChain([options, 'access',
|
|
1272
|
-
createdAt: _optionalChain([options, 'access',
|
|
1273
|
-
updatedAt: _optionalChain([options, 'access',
|
|
1274
|
-
..._optionalChain([options, 'access',
|
|
1342
|
+
id: _optionalChain([options, 'access', _58 => _58.document, 'optionalAccess', _59 => _59.id]) || `sheet_${Date.now()}`,
|
|
1343
|
+
name: _optionalChain([options, 'access', _60 => _60.document, 'optionalAccess', _61 => _61.name]) || "Sheet 1",
|
|
1344
|
+
columns: _optionalChain([options, 'access', _62 => _62.document, 'optionalAccess', _63 => _63.columns]) || defaultCols,
|
|
1345
|
+
rows: _optionalChain([options, 'access', _64 => _64.document, 'optionalAccess', _65 => _65.rows]) || defaultRows,
|
|
1346
|
+
cells: _optionalChain([options, 'access', _66 => _66.document, 'optionalAccess', _67 => _67.cells]) || {},
|
|
1347
|
+
createdAt: _optionalChain([options, 'access', _68 => _68.document, 'optionalAccess', _69 => _69.createdAt]) || Date.now(),
|
|
1348
|
+
updatedAt: _optionalChain([options, 'access', _70 => _70.document, 'optionalAccess', _71 => _71.updatedAt]) || Date.now(),
|
|
1349
|
+
..._optionalChain([options, 'access', _72 => _72.document, 'optionalAccess', _73 => _73.table]) ? { table: options.document.table } : {}
|
|
1275
1350
|
};
|
|
1276
1351
|
this.primaryDataSourceId = options.primaryDataSourceId;
|
|
1277
1352
|
this.onDocumentChange = options.onDocumentChange;
|
|
@@ -1280,10 +1355,12 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1280
1355
|
if (options.dataSources) {
|
|
1281
1356
|
options.dataSources.forEach((ds) => this.binder.register(ds));
|
|
1282
1357
|
}
|
|
1283
|
-
this.evaluator = new (0,
|
|
1358
|
+
this.evaluator = new (0, _chunkSAZRENEZcjs.FormulaEvaluator)({
|
|
1284
1359
|
resolveCell: (colStr, rowNum) => this.resolveCellByCoord(colStr, rowNum),
|
|
1285
1360
|
resolveRange: (sCol, sRow, eCol, eRow) => this.resolveRangeByCoords(sCol, sRow, eCol, eRow),
|
|
1286
|
-
resolveProperty: (prop) => this.resolveCurrentRowProperty(prop)
|
|
1361
|
+
resolveProperty: (prop) => this.resolveCurrentRowProperty(prop),
|
|
1362
|
+
resolveSpill: (colStr, rowNum) => this.resolveSpillByCoord(colStr, rowNum),
|
|
1363
|
+
getFormulaCell: () => this.evaluatingCell
|
|
1287
1364
|
});
|
|
1288
1365
|
this.syncWithDataSource();
|
|
1289
1366
|
this.recalculateAll();
|
|
@@ -1320,7 +1397,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1320
1397
|
r.index = idx;
|
|
1321
1398
|
});
|
|
1322
1399
|
this.document.columns.forEach((c, idx) => {
|
|
1323
|
-
c.key =
|
|
1400
|
+
c.key = _chunkSAZRENEZcjs.indexToColName.call(void 0, idx);
|
|
1324
1401
|
});
|
|
1325
1402
|
}
|
|
1326
1403
|
getColumn(colIdOrKey) {
|
|
@@ -1335,7 +1412,12 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1335
1412
|
return this.document.rows.find((r) => r.id === rowIdOrIndex);
|
|
1336
1413
|
}
|
|
1337
1414
|
getCell(rowId, colId) {
|
|
1338
|
-
const existing = _optionalChain([this, 'access',
|
|
1415
|
+
const existing = _optionalChain([this, 'access', _74 => _74.document, 'access', _75 => _75.cells, 'access', _76 => _76[rowId], 'optionalAccess', _77 => _77[colId]]);
|
|
1416
|
+
if (existing && existing.raw !== "") return existing;
|
|
1417
|
+
if (this.spillCells.size > 0) {
|
|
1418
|
+
const spilled = this.spillCells.get(spillCellId(rowId, colId));
|
|
1419
|
+
if (spilled) return spilled;
|
|
1420
|
+
}
|
|
1339
1421
|
if (existing) return existing;
|
|
1340
1422
|
const col = this.document.columns.find((c) => c.id === colId);
|
|
1341
1423
|
const row = this.document.rows.find((r) => r.id === rowId);
|
|
@@ -1362,7 +1444,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1362
1444
|
format: col.format
|
|
1363
1445
|
};
|
|
1364
1446
|
}
|
|
1365
|
-
return { raw: "", value: "", format: _optionalChain([col, 'optionalAccess',
|
|
1447
|
+
return { raw: "", value: "", format: _optionalChain([col, 'optionalAccess', _78 => _78.format]) };
|
|
1366
1448
|
}
|
|
1367
1449
|
setCellValue(rowId, colId, raw) {
|
|
1368
1450
|
this.recordSnapshot();
|
|
@@ -1371,7 +1453,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1371
1453
|
}
|
|
1372
1454
|
const col = this.document.columns.find((c) => c.id === colId);
|
|
1373
1455
|
const row = this.document.rows.find((r) => r.id === rowId);
|
|
1374
|
-
if (_optionalChain([col, 'optionalAccess',
|
|
1456
|
+
if (_optionalChain([col, 'optionalAccess', _79 => _79.type]) === "bound" && col.binding && _optionalChain([row, 'optionalAccess', _80 => _80.recordId])) {
|
|
1375
1457
|
this.binder.commitBoundValue(
|
|
1376
1458
|
col.binding.dataSource,
|
|
1377
1459
|
row.recordId,
|
|
@@ -1384,7 +1466,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1384
1466
|
this.document.cells[rowId][colId] = {
|
|
1385
1467
|
raw,
|
|
1386
1468
|
value: raw,
|
|
1387
|
-
format: _optionalChain([col, 'optionalAccess',
|
|
1469
|
+
format: _optionalChain([col, 'optionalAccess', _81 => _81.format])
|
|
1388
1470
|
};
|
|
1389
1471
|
this.document.updatedAt = Date.now();
|
|
1390
1472
|
if (this.batching) {
|
|
@@ -1393,8 +1475,8 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1393
1475
|
}
|
|
1394
1476
|
this.recalculateCell(rowId, colId);
|
|
1395
1477
|
this.notifyChange();
|
|
1396
|
-
const evaluatedVal = _optionalChain([this, 'access',
|
|
1397
|
-
_optionalChain([this, 'access',
|
|
1478
|
+
const evaluatedVal = _optionalChain([this, 'access', _82 => _82.document, 'access', _83 => _83.cells, 'access', _84 => _84[rowId], 'access', _85 => _85[colId], 'optionalAccess', _86 => _86.value]);
|
|
1479
|
+
_optionalChain([this, 'access', _87 => _87.onCellCommit, 'optionalCall', _88 => _88(rowId, colId, raw, evaluatedVal)]);
|
|
1398
1480
|
}
|
|
1399
1481
|
getCellKey(rowId, colId) {
|
|
1400
1482
|
const row = this.document.rows.find((r) => r.id === rowId);
|
|
@@ -1408,7 +1490,30 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1408
1490
|
*/
|
|
1409
1491
|
recalculateCell(rowId, colId) {
|
|
1410
1492
|
const cellKey = this.getCellKey(rowId, colId);
|
|
1411
|
-
this.
|
|
1493
|
+
const anchor = this.spilledBy.get(cellKey);
|
|
1494
|
+
this.recalculateKeys(anchor ? [cellKey, anchor] : [cellKey], true);
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Recalculates `keys` (and, with `includeDependents`, their dependents) in
|
|
1498
|
+
* dependency order. Spill ranges are only known after evaluating their
|
|
1499
|
+
* anchors, so when a pass changes which cells hold spilled values (and so
|
|
1500
|
+
* the dependency graph), the dependents of those cells are recalculated in
|
|
1501
|
+
* another pass, until nothing changes.
|
|
1502
|
+
*/
|
|
1503
|
+
recalculateKeys(keys, includeDependents) {
|
|
1504
|
+
let pending = Array.from(keys);
|
|
1505
|
+
let withDependents = includeDependents;
|
|
1506
|
+
for (let pass = 0; pass < MAX_SPILL_PASSES && pending.length > 0; pass++) {
|
|
1507
|
+
const changed = /* @__PURE__ */ new Set();
|
|
1508
|
+
this.spillChanges = changed;
|
|
1509
|
+
try {
|
|
1510
|
+
this.runEvaluationPlan(this.depGraph.getEvaluationPlan(pending, { includeDependents: withDependents }));
|
|
1511
|
+
} finally {
|
|
1512
|
+
this.spillChanges = null;
|
|
1513
|
+
}
|
|
1514
|
+
pending = Array.from(changed);
|
|
1515
|
+
withDependents = true;
|
|
1516
|
+
}
|
|
1412
1517
|
}
|
|
1413
1518
|
/**
|
|
1414
1519
|
* Rebuilds the dependency graph from scratch and recalculates every formula
|
|
@@ -1416,10 +1521,13 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1416
1521
|
*/
|
|
1417
1522
|
recalculateAll() {
|
|
1418
1523
|
this.depGraph.clear();
|
|
1524
|
+
this.spills.clear();
|
|
1525
|
+
this.spilledBy.clear();
|
|
1526
|
+
this.spillCells.clear();
|
|
1419
1527
|
const formulaKeys = [];
|
|
1420
1528
|
for (const row of this.document.rows) {
|
|
1421
1529
|
for (const col of this.document.columns) {
|
|
1422
|
-
const cell = _nullishCoalesce(_optionalChain([this, 'access',
|
|
1530
|
+
const cell = _nullishCoalesce(_optionalChain([this, 'access', _89 => _89.document, 'access', _90 => _90.cells, 'access', _91 => _91[row.id], 'optionalAccess', _92 => _92[col.id]]), () => ( this.getDerivedCell(row, col)));
|
|
1423
1531
|
if (cell.raw.startsWith("=")) {
|
|
1424
1532
|
const cellKey = `${col.key}${row.index + 1}`.toUpperCase();
|
|
1425
1533
|
this.depGraph.setCellFormula(cellKey, cell.raw);
|
|
@@ -1427,7 +1535,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1427
1535
|
}
|
|
1428
1536
|
}
|
|
1429
1537
|
}
|
|
1430
|
-
this.
|
|
1538
|
+
this.recalculateKeys(formulaKeys, false);
|
|
1431
1539
|
}
|
|
1432
1540
|
runEvaluationPlan(plan) {
|
|
1433
1541
|
for (const key of plan.order) {
|
|
@@ -1454,7 +1562,10 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1454
1562
|
if (!this.document.cells[row.id]) this.document.cells[row.id] = {};
|
|
1455
1563
|
const deps = this.depGraph.getDependencies(cellKey);
|
|
1456
1564
|
const selfReference = deps.includes(cellKey) || deps.includes(`${col.key.toUpperCase()}:`);
|
|
1457
|
-
const
|
|
1565
|
+
const spilledKeys = this.depGraph.getSpilledKeys(cellKey);
|
|
1566
|
+
const ownSpill = deps.find((dep) => spilledKeys.includes(dep));
|
|
1567
|
+
const errorMessage = selfReference ? "This formula can't reference its own cell." : ownSpill ? `This formula refers to ${ownSpill}, which holds its own spilled results (a circular reference).` : "This formula is part of a circular reference: it depends on its own result through other cells.";
|
|
1568
|
+
this.clearSpill(cellKey.toUpperCase(), true);
|
|
1458
1569
|
this.document.cells[row.id][col.id] = { ...cell, value: "#CYCLE!", error: "#CYCLE!", errorMessage };
|
|
1459
1570
|
}
|
|
1460
1571
|
evalSingleCellByKey(cellKey) {
|
|
@@ -1471,25 +1582,176 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1471
1582
|
cell.error = void 0;
|
|
1472
1583
|
cell.errorMessage = void 0;
|
|
1473
1584
|
}
|
|
1585
|
+
this.clearSpill(`${colName}${rowNum}`);
|
|
1474
1586
|
return;
|
|
1475
1587
|
}
|
|
1476
1588
|
try {
|
|
1477
1589
|
this.evaluatingRowIndex = rowNum - 1;
|
|
1590
|
+
this.evaluatingCell = { col: colName, row: rowNum };
|
|
1478
1591
|
const result = this.evaluator.evaluateWithDiagnostics(cell.raw);
|
|
1479
1592
|
if (!this.document.cells[row.id]) {
|
|
1480
1593
|
this.document.cells[row.id] = {};
|
|
1481
1594
|
}
|
|
1595
|
+
let { value, error, message } = result;
|
|
1596
|
+
if (result.array) {
|
|
1597
|
+
const blocked = this.placeSpill(`${colName}${rowNum}`, rowNum - 1, this.document.columns.indexOf(col), result.array);
|
|
1598
|
+
if (blocked) {
|
|
1599
|
+
value = "#SPILL!";
|
|
1600
|
+
error = "#SPILL!";
|
|
1601
|
+
message = blocked;
|
|
1602
|
+
}
|
|
1603
|
+
} else {
|
|
1604
|
+
this.clearSpill(`${colName}${rowNum}`);
|
|
1605
|
+
}
|
|
1482
1606
|
this.document.cells[row.id][col.id] = {
|
|
1483
1607
|
...cell,
|
|
1484
|
-
value
|
|
1608
|
+
value,
|
|
1485
1609
|
// `#ERROR!` (malformed formula, wrong argument count) keeps its
|
|
1486
1610
|
// message in `error`, as before; other errors store their code.
|
|
1487
|
-
error:
|
|
1488
|
-
errorMessage:
|
|
1611
|
+
error: error === "#ERROR!" ? message : error,
|
|
1612
|
+
errorMessage: message
|
|
1489
1613
|
};
|
|
1490
1614
|
} finally {
|
|
1491
1615
|
this.evaluatingRowIndex = null;
|
|
1616
|
+
this.evaluatingCell = null;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
// --- Dynamic arrays (spilling) ---
|
|
1620
|
+
/**
|
|
1621
|
+
* Spills `array` from the anchor at (row, col) into the cells below and to
|
|
1622
|
+
* the right. Returns why it can't (the anchor then shows `#SPILL!`), or
|
|
1623
|
+
* null once placed. The grid never grows to fit an array, as in Excel.
|
|
1624
|
+
*/
|
|
1625
|
+
placeSpill(anchor, row, col, array) {
|
|
1626
|
+
const { rows, cols } = array;
|
|
1627
|
+
const area = { startRow: row, startCol: col, endRow: row + rows - 1, endCol: col + cols - 1 };
|
|
1628
|
+
const label = `${_chunkSAZRENEZcjs.indexToColName.call(void 0, area.startCol)}${area.startRow + 1}:${_chunkSAZRENEZcjs.indexToColName.call(void 0, area.endCol)}${area.endRow + 1}`;
|
|
1629
|
+
let reason = null;
|
|
1630
|
+
const blockers = [];
|
|
1631
|
+
if (area.endRow >= this.document.rows.length || area.endCol >= this.document.columns.length) {
|
|
1632
|
+
reason = `The ${rows}\xD7${cols} result needs ${label}, which extends past the edge of the sheet.`;
|
|
1633
|
+
} else if (this.getMerges().some((m) => rangesIntersect(m, area))) {
|
|
1634
|
+
reason = `The result can't spill into merged cells (it needs ${label}).`;
|
|
1635
|
+
} else {
|
|
1636
|
+
for (let c = area.startCol; c <= area.endCol; c++) {
|
|
1637
|
+
const column = this.document.columns[c];
|
|
1638
|
+
for (let r = area.startRow; r <= area.endRow; r++) {
|
|
1639
|
+
if (r === row && c === col) continue;
|
|
1640
|
+
const rowObj = this.document.rows[r];
|
|
1641
|
+
const key = `${column.key}${r + 1}`.toUpperCase();
|
|
1642
|
+
const stored = _optionalChain([this, 'access', _93 => _93.document, 'access', _94 => _94.cells, 'access', _95 => _95[rowObj.id], 'optionalAccess', _96 => _96[column.id]]);
|
|
1643
|
+
const raw = stored ? stored.raw : this.getDerivedCell(rowObj, column).raw;
|
|
1644
|
+
const owner = this.spilledBy.get(key);
|
|
1645
|
+
if (raw !== "") {
|
|
1646
|
+
blockers.push(key);
|
|
1647
|
+
reason ??= `The result needs ${label}, but ${key} isn't empty.`;
|
|
1648
|
+
} else if (owner && owner !== anchor) {
|
|
1649
|
+
blockers.push(key);
|
|
1650
|
+
reason ??= `The result needs ${label}, but ${key} already holds values spilled from ${owner}.`;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
if (reason) {
|
|
1656
|
+
this.clearSpill(anchor);
|
|
1657
|
+
this.depGraph.setSpillEdges(anchor, [], blockers);
|
|
1658
|
+
return reason;
|
|
1659
|
+
}
|
|
1660
|
+
const previous = this.spills.get(anchor);
|
|
1661
|
+
const cells = [];
|
|
1662
|
+
for (let c = 0; c < cols; c++) {
|
|
1663
|
+
const column = this.document.columns[col + c];
|
|
1664
|
+
for (let r = 0; r < rows; r++) {
|
|
1665
|
+
if (r === 0 && c === 0) continue;
|
|
1666
|
+
const rowObj = this.document.rows[row + r];
|
|
1667
|
+
const key = `${column.key}${row + r + 1}`.toUpperCase();
|
|
1668
|
+
const value = _nullishCoalesce(array.values[c * rows + r], () => ( ""));
|
|
1669
|
+
const display = { raw: "", value, format: column.format, spillAnchor: anchor };
|
|
1670
|
+
if (_chunkSAZRENEZcjs.isFormulaError.call(void 0, value)) {
|
|
1671
|
+
display.error = value;
|
|
1672
|
+
display.errorMessage = _chunkSAZRENEZcjs.describeFormulaError.call(void 0, value);
|
|
1673
|
+
}
|
|
1674
|
+
this.spillCells.set(spillCellId(rowObj.id, column.id), display);
|
|
1675
|
+
if (this.spilledBy.get(key) !== anchor) {
|
|
1676
|
+
this.spilledBy.set(key, anchor);
|
|
1677
|
+
_optionalChain([this, 'access', _97 => _97.spillChanges, 'optionalAccess', _98 => _98.add, 'call', _99 => _99(key)]);
|
|
1678
|
+
}
|
|
1679
|
+
cells.push({ key, rowId: rowObj.id, colId: column.id });
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
if (previous) {
|
|
1683
|
+
const kept = new Set(cells.map((cell) => cell.key));
|
|
1684
|
+
for (const old of previous.cells) {
|
|
1685
|
+
if (kept.has(old.key)) continue;
|
|
1686
|
+
this.forgetSpilledCell(anchor, old);
|
|
1687
|
+
}
|
|
1492
1688
|
}
|
|
1689
|
+
this.spills.set(anchor, { anchor, row, col, rows, cols, values: array.values, cells });
|
|
1690
|
+
this.depGraph.setSpillEdges(anchor, cells.map((cell) => cell.key));
|
|
1691
|
+
return null;
|
|
1692
|
+
}
|
|
1693
|
+
/** Removes the array spilled from `anchor`. With `keepEdges`, its dependency edges stay. */
|
|
1694
|
+
clearSpill(anchor, keepEdges = false) {
|
|
1695
|
+
const record = this.spills.get(anchor);
|
|
1696
|
+
if (record) {
|
|
1697
|
+
for (const cell of record.cells) this.forgetSpilledCell(anchor, cell);
|
|
1698
|
+
this.spills.delete(anchor);
|
|
1699
|
+
}
|
|
1700
|
+
if (!keepEdges) this.depGraph.setSpillEdges(anchor, []);
|
|
1701
|
+
}
|
|
1702
|
+
forgetSpilledCell(anchor, cell) {
|
|
1703
|
+
if (this.spilledBy.get(cell.key) !== anchor) return;
|
|
1704
|
+
this.spilledBy.delete(cell.key);
|
|
1705
|
+
this.spillCells.delete(spillCellId(cell.rowId, cell.colId));
|
|
1706
|
+
_optionalChain([this, 'access', _100 => _100.spillChanges, 'optionalAccess', _101 => _101.add, 'call', _102 => _102(cell.key)]);
|
|
1707
|
+
}
|
|
1708
|
+
resolveSpillByCoord(colStr, rowNum) {
|
|
1709
|
+
const record = this.spills.get(`${colStr}${rowNum}`.toUpperCase());
|
|
1710
|
+
if (record) return { rows: record.rows, cols: record.cols, values: record.values };
|
|
1711
|
+
const value = this.resolveCellByCoord(colStr, rowNum);
|
|
1712
|
+
return _chunkSAZRENEZcjs.isFormulaError.call(void 0, value) ? value : "#REF!";
|
|
1713
|
+
}
|
|
1714
|
+
toSpill(record) {
|
|
1715
|
+
const row = this.document.rows[record.row];
|
|
1716
|
+
const col = this.document.columns[record.col];
|
|
1717
|
+
return {
|
|
1718
|
+
key: record.anchor,
|
|
1719
|
+
anchor: { row: record.row, col: record.col },
|
|
1720
|
+
range: {
|
|
1721
|
+
startRow: record.row,
|
|
1722
|
+
startCol: record.col,
|
|
1723
|
+
endRow: record.row + record.rows - 1,
|
|
1724
|
+
endCol: record.col + record.cols - 1
|
|
1725
|
+
},
|
|
1726
|
+
formula: row && col ? this.getCell(row.id, col.id).raw : ""
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* The dynamic array covering (row, col), whether it is the anchor (the cell
|
|
1731
|
+
* holding the formula) or a spilled cell; null when there is none.
|
|
1732
|
+
*/
|
|
1733
|
+
getSpillAt(row, col) {
|
|
1734
|
+
if (this.spills.size === 0) return null;
|
|
1735
|
+
const key = `${_chunkSAZRENEZcjs.indexToColName.call(void 0, col)}${row + 1}`;
|
|
1736
|
+
const record = _nullishCoalesce(this.spills.get(key), () => ( this.spills.get(_nullishCoalesce(this.spilledBy.get(key), () => ( "")))));
|
|
1737
|
+
return record ? this.toSpill(record) : null;
|
|
1738
|
+
}
|
|
1739
|
+
/** Every dynamic array currently spilled. */
|
|
1740
|
+
getSpills() {
|
|
1741
|
+
return Array.from(this.spills.values(), (record) => this.toSpill(record));
|
|
1742
|
+
}
|
|
1743
|
+
/** Whether `range` overlaps a spilled array (its anchor or spilled cells). */
|
|
1744
|
+
intersectsSpill(range) {
|
|
1745
|
+
for (const record of this.spills.values()) {
|
|
1746
|
+
const area = {
|
|
1747
|
+
startRow: record.row,
|
|
1748
|
+
startCol: record.col,
|
|
1749
|
+
endRow: record.row + record.rows - 1,
|
|
1750
|
+
endCol: record.col + record.cols - 1
|
|
1751
|
+
};
|
|
1752
|
+
if (rangesIntersect(area, range)) return true;
|
|
1753
|
+
}
|
|
1754
|
+
return false;
|
|
1493
1755
|
}
|
|
1494
1756
|
resolveCellByCoord(colStr, rowNum) {
|
|
1495
1757
|
const col = this.document.columns.find((c) => c.key.toUpperCase() === colStr.toUpperCase());
|
|
@@ -1498,15 +1760,15 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1498
1760
|
return _nullishCoalesce(this.getCell(row.id, col.id).value, () => ( ""));
|
|
1499
1761
|
}
|
|
1500
1762
|
resolveRangeByCoords(sCol, sRow, eCol, eRow) {
|
|
1501
|
-
const startC =
|
|
1502
|
-
const endC =
|
|
1763
|
+
const startC = _chunkSAZRENEZcjs.colNameToIndex.call(void 0, sCol);
|
|
1764
|
+
const endC = _chunkSAZRENEZcjs.colNameToIndex.call(void 0, eCol);
|
|
1503
1765
|
const minC = Math.min(startC, endC);
|
|
1504
1766
|
const maxC = Math.max(startC, endC);
|
|
1505
1767
|
const minR = Math.min(sRow, eRow);
|
|
1506
|
-
const maxR = Math.min(Math.max(sRow, eRow),
|
|
1768
|
+
const maxR = Math.min(Math.max(sRow, eRow), _chunkSAZRENEZcjs.WHOLE_COLUMN_END_ROW, this.document.rows.length);
|
|
1507
1769
|
const results = [];
|
|
1508
1770
|
for (let c = minC; c <= maxC; c++) {
|
|
1509
|
-
const colName =
|
|
1771
|
+
const colName = _chunkSAZRENEZcjs.indexToColName.call(void 0, c);
|
|
1510
1772
|
const col = this.document.columns.find((colDef) => colDef.key.toUpperCase() === colName);
|
|
1511
1773
|
if (!col) continue;
|
|
1512
1774
|
for (let r = minR; r <= maxR; r++) {
|
|
@@ -1518,7 +1780,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1518
1780
|
return results;
|
|
1519
1781
|
}
|
|
1520
1782
|
resolveCurrentRowProperty(prop) {
|
|
1521
|
-
const rowIndex = _nullishCoalesce(this.evaluatingRowIndex, () => ( _optionalChain([this, 'access',
|
|
1783
|
+
const rowIndex = _nullishCoalesce(this.evaluatingRowIndex, () => ( _optionalChain([this, 'access', _103 => _103.activeCell, 'optionalAccess', _104 => _104.row])));
|
|
1522
1784
|
if (rowIndex === void 0 || rowIndex === null) return 0;
|
|
1523
1785
|
const row = this.document.rows[rowIndex];
|
|
1524
1786
|
if (!row || !row.recordId || !this.primaryDataSourceId) return 0;
|
|
@@ -1536,8 +1798,8 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1536
1798
|
this.activeCell = {
|
|
1537
1799
|
row: activeRow,
|
|
1538
1800
|
col: activeCol,
|
|
1539
|
-
rowId: _optionalChain([rowObj, 'optionalAccess',
|
|
1540
|
-
colId: _optionalChain([colObj, 'optionalAccess',
|
|
1801
|
+
rowId: _optionalChain([rowObj, 'optionalAccess', _105 => _105.id]),
|
|
1802
|
+
colId: _optionalChain([colObj, 'optionalAccess', _106 => _106.id])
|
|
1541
1803
|
};
|
|
1542
1804
|
if (extendSelection && this.selectedRange) {
|
|
1543
1805
|
this.selectedRange = this.expandRangeToMerges({
|
|
@@ -1556,16 +1818,16 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1556
1818
|
endCol: clampedCol
|
|
1557
1819
|
};
|
|
1558
1820
|
}
|
|
1559
|
-
_optionalChain([this, 'access',
|
|
1821
|
+
_optionalChain([this, 'access', _107 => _107.onSelectionChange, 'optionalCall', _108 => _108(this.activeCell, this.selectedRange)]);
|
|
1560
1822
|
}
|
|
1561
1823
|
selectRange(range) {
|
|
1562
1824
|
this.selectedRange = range;
|
|
1563
|
-
_optionalChain([this, 'access',
|
|
1825
|
+
_optionalChain([this, 'access', _109 => _109.onSelectionChange, 'optionalCall', _110 => _110(this.activeCell, this.selectedRange)]);
|
|
1564
1826
|
}
|
|
1565
1827
|
startEditing(row, col, initialValue) {
|
|
1566
|
-
this.selectCell(_nullishCoalesce(_nullishCoalesce(row, () => ( _optionalChain([this, 'access',
|
|
1567
|
-
const targetRow = _nullishCoalesce(_optionalChain([this, 'access',
|
|
1568
|
-
const targetCol = _nullishCoalesce(_optionalChain([this, 'access',
|
|
1828
|
+
this.selectCell(_nullishCoalesce(_nullishCoalesce(row, () => ( _optionalChain([this, 'access', _111 => _111.activeCell, 'optionalAccess', _112 => _112.row]))), () => ( 0)), _nullishCoalesce(_nullishCoalesce(col, () => ( _optionalChain([this, 'access', _113 => _113.activeCell, 'optionalAccess', _114 => _114.col]))), () => ( 0)));
|
|
1829
|
+
const targetRow = _nullishCoalesce(_optionalChain([this, 'access', _115 => _115.activeCell, 'optionalAccess', _116 => _116.row]), () => ( 0));
|
|
1830
|
+
const targetCol = _nullishCoalesce(_optionalChain([this, 'access', _117 => _117.activeCell, 'optionalAccess', _118 => _118.col]), () => ( 0));
|
|
1569
1831
|
const rowObj = this.document.rows[targetRow];
|
|
1570
1832
|
const colObj = this.document.columns[targetCol];
|
|
1571
1833
|
if (!rowObj || !colObj) return;
|
|
@@ -1619,17 +1881,17 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1619
1881
|
// --- Grid Structure Mutations ---
|
|
1620
1882
|
insertColumn(index, config) {
|
|
1621
1883
|
this.recordSnapshot();
|
|
1622
|
-
const newId = _optionalChain([config, 'optionalAccess',
|
|
1884
|
+
const newId = _optionalChain([config, 'optionalAccess', _119 => _119.id]) || this.generateId("col");
|
|
1623
1885
|
const newCol = {
|
|
1624
1886
|
id: newId,
|
|
1625
|
-
key:
|
|
1626
|
-
title: _optionalChain([config, 'optionalAccess',
|
|
1627
|
-
width: _optionalChain([config, 'optionalAccess',
|
|
1628
|
-
type: _optionalChain([config, 'optionalAccess',
|
|
1629
|
-
binding: _optionalChain([config, 'optionalAccess',
|
|
1630
|
-
formula: _optionalChain([config, 'optionalAccess',
|
|
1631
|
-
format: _optionalChain([config, 'optionalAccess',
|
|
1632
|
-
readOnly: _optionalChain([config, 'optionalAccess',
|
|
1887
|
+
key: _chunkSAZRENEZcjs.indexToColName.call(void 0, index),
|
|
1888
|
+
title: _optionalChain([config, 'optionalAccess', _120 => _120.title]) || _chunkSAZRENEZcjs.indexToColName.call(void 0, index),
|
|
1889
|
+
width: _optionalChain([config, 'optionalAccess', _121 => _121.width]) || 130,
|
|
1890
|
+
type: _optionalChain([config, 'optionalAccess', _122 => _122.type]) || "freeform",
|
|
1891
|
+
binding: _optionalChain([config, 'optionalAccess', _123 => _123.binding]),
|
|
1892
|
+
formula: _optionalChain([config, 'optionalAccess', _124 => _124.formula]),
|
|
1893
|
+
format: _optionalChain([config, 'optionalAccess', _125 => _125.format]) || "text",
|
|
1894
|
+
readOnly: _optionalChain([config, 'optionalAccess', _126 => _126.readOnly])
|
|
1633
1895
|
};
|
|
1634
1896
|
this.shiftReferences({ axis: "col", index, type: "insert" });
|
|
1635
1897
|
this.adjustTableForStructuralChange({ axis: "col", index, type: "insert" });
|
|
@@ -1654,13 +1916,13 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1654
1916
|
}
|
|
1655
1917
|
insertRow(index, config) {
|
|
1656
1918
|
this.recordSnapshot();
|
|
1657
|
-
const newId = _optionalChain([config, 'optionalAccess',
|
|
1919
|
+
const newId = _optionalChain([config, 'optionalAccess', _127 => _127.id]) || this.generateId("row");
|
|
1658
1920
|
const newRow = {
|
|
1659
1921
|
id: newId,
|
|
1660
1922
|
index,
|
|
1661
|
-
height: _optionalChain([config, 'optionalAccess',
|
|
1662
|
-
recordId: _optionalChain([config, 'optionalAccess',
|
|
1663
|
-
type: _optionalChain([config, 'optionalAccess',
|
|
1923
|
+
height: _optionalChain([config, 'optionalAccess', _128 => _128.height]) || 32,
|
|
1924
|
+
recordId: _optionalChain([config, 'optionalAccess', _129 => _129.recordId]),
|
|
1925
|
+
type: _optionalChain([config, 'optionalAccess', _130 => _130.type]) || "freeform"
|
|
1664
1926
|
};
|
|
1665
1927
|
this.shiftReferences({ axis: "row", index, type: "insert" });
|
|
1666
1928
|
this.adjustTableForStructuralChange({ axis: "row", index, type: "insert" });
|
|
@@ -1691,14 +1953,14 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1691
1953
|
shiftReferences(change) {
|
|
1692
1954
|
for (const rowCells of Object.values(this.document.cells)) {
|
|
1693
1955
|
for (const cell of Object.values(rowCells)) {
|
|
1694
|
-
if (_optionalChain([cell, 'access',
|
|
1956
|
+
if (_optionalChain([cell, 'access', _131 => _131.raw, 'optionalAccess', _132 => _132.startsWith, 'call', _133 => _133("=")])) {
|
|
1695
1957
|
cell.raw = shiftFormulaReferences(cell.raw, change);
|
|
1696
1958
|
}
|
|
1697
1959
|
}
|
|
1698
1960
|
}
|
|
1699
1961
|
if (change.axis === "col") {
|
|
1700
1962
|
for (const col of this.document.columns) {
|
|
1701
|
-
if (_optionalChain([col, 'access',
|
|
1963
|
+
if (_optionalChain([col, 'access', _134 => _134.formula, 'optionalAccess', _135 => _135.startsWith, 'call', _136 => _136("=")])) {
|
|
1702
1964
|
col.formula = shiftFormulaReferences(col.formula, change);
|
|
1703
1965
|
}
|
|
1704
1966
|
}
|
|
@@ -1766,7 +2028,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1766
2028
|
this.document.rows.push({ id: this.generateId("row"), index, height: 32, type: "freeform" });
|
|
1767
2029
|
}
|
|
1768
2030
|
while (colIndex >= this.document.columns.length) {
|
|
1769
|
-
const key =
|
|
2031
|
+
const key = _chunkSAZRENEZcjs.indexToColName.call(void 0, this.document.columns.length);
|
|
1770
2032
|
this.document.columns.push({
|
|
1771
2033
|
id: this.generateId("col"),
|
|
1772
2034
|
key,
|
|
@@ -1813,7 +2075,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1813
2075
|
const commits = this.pendingCommits;
|
|
1814
2076
|
this.pendingCommits = [];
|
|
1815
2077
|
for (const [rowId, colId, raw] of commits) {
|
|
1816
|
-
_optionalChain([this, 'access',
|
|
2078
|
+
_optionalChain([this, 'access', _137 => _137.onCellCommit, 'optionalCall', _138 => _138(rowId, colId, raw, _optionalChain([this, 'access', _139 => _139.document, 'access', _140 => _140.cells, 'access', _141 => _141[rowId], 'optionalAccess', _142 => _142[colId], 'optionalAccess', _143 => _143.value]))]);
|
|
1817
2079
|
}
|
|
1818
2080
|
}
|
|
1819
2081
|
// --- CSV ---
|
|
@@ -1861,7 +2123,15 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1861
2123
|
*/
|
|
1862
2124
|
copyToClipboardData(range = this.selectedRange) {
|
|
1863
2125
|
const r = range ? normalizeRange(range) : { startRow: 0, startCol: 0, endRow: this.document.rows.length - 1, endCol: this.document.columns.length - 1 };
|
|
1864
|
-
const cells = this.readMatrix(r).map(
|
|
2126
|
+
const cells = this.readMatrix(r).map(
|
|
2127
|
+
(row) => row.map((cell) => {
|
|
2128
|
+
const value = cell.error || cell.value;
|
|
2129
|
+
if (cell.spillAnchor && !this.spillAnchorInRange(cell.spillAnchor, r)) {
|
|
2130
|
+
return { raw: value === null || value === void 0 ? "" : String(value), value };
|
|
2131
|
+
}
|
|
2132
|
+
return { raw: cell.raw, value };
|
|
2133
|
+
})
|
|
2134
|
+
);
|
|
1865
2135
|
return createSpreadsheetClipboardData(cells, { row: r.startRow, col: r.startCol });
|
|
1866
2136
|
}
|
|
1867
2137
|
/**
|
|
@@ -1884,12 +2154,16 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1884
2154
|
this.selectRange(r);
|
|
1885
2155
|
return true;
|
|
1886
2156
|
}
|
|
2157
|
+
spillAnchorInRange(anchor, range) {
|
|
2158
|
+
const record = this.spills.get(anchor);
|
|
2159
|
+
return !!record && rangeContains(range, record.row, record.col);
|
|
2160
|
+
}
|
|
1887
2161
|
getSelectionTopLeft() {
|
|
1888
2162
|
if (this.selectedRange) {
|
|
1889
2163
|
const r = normalizeRange(this.selectedRange);
|
|
1890
2164
|
return { row: r.startRow, col: r.startCol };
|
|
1891
2165
|
}
|
|
1892
|
-
return { row: _nullishCoalesce(_optionalChain([this, 'access',
|
|
2166
|
+
return { row: _nullishCoalesce(_optionalChain([this, 'access', _144 => _144.activeCell, 'optionalAccess', _145 => _145.row]), () => ( 0)), col: _nullishCoalesce(_optionalChain([this, 'access', _146 => _146.activeCell, 'optionalAccess', _147 => _147.col]), () => ( 0)) };
|
|
1893
2167
|
}
|
|
1894
2168
|
// --- Table operations: shared helpers ---
|
|
1895
2169
|
/** The table settings object, created on first use. */
|
|
@@ -1913,7 +2187,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1913
2187
|
const { headerRows, footerRows } = getTableSections(this.document);
|
|
1914
2188
|
return { start: headerRows, end: this.document.rows.length - footerRows - 1 };
|
|
1915
2189
|
}
|
|
1916
|
-
|
|
2190
|
+
__init24() {this.getCellValueAt = (rowIndex, colIndex) => {
|
|
1917
2191
|
const row = this.document.rows[rowIndex];
|
|
1918
2192
|
const col = this.document.columns[colIndex];
|
|
1919
2193
|
if (!row || !col) return "";
|
|
@@ -1923,7 +2197,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1923
2197
|
remapAllFormulas(moveCell) {
|
|
1924
2198
|
for (const rowCells of Object.values(this.document.cells)) {
|
|
1925
2199
|
for (const cell of Object.values(rowCells)) {
|
|
1926
|
-
if (_optionalChain([cell, 'access',
|
|
2200
|
+
if (_optionalChain([cell, 'access', _148 => _148.raw, 'optionalAccess', _149 => _149.startsWith, 'call', _150 => _150("=")])) {
|
|
1927
2201
|
cell.raw = remapFormulaReferences(cell.raw, moveCell);
|
|
1928
2202
|
}
|
|
1929
2203
|
}
|
|
@@ -1935,8 +2209,8 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1935
2209
|
* merges reduced to a single cell are dropped.
|
|
1936
2210
|
*/
|
|
1937
2211
|
adjustTableForStructuralChange(change) {
|
|
1938
|
-
const merges = _optionalChain([this, 'access',
|
|
1939
|
-
if (!_optionalChain([merges, 'optionalAccess',
|
|
2212
|
+
const merges = _optionalChain([this, 'access', _151 => _151.document, 'access', _152 => _152.table, 'optionalAccess', _153 => _153.merges]);
|
|
2213
|
+
if (!_optionalChain([merges, 'optionalAccess', _154 => _154.length])) return;
|
|
1940
2214
|
const startKey = change.axis === "row" ? "startRow" : "startCol";
|
|
1941
2215
|
const endKey = change.axis === "row" ? "endRow" : "endCol";
|
|
1942
2216
|
const next = [];
|
|
@@ -1967,8 +2241,8 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1967
2241
|
const colCount = this.document.columns.length;
|
|
1968
2242
|
const body = this.getBodyRowBounds();
|
|
1969
2243
|
const range = options.range ? normalizeRange(options.range) : null;
|
|
1970
|
-
const startRow = Math.max(_nullishCoalesce(_optionalChain([range, 'optionalAccess',
|
|
1971
|
-
const endRow = Math.min(_nullishCoalesce(_optionalChain([range, 'optionalAccess',
|
|
2244
|
+
const startRow = Math.max(_nullishCoalesce(_optionalChain([range, 'optionalAccess', _155 => _155.startRow]), () => ( body.start)), body.start);
|
|
2245
|
+
const endRow = Math.min(_nullishCoalesce(_optionalChain([range, 'optionalAccess', _156 => _156.endRow]), () => ( body.end)), body.end);
|
|
1972
2246
|
const startCol = range ? Math.max(0, range.startCol) : 0;
|
|
1973
2247
|
const endCol = range ? Math.min(colCount - 1, range.endCol) : colCount - 1;
|
|
1974
2248
|
if (endRow - startRow < 1 || startCol > endCol) return false;
|
|
@@ -1978,7 +2252,8 @@ var SpreadsheetController = (_class3 = class {
|
|
|
1978
2252
|
}));
|
|
1979
2253
|
if (keyCols.length === 0 || keyCols.some((k) => k.index < startCol || k.index > endCol)) return false;
|
|
1980
2254
|
const area = { startRow, startCol, endRow, endCol };
|
|
1981
|
-
if ((_nullishCoalesce(_optionalChain([this, 'access',
|
|
2255
|
+
if ((_nullishCoalesce(_optionalChain([this, 'access', _157 => _157.document, 'access', _158 => _158.table, 'optionalAccess', _159 => _159.merges]), () => ( []))).some((m) => rangesIntersect(m, area))) return false;
|
|
2256
|
+
if (this.intersectsSpill(area)) return false;
|
|
1982
2257
|
const sourceRows = [];
|
|
1983
2258
|
for (let r = startRow; r <= endRow; r++) sourceRows.push(r);
|
|
1984
2259
|
const sorted = sourceRows.map((r) => ({ r, values: keyCols.map((k) => this.getCellValueAt(r, k.index)) })).sort((a, b) => {
|
|
@@ -2005,7 +2280,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2005
2280
|
const colIds = this.document.columns.slice(startCol, endCol + 1).map((c) => c.id);
|
|
2006
2281
|
const snapshot = sorted.map((oldRow) => {
|
|
2007
2282
|
const rowId = this.document.rows[oldRow].id;
|
|
2008
|
-
return colIds.map((colId) => _optionalChain([this, 'access',
|
|
2283
|
+
return colIds.map((colId) => _optionalChain([this, 'access', _160 => _160.document, 'access', _161 => _161.cells, 'access', _162 => _162[rowId], 'optionalAccess', _163 => _163[colId]]));
|
|
2009
2284
|
});
|
|
2010
2285
|
snapshot.forEach((cells, i) => {
|
|
2011
2286
|
const rowId = this.document.rows[startRow + i].id;
|
|
@@ -2021,7 +2296,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2021
2296
|
}
|
|
2022
2297
|
// --- Filters ---
|
|
2023
2298
|
getFilterState() {
|
|
2024
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
2299
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _164 => _164.document, 'access', _165 => _165.table, 'optionalAccess', _166 => _166.filter]), () => ( { enabled: false, rules: [] }));
|
|
2025
2300
|
}
|
|
2026
2301
|
/** Replaces all filter rules (and turns filters on when there are any). */
|
|
2027
2302
|
setFilterRules(rules) {
|
|
@@ -2098,7 +2373,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2098
2373
|
}
|
|
2099
2374
|
setTableCount(key, count, max) {
|
|
2100
2375
|
const value = Math.max(0, Math.min(Math.floor(count), max));
|
|
2101
|
-
if ((_nullishCoalesce(_optionalChain([this, 'access',
|
|
2376
|
+
if ((_nullishCoalesce(_optionalChain([this, 'access', _167 => _167.document, 'access', _168 => _168.table, 'optionalAccess', _169 => _169[key]]), () => ( 0))) === value) return;
|
|
2102
2377
|
this.applyTableChange(() => {
|
|
2103
2378
|
this.table[key] = value;
|
|
2104
2379
|
});
|
|
@@ -2139,7 +2414,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2139
2414
|
}
|
|
2140
2415
|
// --- Merged cells ---
|
|
2141
2416
|
getMerges() {
|
|
2142
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
2417
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _170 => _170.document, 'access', _171 => _171.table, 'optionalAccess', _172 => _172.merges]), () => ( []));
|
|
2143
2418
|
}
|
|
2144
2419
|
/** The merge containing (row, col), or null. */
|
|
2145
2420
|
getMergeAt(row, col) {
|
|
@@ -2186,12 +2461,13 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2186
2461
|
}
|
|
2187
2462
|
const merges = this.getMerges();
|
|
2188
2463
|
if (merges.some((m) => rangesIntersect(m, r) && !rangeContainsRange(r, m))) return false;
|
|
2464
|
+
if (this.intersectsSpill(r)) return false;
|
|
2189
2465
|
this.applyTableChange(() => {
|
|
2190
2466
|
for (let row = r.startRow; row <= r.endRow; row++) {
|
|
2191
2467
|
const rowId = this.document.rows[row].id;
|
|
2192
2468
|
for (let col = r.startCol; col <= r.endCol; col++) {
|
|
2193
2469
|
if (row === r.startRow && col === r.startCol) continue;
|
|
2194
|
-
_optionalChainDelete([this, 'access',
|
|
2470
|
+
_optionalChainDelete([this, 'access', _173 => _173.document, 'access', _174 => _174.cells, 'access', _175 => _175[rowId], 'optionalAccess', _176 => _176[this.document.columns[col].id]]);
|
|
2195
2471
|
}
|
|
2196
2472
|
}
|
|
2197
2473
|
this.table.merges = [...merges.filter((m) => !rangeContainsRange(r, m)), r];
|
|
@@ -2207,7 +2483,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2207
2483
|
if (remaining.length === merges.length) return false;
|
|
2208
2484
|
this.applyTableChange(() => {
|
|
2209
2485
|
this.table.merges = remaining;
|
|
2210
|
-
});
|
|
2486
|
+
}, { recalculate: true });
|
|
2211
2487
|
return true;
|
|
2212
2488
|
}
|
|
2213
2489
|
// --- Autofill ---
|
|
@@ -2277,14 +2553,14 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2277
2553
|
});
|
|
2278
2554
|
}
|
|
2279
2555
|
ungroupRows() {
|
|
2280
|
-
if (!_optionalChain([this, 'access',
|
|
2556
|
+
if (!_optionalChain([this, 'access', _177 => _177.document, 'access', _178 => _178.table, 'optionalAccess', _179 => _179.grouping])) return;
|
|
2281
2557
|
this.applyTableChange(() => {
|
|
2282
2558
|
delete this.table.grouping;
|
|
2283
2559
|
});
|
|
2284
2560
|
}
|
|
2285
2561
|
/** Sets (or with `null`, removes) the group summary for a column. */
|
|
2286
2562
|
setGroupSummary(colId, aggregate) {
|
|
2287
|
-
const grouping = _optionalChain([this, 'access',
|
|
2563
|
+
const grouping = _optionalChain([this, 'access', _180 => _180.document, 'access', _181 => _181.table, 'optionalAccess', _182 => _182.grouping]);
|
|
2288
2564
|
if (!grouping) return;
|
|
2289
2565
|
this.applyTableChange(() => {
|
|
2290
2566
|
const others = grouping.summaries.filter((s) => s.colId !== colId);
|
|
@@ -2295,7 +2571,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2295
2571
|
});
|
|
2296
2572
|
}
|
|
2297
2573
|
setGroupCollapsed(key, collapsed) {
|
|
2298
|
-
const grouping = _optionalChain([this, 'access',
|
|
2574
|
+
const grouping = _optionalChain([this, 'access', _183 => _183.document, 'access', _184 => _184.table, 'optionalAccess', _185 => _185.grouping]);
|
|
2299
2575
|
if (!grouping || grouping.collapsed.includes(key) === collapsed) return;
|
|
2300
2576
|
this.applyTableChange(() => {
|
|
2301
2577
|
this.table.grouping = {
|
|
@@ -2305,7 +2581,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2305
2581
|
});
|
|
2306
2582
|
}
|
|
2307
2583
|
toggleGroupCollapsed(key) {
|
|
2308
|
-
const grouping = _optionalChain([this, 'access',
|
|
2584
|
+
const grouping = _optionalChain([this, 'access', _186 => _186.document, 'access', _187 => _187.table, 'optionalAccess', _188 => _188.grouping]);
|
|
2309
2585
|
if (!grouping) return;
|
|
2310
2586
|
this.setGroupCollapsed(key, !grouping.collapsed.includes(key));
|
|
2311
2587
|
}
|
|
@@ -2328,6 +2604,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2328
2604
|
const width = s.endCol - s.startCol + 1;
|
|
2329
2605
|
const t = { startRow: s.startRow, startCol: s.startCol, endRow: s.startRow + width - 1, endCol: s.startCol + height - 1 };
|
|
2330
2606
|
if (this.getMerges().some((m) => rangesIntersect(m, s) || rangesIntersect(m, t))) return false;
|
|
2607
|
+
if (this.intersectsSpill(s) || this.intersectsSpill(t)) return false;
|
|
2331
2608
|
this.applyTableChange(() => {
|
|
2332
2609
|
this.growGrid(t.endRow, t.endCol);
|
|
2333
2610
|
this.remapAllFormulas(({ row, col }) => {
|
|
@@ -2342,9 +2619,9 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2342
2619
|
moved.push({
|
|
2343
2620
|
row: s.startRow + (c - s.startCol),
|
|
2344
2621
|
col: s.startCol + (r - s.startRow),
|
|
2345
|
-
cell: _optionalChain([this, 'access',
|
|
2622
|
+
cell: _optionalChain([this, 'access', _189 => _189.document, 'access', _190 => _190.cells, 'access', _191 => _191[rowId(r)], 'optionalAccess', _192 => _192[colId(c)]])
|
|
2346
2623
|
});
|
|
2347
|
-
_optionalChainDelete([this, 'access',
|
|
2624
|
+
_optionalChainDelete([this, 'access', _193 => _193.document, 'access', _194 => _194.cells, 'access', _195 => _195[rowId(r)], 'optionalAccess', _196 => _196[colId(c)]]);
|
|
2348
2625
|
}
|
|
2349
2626
|
}
|
|
2350
2627
|
for (const { row, col, cell } of moved) {
|
|
@@ -2397,7 +2674,7 @@ var SpreadsheetController = (_class3 = class {
|
|
|
2397
2674
|
}
|
|
2398
2675
|
}
|
|
2399
2676
|
notifyChange() {
|
|
2400
|
-
_optionalChain([this, 'access',
|
|
2677
|
+
_optionalChain([this, 'access', _197 => _197.onDocumentChange, 'optionalCall', _198 => _198(this.document)]);
|
|
2401
2678
|
}
|
|
2402
2679
|
}, _class3);
|
|
2403
2680
|
function stepInOrder(order, from, delta) {
|
|
@@ -2412,6 +2689,17 @@ function stepInOrder(order, from, delta) {
|
|
|
2412
2689
|
}
|
|
2413
2690
|
|
|
2414
2691
|
// src/spreadsheet/menu.ts
|
|
2692
|
+
function clampMenuPosition(point, size, viewport, margin = 4) {
|
|
2693
|
+
const place = (start, length, limit) => {
|
|
2694
|
+
if (start + length <= limit - margin) return Math.max(margin, start);
|
|
2695
|
+
const flipped = start - length;
|
|
2696
|
+
return Math.max(margin, flipped >= margin ? flipped : limit - margin - length);
|
|
2697
|
+
};
|
|
2698
|
+
return {
|
|
2699
|
+
x: place(point.x, size.width, viewport.width),
|
|
2700
|
+
y: place(point.y, size.height, viewport.height)
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2415
2703
|
var quote = (value) => {
|
|
2416
2704
|
const text = String(_nullishCoalesce(value, () => ( "")));
|
|
2417
2705
|
return text.length > 24 ? `"${text.slice(0, 23)}\u2026"` : `"${text}"`;
|
|
@@ -2422,7 +2710,7 @@ function getSpreadsheetMenuItems(controller, cell) {
|
|
|
2422
2710
|
const row = doc.rows[cell.row];
|
|
2423
2711
|
if (!column || !row) return [];
|
|
2424
2712
|
const selection = controller.selectedRange && rangeContains(controller.selectedRange, cell.row, cell.col) ? normalizeRange(controller.selectedRange) : { startRow: cell.row, startCol: cell.col, endRow: cell.row, endCol: cell.col };
|
|
2425
|
-
const colName =
|
|
2713
|
+
const colName = _chunkSAZRENEZcjs.indexToColName.call(void 0, cell.col);
|
|
2426
2714
|
const value = controller.getCell(row.id, column.id).value;
|
|
2427
2715
|
const table = _nullishCoalesce(doc.table, () => ( {}));
|
|
2428
2716
|
const filter = controller.getFilterState();
|
|
@@ -2702,5 +2990,6 @@ async function importFileIntoSpreadsheet(controller, input, options) {
|
|
|
2702
2990
|
|
|
2703
2991
|
|
|
2704
2992
|
|
|
2705
|
-
|
|
2706
|
-
|
|
2993
|
+
|
|
2994
|
+
exports.columnDependencyKey = columnDependencyKey; exports.extractCellDependencies = extractCellDependencies; exports.DependencyGraph = DependencyGraph; exports.shiftFormulaReferences = shiftFormulaReferences; exports.mapFormulaReferences = mapFormulaReferences; exports.offsetFormulaReferences = offsetFormulaReferences; exports.remapFormulaReferences = remapFormulaReferences; exports.getFormulaCaretContext = getFormulaCaretContext; exports.getFormulaHints = getFormulaHints; exports.applyFormulaSuggestion = applyFormulaSuggestion; exports.DataSourceBinder = DataSourceBinder; exports.normalizeRange = normalizeRange; exports.rangeContains = rangeContains; exports.rangesIntersect = rangesIntersect; exports.rangeContainsRange = rangeContainsRange; exports.isSingleCellRange = isSingleCellRange; exports.isBlankValue = isBlankValue; exports.toNumber = toNumber; exports.compareCellValues = compareCellValues; exports.matchesFilterRule = matchesFilterRule; exports.aggregateValues = aggregateValues; exports.roundFloat = roundFloat; exports.fillSeries = fillSeries; exports.computeFillTarget = computeFillTarget; exports.getFillDirection = getFillDirection; exports.parseCsv = parseCsv; exports.escapeCsvField = escapeCsvField; exports.serializeCsv = serializeCsv; exports.parseTsv = parseTsv; exports.serializeTsv = serializeTsv; exports.SPREADSHEET_CLIPBOARD_MIME = SPREADSHEET_CLIPBOARD_MIME; exports.serializeHtmlTable = serializeHtmlTable; exports.parseHtmlTable = parseHtmlTable; exports.createSpreadsheetClipboardData = createSpreadsheetClipboardData; exports.readSpreadsheetClipboard = readSpreadsheetClipboard; exports.rebaseClipboardRows = rebaseClipboardRows; exports.DEFAULT_ROW_HEIGHT = DEFAULT_ROW_HEIGHT; exports.DEFAULT_COLUMN_WIDTH = DEFAULT_COLUMN_WIDTH; exports.getTableSections = getTableSections; exports.getRowSection = getRowSection; exports.rowPassesFilters = rowPassesFilters; exports.computeRowGroups = computeRowGroups; exports.buildSpreadsheetView = buildSpreadsheetView; exports.SpreadsheetController = SpreadsheetController; exports.clampMenuPosition = clampMenuPosition; exports.getSpreadsheetMenuItems = getSpreadsheetMenuItems; exports.SPREADSHEET_TABLE_ACTIONS = SPREADSHEET_TABLE_ACTIONS; exports.bindSpreadsheetTableActions = bindSpreadsheetTableActions; exports.csvImportAdapter = csvImportAdapter; exports.tsvImportAdapter = tsvImportAdapter; exports.SPREADSHEET_IMPORT_ADAPTERS = SPREADSHEET_IMPORT_ADAPTERS; exports.registerSpreadsheetImportAdapters = registerSpreadsheetImportAdapters; exports.importFileIntoSpreadsheet = importFileIntoSpreadsheet;
|
|
2995
|
+
//# sourceMappingURL=chunk-6M3BCTBD.cjs.map
|