ooxml-core 1.2.0 → 1.3.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/dist/{PptxHandler-SJTINPU4.mjs → PptxHandler-ZPJNHEZZ.mjs} +2 -2
- package/dist/automation/index.cjs +3294 -661
- package/dist/automation/index.mjs +3294 -661
- package/dist/chart/bar-cluster-geometry.d.ts +6 -0
- package/dist/chart/bar-cluster-geometry.d.ts.map +1 -1
- package/dist/chart/index.cjs +5 -2
- package/dist/chart/index.mjs +5 -3
- package/dist/chart/render/chart-spacing.d.ts.map +1 -1
- package/dist/{chunk-TEOAOAIF.mjs → chunk-BB55ASTX.mjs} +3 -3
- package/dist/{chunk-CQQAPUAG.mjs → chunk-H4TPDZV4.mjs} +11 -9
- package/dist/{chunk-VYTA2OUN.mjs → chunk-IVDC75E5.mjs} +1 -1
- package/dist/{chunk-FI4RSJ24.mjs → chunk-QPQDLSJQ.mjs} +1 -1
- package/dist/{chunk-XCZ7U3GZ.mjs → chunk-XGLKW3JJ.mjs} +13 -9
- package/dist/docx/index.cjs +4 -2
- package/dist/docx/index.mjs +4 -2
- package/dist/docx/layout/index.cjs +4 -2
- package/dist/docx/layout/index.mjs +4 -2
- package/dist/docx/ui/index.cjs +4 -2
- package/dist/docx/ui/index.mjs +4 -2
- package/dist/index.cjs +5 -2
- package/dist/index.mjs +5 -2
- package/dist/pptx/automation/index.cjs +29 -17
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/chunks/index-EZJZ7USt.d.ts.map +1 -1
- package/dist/pptx/cli/index.cjs +29 -17
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/index.cjs +29 -17
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +176 -92
- package/dist/teams/index.mjs +176 -92
- package/dist/visio/clipboard-resources.d.ts +11 -0
- package/dist/visio/clipboard-resources.d.ts.map +1 -0
- package/dist/visio/clipboard-types.d.ts +26 -0
- package/dist/visio/clipboard-types.d.ts.map +1 -0
- package/dist/visio/clipboard-xml.d.ts +8 -0
- package/dist/visio/clipboard-xml.d.ts.map +1 -0
- package/dist/visio/clipboard.d.ts +7 -0
- package/dist/visio/clipboard.d.ts.map +1 -0
- package/dist/visio/create-document.d.ts +8 -0
- package/dist/visio/create-document.d.ts.map +1 -0
- package/dist/visio/edit-commands.d.ts +19 -2
- package/dist/visio/edit-commands.d.ts.map +1 -1
- package/dist/visio/edit-delete.d.ts +9 -0
- package/dist/visio/edit-delete.d.ts.map +1 -0
- package/dist/visio/edit-duplicate-commands.d.ts +14 -0
- package/dist/visio/edit-duplicate-commands.d.ts.map +1 -0
- package/dist/visio/edit-duplicate-scope.d.ts +4 -0
- package/dist/visio/edit-duplicate-scope.d.ts.map +1 -0
- package/dist/visio/edit-duplicate.d.ts +10 -0
- package/dist/visio/edit-duplicate.d.ts.map +1 -0
- package/dist/visio/edit-formatting-cell-admission.d.ts +3 -0
- package/dist/visio/edit-formatting-cell-admission.d.ts.map +1 -0
- package/dist/visio/edit-formatting-commands.d.ts +46 -0
- package/dist/visio/edit-formatting-commands.d.ts.map +1 -0
- package/dist/visio/edit-formatting-font.d.ts +6 -0
- package/dist/visio/edit-formatting-font.d.ts.map +1 -0
- package/dist/visio/edit-formatting-paint-scope.d.ts +6 -0
- package/dist/visio/edit-formatting-paint-scope.d.ts.map +1 -0
- package/dist/visio/edit-formatting-paint.d.ts +6 -0
- package/dist/visio/edit-formatting-paint.d.ts.map +1 -0
- package/dist/visio/edit-formatting-rows.d.ts +14 -0
- package/dist/visio/edit-formatting-rows.d.ts.map +1 -0
- package/dist/visio/edit-formatting-scope.d.ts +6 -0
- package/dist/visio/edit-formatting-scope.d.ts.map +1 -0
- package/dist/visio/edit-formatting-text.d.ts +8 -0
- package/dist/visio/edit-formatting-text.d.ts.map +1 -0
- package/dist/visio/edit-formatting.d.ts +12 -0
- package/dist/visio/edit-formatting.d.ts.map +1 -0
- package/dist/visio/edit-geometry.d.ts.map +1 -1
- package/dist/visio/edit-paste-commands.d.ts +15 -0
- package/dist/visio/edit-paste-commands.d.ts.map +1 -0
- package/dist/visio/edit-paste.d.ts +5 -0
- package/dist/visio/edit-paste.d.ts.map +1 -0
- package/dist/visio/edit-recalculate.d.ts +3 -1
- package/dist/visio/edit-recalculate.d.ts.map +1 -1
- package/dist/visio/edit-resize-anchor.d.ts +8 -0
- package/dist/visio/edit-resize-anchor.d.ts.map +1 -0
- package/dist/visio/edit-scope.d.ts.map +1 -1
- package/dist/visio/edit-shape-create.d.ts +1 -1
- package/dist/visio/edit-shape-create.d.ts.map +1 -1
- package/dist/visio/edit-shape-order.d.ts +7 -0
- package/dist/visio/edit-shape-order.d.ts.map +1 -0
- package/dist/visio/edit-style-admission.d.ts +17 -0
- package/dist/visio/edit-style-admission.d.ts.map +1 -0
- package/dist/visio/edit-text-scope.d.ts +7 -0
- package/dist/visio/edit-text-scope.d.ts.map +1 -0
- package/dist/visio/edit-text.d.ts +1 -1
- package/dist/visio/edit-text.d.ts.map +1 -1
- package/dist/visio/edit.d.ts +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/index.cjs +3245 -1077
- package/dist/visio/index.d.ts +3 -1
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +3241 -1079
- package/dist/visio/line-pattern.d.ts +1 -1
- package/dist/visio/line-pattern.d.ts.map +1 -1
- package/dist/visio/line-style.d.ts.map +1 -1
- package/dist/visio/model.d.ts +23 -3
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/plain-text.d.ts +5 -0
- package/dist/visio/plain-text.d.ts.map +1 -0
- package/dist/visio/resize-anchor.d.ts +27 -0
- package/dist/visio/resize-anchor.d.ts.map +1 -0
- package/dist/visio/source-paint.d.ts +5 -0
- package/dist/visio/source-paint.d.ts.map +1 -0
- package/dist/visio/style.d.ts.map +1 -1
- package/dist/visio/theme-root.d.ts.map +1 -1
- package/dist/visio/ui/contract.d.ts +10 -6
- package/dist/visio/ui/contract.d.ts.map +1 -1
- package/dist/visio/ui/draw-plan.d.ts +32 -0
- package/dist/visio/ui/draw-plan.d.ts.map +1 -0
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/formatting.d.ts +28 -0
- package/dist/visio/ui/formatting.d.ts.map +1 -0
- package/dist/visio/ui/index.cjs +1305 -15
- package/dist/visio/ui/index.d.ts +15 -0
- package/dist/visio/ui/index.d.ts.map +1 -1
- package/dist/visio/ui/index.mjs +1261 -16
- package/dist/visio/ui/line-dash.d.ts +4 -0
- package/dist/visio/ui/line-dash.d.ts.map +1 -0
- package/dist/visio/ui/marquee.d.ts +15 -0
- package/dist/visio/ui/marquee.d.ts.map +1 -0
- package/dist/visio/ui/page-edit.d.ts.map +1 -1
- package/dist/visio/ui/scene-validation.d.ts.map +1 -1
- package/dist/visio/ui/selection.d.ts +12 -0
- package/dist/visio/ui/selection.d.ts.map +1 -0
- package/dist/visio/ui/shape-arrange.d.ts +17 -0
- package/dist/visio/ui/shape-arrange.d.ts.map +1 -0
- package/dist/visio/ui/shape-clipboard.d.ts +10 -0
- package/dist/visio/ui/shape-clipboard.d.ts.map +1 -0
- package/dist/visio/ui/shape-duplicate.d.ts +5 -0
- package/dist/visio/ui/shape-duplicate.d.ts.map +1 -0
- package/dist/visio/ui/shape-formatting.d.ts +14 -0
- package/dist/visio/ui/shape-formatting.d.ts.map +1 -0
- package/dist/visio/ui/shape-move.d.ts +14 -0
- package/dist/visio/ui/shape-move.d.ts.map +1 -0
- package/dist/visio/ui/shape-order.d.ts +4 -0
- package/dist/visio/ui/shape-order.d.ts.map +1 -0
- package/dist/visio/ui/shape-resize.d.ts +61 -0
- package/dist/visio/ui/shape-resize.d.ts.map +1 -0
- package/dist/visio/ui/size-position.d.ts +19 -0
- package/dist/visio/ui/size-position.d.ts.map +1 -0
- package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
- package/dist/visio/ui/svg-stroke.d.ts +8 -0
- package/dist/visio/ui/svg-stroke.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-selection.d.ts +9 -0
- package/dist/visio/ui/text-replace-selection.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-snapshot.d.ts +14 -0
- package/dist/visio/ui/text-replace-snapshot.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-types.d.ts +48 -0
- package/dist/visio/ui/text-replace-types.d.ts.map +1 -0
- package/dist/visio/ui/text-replace.d.ts +18 -0
- package/dist/visio/ui/text-replace.d.ts.map +1 -0
- package/dist/xlsx/edit/context.d.ts +3 -1
- package/dist/xlsx/edit/context.d.ts.map +1 -1
- package/dist/xlsx/edit/history.d.ts +18 -0
- package/dist/xlsx/edit/history.d.ts.map +1 -1
- package/dist/xlsx/edit/session-calc.d.ts +30 -8
- package/dist/xlsx/edit/session-calc.d.ts.map +1 -1
- package/dist/xlsx/edit/session.d.ts.map +1 -1
- package/dist/xlsx/edit/sheets.d.ts.map +1 -1
- package/dist/xlsx/edit/types.d.ts +23 -3
- package/dist/xlsx/edit/types.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-core.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-host.d.ts +6 -2
- package/dist/xlsx/formula/engine-host.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-prepare.d.ts +33 -0
- package/dist/xlsx/formula/engine-prepare.d.ts.map +1 -0
- package/dist/xlsx/formula/engine-structure.d.ts +40 -0
- package/dist/xlsx/formula/engine-structure.d.ts.map +1 -0
- package/dist/xlsx/formula/engine-types.d.ts +26 -0
- package/dist/xlsx/formula/engine-types.d.ts.map +1 -1
- package/dist/xlsx/formula/engine.d.ts.map +1 -1
- package/dist/xlsx/formula/formula-shape.d.ts +28 -0
- package/dist/xlsx/formula/formula-shape.d.ts.map +1 -0
- package/dist/xlsx/formula/graph-index.d.ts +3 -1
- package/dist/xlsx/formula/graph-index.d.ts.map +1 -1
- package/dist/xlsx/formula/graph.d.ts +5 -0
- package/dist/xlsx/formula/graph.d.ts.map +1 -1
- package/dist/xlsx/formula/lexemes.d.ts.map +1 -1
- package/dist/xlsx/formula/parse-cache.d.ts +9 -0
- package/dist/xlsx/formula/parse-cache.d.ts.map +1 -0
- package/dist/xlsx/formula/parser.d.ts +3 -0
- package/dist/xlsx/formula/parser.d.ts.map +1 -1
- package/dist/xlsx/formula/ref-text.d.ts +14 -0
- package/dist/xlsx/formula/ref-text.d.ts.map +1 -0
- package/dist/xlsx/formula/references.d.ts.map +1 -1
- package/dist/xlsx/formula/shift-formula.d.ts +19 -0
- package/dist/xlsx/formula/shift-formula.d.ts.map +1 -0
- package/dist/xlsx/formula/shift-graph.d.ts +42 -0
- package/dist/xlsx/formula/shift-graph.d.ts.map +1 -0
- package/dist/xlsx/formula/transform.d.ts +2 -23
- package/dist/xlsx/formula/transform.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +1087 -338
- package/dist/xlsx/index.mjs +1087 -339
- package/dist/xlsx/layout/index.d.ts +1 -1
- package/dist/xlsx/layout/index.d.ts.map +1 -1
- package/dist/xlsx/layout/sheet-queries.d.ts +7 -0
- package/dist/xlsx/layout/sheet-queries.d.ts.map +1 -1
- package/dist/xlsx/load/index.cjs +170 -99
- package/dist/xlsx/load/index.mjs +170 -99
- package/dist/xlsx/ui/index.cjs +1072 -332
- package/dist/xlsx/ui/index.mjs +1072 -332
- package/package.json +1 -1
package/dist/xlsx/ui/index.mjs
CHANGED
|
@@ -2040,7 +2040,7 @@ var NAME_RE = /^[A-Za-z_\\\u00A1-\uFFFF][A-Za-z0-9_.?\\\u00A1-\uFFFF]*/;
|
|
|
2040
2040
|
var CELL_RE = /^(\$?)([A-Za-z]{1,3})(\$?)(\d{1,7})/;
|
|
2041
2041
|
var COLS_RE = /^(\$?)([A-Za-z]{1,3}):(\$?)([A-Za-z]{1,3})/;
|
|
2042
2042
|
var ROWS_RE = /^(\$?)(\d{1,7}):(\$?)(\d{1,7})/;
|
|
2043
|
-
var NUMBER_RE2 = /^(?:\d
|
|
2043
|
+
var NUMBER_RE2 = /^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/;
|
|
2044
2044
|
var sticky = (re) => new RegExp(re.source.replace(/^\^/, ""), "y");
|
|
2045
2045
|
var CELL_AT = sticky(CELL_RE);
|
|
2046
2046
|
var COLS_AT = sticky(COLS_RE);
|
|
@@ -2200,14 +2200,13 @@ function splitSheets(text2) {
|
|
|
2200
2200
|
if (book !== void 0) out.book = book;
|
|
2201
2201
|
return out;
|
|
2202
2202
|
}
|
|
2203
|
-
var PREFIX_AT = /(\[\d+\])?([A-Za-z0-9_.\u00A1-\uFFFF]+)(?::([A-Za-z0-9_.\u00A1-\uFFFF]+))?!/y;
|
|
2204
2203
|
function readPrefix(source, at) {
|
|
2205
2204
|
const ch = source[at];
|
|
2206
2205
|
if (ch === "'") {
|
|
2207
2206
|
const quoted = readQuoted(source, at);
|
|
2208
2207
|
if (source[at + quoted.length] !== "!") return void 0;
|
|
2209
|
-
const
|
|
2210
|
-
return { prefix: { text: source.slice(at, at +
|
|
2208
|
+
const length2 = quoted.length + 1;
|
|
2209
|
+
return { prefix: { text: source.slice(at, at + length2), ...splitSheets(quoted.name) }, length: length2 };
|
|
2211
2210
|
}
|
|
2212
2211
|
let i2 = at;
|
|
2213
2212
|
if (ch === "[") {
|
|
@@ -2216,13 +2215,23 @@ function readPrefix(source, at) {
|
|
|
2216
2215
|
if (i2 === at + 1 || source[i2] !== "]") return void 0;
|
|
2217
2216
|
i2++;
|
|
2218
2217
|
}
|
|
2218
|
+
const sheetFrom = i2;
|
|
2219
2219
|
while (i2 < source.length && isSheetCharCode(source.charCodeAt(i2))) i2++;
|
|
2220
|
-
if (
|
|
2221
|
-
|
|
2222
|
-
if (
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2220
|
+
if (i2 === sheetFrom) return void 0;
|
|
2221
|
+
let lastFrom = -1;
|
|
2222
|
+
if (source[i2] === ":") {
|
|
2223
|
+
lastFrom = i2 + 1;
|
|
2224
|
+
i2 = lastFrom;
|
|
2225
|
+
while (i2 < source.length && isSheetCharCode(source.charCodeAt(i2))) i2++;
|
|
2226
|
+
if (i2 === lastFrom) return void 0;
|
|
2227
|
+
}
|
|
2228
|
+
if (source[i2] !== "!") return void 0;
|
|
2229
|
+
if (ch !== "[" && lastFrom < 0 && isDigitCode(source.charCodeAt(sheetFrom))) return void 0;
|
|
2230
|
+
const length = i2 + 1 - at;
|
|
2231
|
+
return {
|
|
2232
|
+
prefix: { text: source.slice(at, at + length), ...splitSheets(source.slice(at, i2)) },
|
|
2233
|
+
length
|
|
2234
|
+
};
|
|
2226
2235
|
}
|
|
2227
2236
|
function numberLiteral(text2) {
|
|
2228
2237
|
if (text2.length <= 15) return Number(text2);
|
|
@@ -2412,7 +2421,9 @@ var PREC_INTERSECT = 9;
|
|
|
2412
2421
|
var PREC_RANGE = 10;
|
|
2413
2422
|
var OPERAND_START = /* @__PURE__ */ new Set(["ref", "name", "func", "open", "structured"]);
|
|
2414
2423
|
function parseFormula(formula) {
|
|
2415
|
-
|
|
2424
|
+
return parseTokens(tokenize(formula));
|
|
2425
|
+
}
|
|
2426
|
+
function parseTokens(all2) {
|
|
2416
2427
|
const tokens = [];
|
|
2417
2428
|
const wsBefore = [];
|
|
2418
2429
|
let sawWs = false;
|
|
@@ -2697,6 +2708,222 @@ function localDateToSerial(date, date1904 = date1904Mode) {
|
|
|
2697
2708
|
return base + (utc - dayStart) / DAY_MS;
|
|
2698
2709
|
}
|
|
2699
2710
|
|
|
2711
|
+
// xlsx/formula/area-index.ts
|
|
2712
|
+
var BUCKET_WIDTH = 64;
|
|
2713
|
+
var CHUNK_SHIFT = 6;
|
|
2714
|
+
var CHUNKS = 64;
|
|
2715
|
+
function push(map, key, value2) {
|
|
2716
|
+
const list = map.get(key);
|
|
2717
|
+
if (list) list.push(value2);
|
|
2718
|
+
else map.set(key, [value2]);
|
|
2719
|
+
}
|
|
2720
|
+
function inner(map, sheet) {
|
|
2721
|
+
let found = map.get(sheet);
|
|
2722
|
+
if (!found) map.set(sheet, found = /* @__PURE__ */ new Map());
|
|
2723
|
+
return found;
|
|
2724
|
+
}
|
|
2725
|
+
var AreaIndex = class {
|
|
2726
|
+
cells = /* @__PURE__ */ new Map();
|
|
2727
|
+
chunked = /* @__PURE__ */ new Map();
|
|
2728
|
+
tall = /* @__PURE__ */ new Map();
|
|
2729
|
+
wide = /* @__PURE__ */ new Map();
|
|
2730
|
+
add(area, node) {
|
|
2731
|
+
const { start, end } = area.range;
|
|
2732
|
+
if (start.row === end.row && end.col - start.col + 1 <= BUCKET_WIDTH) {
|
|
2733
|
+
const cells = inner(this.cells, area.sheet);
|
|
2734
|
+
for (let col = start.col; col <= end.col; col++) push(cells, cellKey(start.row, col), node);
|
|
2735
|
+
return;
|
|
2736
|
+
}
|
|
2737
|
+
const entry = { range: area.range, node };
|
|
2738
|
+
if (end.col - start.col + 1 > BUCKET_WIDTH) {
|
|
2739
|
+
const list = this.wide.get(area.sheet);
|
|
2740
|
+
if (list) list.push(entry);
|
|
2741
|
+
else this.wide.set(area.sheet, [entry]);
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
const first2 = start.row >> CHUNK_SHIFT;
|
|
2745
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
2746
|
+
if (last - first2 + 1 > CHUNKS) {
|
|
2747
|
+
const cols2 = inner(this.tall, area.sheet);
|
|
2748
|
+
for (let c = start.col; c <= end.col; c++) push(cols2, c, entry);
|
|
2749
|
+
return;
|
|
2750
|
+
}
|
|
2751
|
+
const cols = inner(this.chunked, area.sheet);
|
|
2752
|
+
for (let c = start.col; c <= end.col; c++) {
|
|
2753
|
+
let chunks = cols.get(c);
|
|
2754
|
+
if (!chunks) cols.set(c, chunks = /* @__PURE__ */ new Map());
|
|
2755
|
+
for (let k = first2; k <= last; k++) push(chunks, k, entry);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
/** Items whose areas intersect `range` on `sheet` (each once). */
|
|
2759
|
+
dependents(sheet, range2, out) {
|
|
2760
|
+
const found = out instanceof Set ? out : /* @__PURE__ */ new Set();
|
|
2761
|
+
this.collect(sheet, range2, found);
|
|
2762
|
+
if (Array.isArray(out)) for (const node of found) out.push(node);
|
|
2763
|
+
}
|
|
2764
|
+
collect(sheet, range2, out) {
|
|
2765
|
+
const { start, end } = range2;
|
|
2766
|
+
const check3 = (list) => {
|
|
2767
|
+
if (list) {
|
|
2768
|
+
for (const entry of list) if (rangesIntersect(entry.range, range2)) out.add(entry.node);
|
|
2769
|
+
}
|
|
2770
|
+
};
|
|
2771
|
+
const cells = this.cells.get(sheet);
|
|
2772
|
+
if (cells) {
|
|
2773
|
+
const size = (end.row - start.row + 1) * (end.col - start.col + 1);
|
|
2774
|
+
if (size <= 4096) {
|
|
2775
|
+
for (let r = start.row; r <= end.row; r++) {
|
|
2776
|
+
for (let c = start.col; c <= end.col; c++) {
|
|
2777
|
+
const list = cells.get(cellKey(r, c));
|
|
2778
|
+
if (list) for (const node of list) out.add(node);
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
} else {
|
|
2782
|
+
for (const [key, list] of cells) {
|
|
2783
|
+
const { row: row2, col } = keyToAddress(key);
|
|
2784
|
+
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
2785
|
+
for (const node of list) out.add(node);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
const columns = (map, visit2) => {
|
|
2790
|
+
if (!map) return;
|
|
2791
|
+
if (end.col - start.col + 1 <= map.size) {
|
|
2792
|
+
for (let c = start.col; c <= end.col; c++) if (map.has(c)) visit2(c);
|
|
2793
|
+
} else for (const c of map.keys()) if (c >= start.col && c <= end.col) visit2(c);
|
|
2794
|
+
};
|
|
2795
|
+
const chunked = this.chunked.get(sheet);
|
|
2796
|
+
const first2 = start.row >> CHUNK_SHIFT;
|
|
2797
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
2798
|
+
columns(chunked, (c) => {
|
|
2799
|
+
const chunks = chunked?.get(c);
|
|
2800
|
+
if (last - first2 + 1 <= chunks.size) {
|
|
2801
|
+
for (let k = first2; k <= last; k++) check3(chunks.get(k));
|
|
2802
|
+
} else for (const [k, list] of chunks) if (k >= first2 && k <= last) check3(list);
|
|
2803
|
+
});
|
|
2804
|
+
const tall = this.tall.get(sheet);
|
|
2805
|
+
columns(tall, (c) => check3(tall?.get(c)));
|
|
2806
|
+
check3(this.wide.get(sheet));
|
|
2807
|
+
}
|
|
2808
|
+
};
|
|
2809
|
+
|
|
2810
|
+
// xlsx/formula/graph-index.ts
|
|
2811
|
+
var ColumnIndex = class {
|
|
2812
|
+
sheets = /* @__PURE__ */ new Map();
|
|
2813
|
+
constructor(nodes) {
|
|
2814
|
+
for (const node of nodes) {
|
|
2815
|
+
let cols = this.sheets.get(node.sheet);
|
|
2816
|
+
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
2817
|
+
let list = cols.get(node.col);
|
|
2818
|
+
if (!list) cols.set(node.col, list = []);
|
|
2819
|
+
list.push(node);
|
|
2820
|
+
}
|
|
2821
|
+
for (const cols of this.sheets.values())
|
|
2822
|
+
for (const list of cols.values()) list.sort((a, b) => a.row - b.row);
|
|
2823
|
+
}
|
|
2824
|
+
nodesIn(area, out) {
|
|
2825
|
+
const cols = this.sheets.get(area.sheet);
|
|
2826
|
+
if (!cols) return;
|
|
2827
|
+
const { start, end } = area.range;
|
|
2828
|
+
const width = end.col - start.col + 1;
|
|
2829
|
+
const scan2 = (list) => {
|
|
2830
|
+
let lo = 0;
|
|
2831
|
+
let hi = list.length;
|
|
2832
|
+
while (lo < hi) {
|
|
2833
|
+
const mid = lo + hi >> 1;
|
|
2834
|
+
if (list[mid].row < start.row) lo = mid + 1;
|
|
2835
|
+
else hi = mid;
|
|
2836
|
+
}
|
|
2837
|
+
for (let i2 = lo; i2 < list.length; i2++) {
|
|
2838
|
+
const node = list[i2];
|
|
2839
|
+
if (node.row > end.row) break;
|
|
2840
|
+
out.push(node);
|
|
2841
|
+
}
|
|
2842
|
+
};
|
|
2843
|
+
if (width <= cols.size) {
|
|
2844
|
+
for (let c = start.col; c <= end.col; c++) {
|
|
2845
|
+
const list = cols.get(c);
|
|
2846
|
+
if (list) scan2(list);
|
|
2847
|
+
}
|
|
2848
|
+
} else {
|
|
2849
|
+
for (const [c, list] of cols) if (c >= start.col && c <= end.col) scan2(list);
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
};
|
|
2853
|
+
var ReverseIndex = class extends AreaIndex {
|
|
2854
|
+
constructor(nodes = []) {
|
|
2855
|
+
super();
|
|
2856
|
+
for (const node of nodes) this.addNode(node);
|
|
2857
|
+
}
|
|
2858
|
+
/** Indexes one more formula's precedents. */
|
|
2859
|
+
addNode(node) {
|
|
2860
|
+
for (const dep of node.deps) this.add(dep, node);
|
|
2861
|
+
for (const dep of node.dynamicDeps) this.add(dep, node);
|
|
2862
|
+
}
|
|
2863
|
+
};
|
|
2864
|
+
|
|
2865
|
+
// xlsx/formula/engine-prepare.ts
|
|
2866
|
+
var CHECK_EVERY = 32;
|
|
2867
|
+
var GraphPreparation = class {
|
|
2868
|
+
constructor(workbook, create) {
|
|
2869
|
+
this.workbook = workbook;
|
|
2870
|
+
this.create = create;
|
|
2871
|
+
}
|
|
2872
|
+
workbook;
|
|
2873
|
+
create;
|
|
2874
|
+
reverse = new ReverseIndex();
|
|
2875
|
+
formulas = { dynamic: [], unvalued: [] };
|
|
2876
|
+
sheet = 0;
|
|
2877
|
+
rows;
|
|
2878
|
+
row = 0;
|
|
2879
|
+
cells;
|
|
2880
|
+
finished = false;
|
|
2881
|
+
/**
|
|
2882
|
+
* Adds formulas to the graph until `timeRemaining` (milliseconds, as an idle deadline reports
|
|
2883
|
+
* them) reaches zero, or until every formula is in. Returns true when the graph is complete.
|
|
2884
|
+
*/
|
|
2885
|
+
run(timeRemaining) {
|
|
2886
|
+
let visited = 0;
|
|
2887
|
+
while (!this.finished) {
|
|
2888
|
+
const cells = this.cells ?? this.nextRow();
|
|
2889
|
+
if (!cells) continue;
|
|
2890
|
+
const next = cells.next();
|
|
2891
|
+
if (next.done) {
|
|
2892
|
+
this.cells = void 0;
|
|
2893
|
+
continue;
|
|
2894
|
+
}
|
|
2895
|
+
const [col, cell] = next.value;
|
|
2896
|
+
if (cell.formula) this.add(this.create(this.sheet, this.row, col, cell), cell);
|
|
2897
|
+
if (timeRemaining && ++visited % CHECK_EVERY === 0 && timeRemaining() <= 0) break;
|
|
2898
|
+
}
|
|
2899
|
+
return this.finished;
|
|
2900
|
+
}
|
|
2901
|
+
add(node, cell) {
|
|
2902
|
+
this.reverse.addNode(node);
|
|
2903
|
+
if (!node.legacy && !node.arrayRange) this.formulas.dynamic.push(node);
|
|
2904
|
+
if (cell.value === null && !node.keepCached) this.formulas.unvalued.push(node);
|
|
2905
|
+
}
|
|
2906
|
+
/** Moves to the next stored row (and sheet), or marks the walk finished. */
|
|
2907
|
+
nextRow() {
|
|
2908
|
+
for (; ; ) {
|
|
2909
|
+
const sheet = this.workbook.sheets[this.sheet];
|
|
2910
|
+
if (!sheet) {
|
|
2911
|
+
this.finished = true;
|
|
2912
|
+
return void 0;
|
|
2913
|
+
}
|
|
2914
|
+
this.rows ??= sheet.rows.entries();
|
|
2915
|
+
const next = this.rows.next();
|
|
2916
|
+
if (!next.done) {
|
|
2917
|
+
this.row = next.value[0];
|
|
2918
|
+
this.cells = next.value[1].entries();
|
|
2919
|
+
return this.cells;
|
|
2920
|
+
}
|
|
2921
|
+
this.rows = void 0;
|
|
2922
|
+
this.sheet++;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
};
|
|
2926
|
+
|
|
2700
2927
|
// xlsx/formula/text-number.ts
|
|
2701
2928
|
var MONTHS2 = [
|
|
2702
2929
|
"jan",
|
|
@@ -5831,8 +6058,10 @@ var FINANCIAL_FUNCTIONS = [
|
|
|
5831
6058
|
|
|
5832
6059
|
// xlsx/formula/references.ts
|
|
5833
6060
|
function sheetIndex(host, name) {
|
|
6061
|
+
const sheets = host.workbook.sheets;
|
|
6062
|
+
for (let i2 = 0; i2 < sheets.length; i2++) if (sheets[i2]?.name === name) return i2;
|
|
5834
6063
|
const lower2 = name.toLowerCase();
|
|
5835
|
-
return
|
|
6064
|
+
return sheets.findIndex((sheet) => sheet.name.toLowerCase() === lower2);
|
|
5836
6065
|
}
|
|
5837
6066
|
function prefixSheets(host, prefix, current) {
|
|
5838
6067
|
if (!prefix) return [current];
|
|
@@ -7402,9 +7631,9 @@ function readBlock(ctx, area, rows2, cols) {
|
|
|
7402
7631
|
if (host.readBlock) return host.readBlock(area.sheet, range2);
|
|
7403
7632
|
return Matrix.build(rows2, cols, (r, c) => ctx.readCell(area.sheet, row2 + r, col + c));
|
|
7404
7633
|
}
|
|
7405
|
-
function shapedMatrices(ctx, values2,
|
|
7634
|
+
function shapedMatrices(ctx, values2, sameShape2) {
|
|
7406
7635
|
let { rows: rows2, cols } = shapeOf(values2[0] ?? null);
|
|
7407
|
-
if (
|
|
7636
|
+
if (sameShape2) {
|
|
7408
7637
|
for (const value2 of values2) {
|
|
7409
7638
|
const shape2 = shapeOf(value2);
|
|
7410
7639
|
if (shape2.rows !== rows2 || shape2.cols !== cols) fail(ERR.VALUE);
|
|
@@ -7430,12 +7659,12 @@ function shapedMatrices(ctx, values2, sameShape) {
|
|
|
7430
7659
|
});
|
|
7431
7660
|
return { matrices, total: total2, block: rows2 * cols };
|
|
7432
7661
|
}
|
|
7433
|
-
function matchingCells(ctx, pairs, target2,
|
|
7662
|
+
function matchingCells(ctx, pairs, target2, sameShape2) {
|
|
7434
7663
|
const ranges = pairs.map((p) => p.range);
|
|
7435
7664
|
const { matrices, total: total2, block } = shapedMatrices(
|
|
7436
7665
|
ctx,
|
|
7437
7666
|
target2 === void 0 ? ranges : [...ranges, target2],
|
|
7438
|
-
|
|
7667
|
+
sameShape2
|
|
7439
7668
|
);
|
|
7440
7669
|
const tests = pairs.map((p) => makeCriteria(scalar(p.criteria)));
|
|
7441
7670
|
const values2 = matrices[matrices.length - 1];
|
|
@@ -7474,7 +7703,7 @@ function indexedCandidates(pairs, matrices) {
|
|
|
7474
7703
|
}
|
|
7475
7704
|
return void 0;
|
|
7476
7705
|
}
|
|
7477
|
-
var matchingValues = (ctx, pairs, target2,
|
|
7706
|
+
var matchingValues = (ctx, pairs, target2, sameShape2) => matchingCells(ctx, pairs, target2, sameShape2).values;
|
|
7478
7707
|
function criteriaPairs(args, from) {
|
|
7479
7708
|
if ((args.length - from) % 2 !== 0) fail(ERR.VALUE);
|
|
7480
7709
|
const pairs = [];
|
|
@@ -11368,7 +11597,7 @@ var REFERENCE_ARGUMENT = /* @__PURE__ */ new Set([
|
|
|
11368
11597
|
"AREAS",
|
|
11369
11598
|
"ISREF"
|
|
11370
11599
|
]);
|
|
11371
|
-
var
|
|
11600
|
+
var push2 = (c, area) => {
|
|
11372
11601
|
(c.dynamic > 0 ? c.dynamicDeps : c.deps).push(area);
|
|
11373
11602
|
};
|
|
11374
11603
|
function spans(areas) {
|
|
@@ -11394,7 +11623,7 @@ function visit(node, c) {
|
|
|
11394
11623
|
if (!sheets) return;
|
|
11395
11624
|
const range2 = specRange(node.ref);
|
|
11396
11625
|
const target2 = node.spill ? { start: range2.start, end: { ...range2.start } } : range2;
|
|
11397
|
-
for (const sheet of sheets)
|
|
11626
|
+
for (const sheet of sheets) push2(c, { sheet, range: target2 });
|
|
11398
11627
|
return;
|
|
11399
11628
|
}
|
|
11400
11629
|
case "name": {
|
|
@@ -11468,7 +11697,7 @@ function visitBinary(node, c) {
|
|
|
11468
11697
|
const list = c.dynamic > 0 ? c.dynamicDeps : c.deps;
|
|
11469
11698
|
const l = list[list.length - 2];
|
|
11470
11699
|
const r = list[list.length - 1];
|
|
11471
|
-
if (l && r && l.sheet === r.sheet)
|
|
11700
|
+
if (l && r && l.sheet === r.sheet) push2(c, spans([l, r])[0]);
|
|
11472
11701
|
continue;
|
|
11473
11702
|
}
|
|
11474
11703
|
const mentioned = [...c.deps.slice(staticStart), ...c.dynamicDeps.slice(dynamicStart)];
|
|
@@ -11484,7 +11713,7 @@ function addStructured(ref, c) {
|
|
|
11484
11713
|
sheet: c.sheet,
|
|
11485
11714
|
row: c.row,
|
|
11486
11715
|
col: c.col});
|
|
11487
|
-
if (value2 instanceof RefValue) for (const area of value2.areas)
|
|
11716
|
+
if (value2 instanceof RefValue) for (const area of value2.areas) push2(c, area);
|
|
11488
11717
|
}
|
|
11489
11718
|
function analyze(ast, host, sheet, row2, col) {
|
|
11490
11719
|
const c = {
|
|
@@ -11508,155 +11737,191 @@ function analyze(ast, host, sheet, row2, col) {
|
|
|
11508
11737
|
};
|
|
11509
11738
|
}
|
|
11510
11739
|
|
|
11511
|
-
// xlsx/formula/
|
|
11512
|
-
var
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11740
|
+
// xlsx/formula/formula-shape.ts
|
|
11741
|
+
var isDigit4 = (code) => code >= 48 && code <= 57;
|
|
11742
|
+
function formulaShape(formula) {
|
|
11743
|
+
const starts = [];
|
|
11744
|
+
const ends = [];
|
|
11745
|
+
let hash = 2166136261;
|
|
11746
|
+
for (let i2 = 0; i2 < formula.length; i2++) {
|
|
11747
|
+
let code = formula.charCodeAt(i2);
|
|
11748
|
+
if (isDigit4(code)) {
|
|
11749
|
+
let j = i2 + 1;
|
|
11750
|
+
while (j < formula.length && isDigit4(formula.charCodeAt(j))) j++;
|
|
11751
|
+
starts.push(i2);
|
|
11752
|
+
ends.push(j);
|
|
11753
|
+
i2 = j - 1;
|
|
11754
|
+
code = 0;
|
|
11755
|
+
}
|
|
11756
|
+
hash = Math.imul(hash ^ code, 16777619);
|
|
11757
|
+
}
|
|
11758
|
+
return { hash: hash >>> 0, starts, ends };
|
|
11519
11759
|
}
|
|
11520
|
-
function
|
|
11521
|
-
let
|
|
11522
|
-
|
|
11523
|
-
return
|
|
11760
|
+
function sameText(a, from, b, at, length) {
|
|
11761
|
+
for (let k = 0; k < length; k++)
|
|
11762
|
+
if (a.charCodeAt(from + k) !== b.charCodeAt(at + k)) return false;
|
|
11763
|
+
return true;
|
|
11524
11764
|
}
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
const
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11765
|
+
function sameShape(a, as, b, bs) {
|
|
11766
|
+
const runs = as.starts.length;
|
|
11767
|
+
if (runs !== bs.starts.length) return false;
|
|
11768
|
+
let fromA = 0;
|
|
11769
|
+
let fromB = 0;
|
|
11770
|
+
for (let i2 = 0; i2 <= runs; i2++) {
|
|
11771
|
+
const toA = i2 < runs ? as.starts[i2] : a.length;
|
|
11772
|
+
const toB = i2 < runs ? bs.starts[i2] : b.length;
|
|
11773
|
+
if (toA - fromA !== toB - fromB || !sameText(a, fromA, b, fromB, toA - fromA)) return false;
|
|
11774
|
+
fromA = as.ends[i2] ?? 0;
|
|
11775
|
+
fromB = bs.ends[i2] ?? 0;
|
|
11776
|
+
}
|
|
11777
|
+
return true;
|
|
11778
|
+
}
|
|
11779
|
+
function makeTemplate(formula, shape2) {
|
|
11780
|
+
let tokens;
|
|
11781
|
+
let ast;
|
|
11782
|
+
try {
|
|
11783
|
+
tokens = tokenize(formula);
|
|
11784
|
+
ast = parseTokens(tokens);
|
|
11785
|
+
} catch (e) {
|
|
11786
|
+
if (e instanceof RangeError) return new FormulaError(e.message, -1, "#VALUE!");
|
|
11787
|
+
if (e instanceof FormulaError) return e;
|
|
11788
|
+
throw e;
|
|
11789
|
+
}
|
|
11790
|
+
const { starts } = shape2;
|
|
11791
|
+
const slotted = starts.map(() => false);
|
|
11792
|
+
const refs = /* @__PURE__ */ new Map();
|
|
11793
|
+
let run = 0;
|
|
11794
|
+
for (const token of tokens) {
|
|
11795
|
+
const end = token.start + token.text.length;
|
|
11796
|
+
const first2 = run;
|
|
11797
|
+
while (run < starts.length && starts[run] < end) run++;
|
|
11798
|
+
const ref = token.kind === "ref" ? token.ref : void 0;
|
|
11799
|
+
if (!ref || ref.kind === "cols") continue;
|
|
11800
|
+
const count2 = ref.kind === "cell" ? 1 : 2;
|
|
11801
|
+
if (run - first2 < count2) continue;
|
|
11802
|
+
const at = run - count2;
|
|
11803
|
+
const indexes2 = count2 === 1 ? [at] : [at, at + 1];
|
|
11804
|
+
if (indexes2.some((i2) => formula.charCodeAt(starts[i2]) === 48)) continue;
|
|
11805
|
+
for (const i2 of indexes2) slotted[i2] = true;
|
|
11806
|
+
refs.set(ref, count2 === 1 ? { start: at } : { start: at, end: at + 1 });
|
|
11807
|
+
}
|
|
11808
|
+
return { formula, shape: shape2, ast, slotted, refs };
|
|
11809
|
+
}
|
|
11810
|
+
function rowsFor(t, formula, shape2) {
|
|
11811
|
+
if (!sameShape(t.formula, t.shape, formula, shape2)) return void 0;
|
|
11812
|
+
const rows2 = [];
|
|
11813
|
+
for (let i2 = 0; i2 < shape2.starts.length; i2++) {
|
|
11814
|
+
const start = shape2.starts[i2];
|
|
11815
|
+
const length = shape2.ends[i2] - start;
|
|
11816
|
+
if (!t.slotted[i2]) {
|
|
11817
|
+
const own = t.shape.starts[i2];
|
|
11818
|
+
if (t.shape.ends[i2] - own !== length) return void 0;
|
|
11819
|
+
if (!sameText(t.formula, own, formula, start, length)) return void 0;
|
|
11820
|
+
rows2.push(-1);
|
|
11821
|
+
continue;
|
|
11536
11822
|
}
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11823
|
+
if (length > 7 || formula.charCodeAt(start) === 48) return void 0;
|
|
11824
|
+
let row2 = 0;
|
|
11825
|
+
for (let k = start; k < start + length; k++) row2 = row2 * 10 + formula.charCodeAt(k) - 48;
|
|
11826
|
+
if (row2 < 1 || row2 > MAX_ROW + 1) return void 0;
|
|
11827
|
+
rows2.push(row2 - 1);
|
|
11828
|
+
}
|
|
11829
|
+
return rows2;
|
|
11830
|
+
}
|
|
11831
|
+
function shiftSpec(spec2, slots, rows2) {
|
|
11832
|
+
const startRow = rows2[slots.start];
|
|
11833
|
+
const endRow = slots.end === void 0 ? startRow : rows2[slots.end];
|
|
11834
|
+
if (startRow === spec2.start.row && endRow === spec2.end.row) return spec2;
|
|
11835
|
+
const { start: from, end: to } = spec2;
|
|
11836
|
+
const start = { row: startRow, col: from.col, rowAbs: from.rowAbs, colAbs: from.colAbs };
|
|
11837
|
+
if (slots.end === void 0) return { kind: spec2.kind, start, end: start };
|
|
11838
|
+
const end = { row: endRow, col: to.col, rowAbs: to.rowAbs, colAbs: to.colAbs };
|
|
11839
|
+
return { kind: spec2.kind, start, end };
|
|
11840
|
+
}
|
|
11841
|
+
function copyTree(node, t, rows2) {
|
|
11842
|
+
switch (node.type) {
|
|
11843
|
+
case "ref": {
|
|
11844
|
+
const slots = node.ref ? t.refs.get(node.ref) : void 0;
|
|
11845
|
+
if (!slots || !node.ref) return node;
|
|
11846
|
+
const ref = shiftSpec(node.ref, slots, rows2);
|
|
11847
|
+
if (ref === node.ref) return node;
|
|
11848
|
+
const copy2 = { type: "ref" };
|
|
11849
|
+
if (node.prefix) copy2.prefix = node.prefix;
|
|
11850
|
+
copy2.ref = ref;
|
|
11851
|
+
if (node.spill) copy2.spill = true;
|
|
11852
|
+
return copy2;
|
|
11543
11853
|
}
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
return;
|
|
11854
|
+
case "unary":
|
|
11855
|
+
case "percent": {
|
|
11856
|
+
const operand4 = copyTree(node.operand, t, rows2);
|
|
11857
|
+
if (operand4 === node.operand) return node;
|
|
11858
|
+
return node.type === "unary" ? { type: "unary", op: node.op, operand: operand4 } : { type: "percent", operand: operand4 };
|
|
11550
11859
|
}
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
if (
|
|
11555
|
-
|
|
11860
|
+
case "binary": {
|
|
11861
|
+
const left2 = copyTree(node.left, t, rows2);
|
|
11862
|
+
const right2 = copyTree(node.right, t, rows2);
|
|
11863
|
+
if (left2 === node.left && right2 === node.right) return node;
|
|
11864
|
+
return { type: "binary", op: node.op, left: left2, right: right2 };
|
|
11865
|
+
}
|
|
11866
|
+
case "call": {
|
|
11867
|
+
const args = copyAll(node.args, t, rows2);
|
|
11868
|
+
if (args === node.args) return node;
|
|
11869
|
+
return { type: "call", name: node.name, rawName: node.rawName, args };
|
|
11870
|
+
}
|
|
11871
|
+
case "invoke": {
|
|
11872
|
+
const callee = copyTree(node.callee, t, rows2);
|
|
11873
|
+
const args = copyAll(node.args, t, rows2);
|
|
11874
|
+
if (callee === node.callee && args === node.args) return node;
|
|
11875
|
+
return { type: "invoke", callee, args };
|
|
11556
11876
|
}
|
|
11877
|
+
default:
|
|
11878
|
+
return node;
|
|
11557
11879
|
}
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11880
|
+
}
|
|
11881
|
+
function copyAll(nodes, t, rows2) {
|
|
11882
|
+
let out;
|
|
11883
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
11884
|
+
const node = nodes[i2];
|
|
11885
|
+
const copy2 = copyTree(node, t, rows2);
|
|
11886
|
+
if (copy2 !== node && !out) out = nodes.slice(0, i2);
|
|
11887
|
+
out?.push(copy2);
|
|
11888
|
+
}
|
|
11889
|
+
return out ?? nodes;
|
|
11890
|
+
}
|
|
11891
|
+
function fromTemplate(t, formula, shape2) {
|
|
11892
|
+
const rows2 = rowsFor(t, formula, shape2);
|
|
11893
|
+
return rows2 ? copyTree(t.ast, t, rows2) : void 0;
|
|
11894
|
+
}
|
|
11895
|
+
|
|
11896
|
+
// xlsx/formula/parse-cache.ts
|
|
11897
|
+
var MAX_TEMPLATE_LENGTH = 2048;
|
|
11898
|
+
var MAX_ENTRIES = 1e5;
|
|
11899
|
+
var MAX_TEMPLATES = 1e4;
|
|
11900
|
+
var NO_RUNS = { hash: 0, starts: [], ends: [] };
|
|
11901
|
+
var treeOf = (made) => "ast" in made ? made.ast : made;
|
|
11902
|
+
var ParseCache = class {
|
|
11903
|
+
byText = /* @__PURE__ */ new Map();
|
|
11904
|
+
templates = /* @__PURE__ */ new Map();
|
|
11905
|
+
parse(formula) {
|
|
11906
|
+
let ast = this.byText.get(formula);
|
|
11907
|
+
if (ast) return ast;
|
|
11908
|
+
ast = this.parseNew(formula);
|
|
11909
|
+
if (this.byText.size > MAX_ENTRIES) this.byText.clear();
|
|
11910
|
+
this.byText.set(formula, ast);
|
|
11911
|
+
return ast;
|
|
11563
11912
|
}
|
|
11564
|
-
|
|
11565
|
-
|
|
11566
|
-
const
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11570
|
-
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
if (size <= 4096) {
|
|
11575
|
-
for (let r = start.row; r <= end.row; r++) {
|
|
11576
|
-
for (let c = start.col; c <= end.col; c++) {
|
|
11577
|
-
const list = cells.get(cellKey(r, c));
|
|
11578
|
-
if (list) for (const node of list) out.add(node);
|
|
11579
|
-
}
|
|
11580
|
-
}
|
|
11581
|
-
} else {
|
|
11582
|
-
for (const [key, list] of cells) {
|
|
11583
|
-
const { row: row2, col } = keyToAddress(key);
|
|
11584
|
-
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
11585
|
-
for (const node of list) out.add(node);
|
|
11586
|
-
}
|
|
11587
|
-
}
|
|
11588
|
-
}
|
|
11589
|
-
const columns = (map, visit2) => {
|
|
11590
|
-
if (!map) return;
|
|
11591
|
-
if (end.col - start.col + 1 <= map.size) {
|
|
11592
|
-
for (let c = start.col; c <= end.col; c++) if (map.has(c)) visit2(c);
|
|
11593
|
-
} else for (const c of map.keys()) if (c >= start.col && c <= end.col) visit2(c);
|
|
11594
|
-
};
|
|
11595
|
-
const chunked = this.chunked.get(sheet);
|
|
11596
|
-
const first2 = start.row >> CHUNK_SHIFT;
|
|
11597
|
-
const last = end.row >> CHUNK_SHIFT;
|
|
11598
|
-
columns(chunked, (c) => {
|
|
11599
|
-
const chunks = chunked?.get(c);
|
|
11600
|
-
if (last - first2 + 1 <= chunks.size) {
|
|
11601
|
-
for (let k = first2; k <= last; k++) check3(chunks.get(k));
|
|
11602
|
-
} else for (const [k, list] of chunks) if (k >= first2 && k <= last) check3(list);
|
|
11603
|
-
});
|
|
11604
|
-
const tall = this.tall.get(sheet);
|
|
11605
|
-
columns(tall, (c) => check3(tall?.get(c)));
|
|
11606
|
-
check3(this.wide.get(sheet));
|
|
11607
|
-
}
|
|
11608
|
-
};
|
|
11609
|
-
|
|
11610
|
-
// xlsx/formula/graph-index.ts
|
|
11611
|
-
var ColumnIndex = class {
|
|
11612
|
-
sheets = /* @__PURE__ */ new Map();
|
|
11613
|
-
constructor(nodes) {
|
|
11614
|
-
for (const node of nodes) {
|
|
11615
|
-
let cols = this.sheets.get(node.sheet);
|
|
11616
|
-
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
11617
|
-
let list = cols.get(node.col);
|
|
11618
|
-
if (!list) cols.set(node.col, list = []);
|
|
11619
|
-
list.push(node);
|
|
11620
|
-
}
|
|
11621
|
-
for (const cols of this.sheets.values())
|
|
11622
|
-
for (const list of cols.values()) list.sort((a, b) => a.row - b.row);
|
|
11623
|
-
}
|
|
11624
|
-
nodesIn(area, out) {
|
|
11625
|
-
const cols = this.sheets.get(area.sheet);
|
|
11626
|
-
if (!cols) return;
|
|
11627
|
-
const { start, end } = area.range;
|
|
11628
|
-
const width = end.col - start.col + 1;
|
|
11629
|
-
const scan2 = (list) => {
|
|
11630
|
-
let lo = 0;
|
|
11631
|
-
let hi = list.length;
|
|
11632
|
-
while (lo < hi) {
|
|
11633
|
-
const mid = lo + hi >> 1;
|
|
11634
|
-
if (list[mid].row < start.row) lo = mid + 1;
|
|
11635
|
-
else hi = mid;
|
|
11636
|
-
}
|
|
11637
|
-
for (let i2 = lo; i2 < list.length; i2++) {
|
|
11638
|
-
const node = list[i2];
|
|
11639
|
-
if (node.row > end.row) break;
|
|
11640
|
-
out.push(node);
|
|
11641
|
-
}
|
|
11642
|
-
};
|
|
11643
|
-
if (width <= cols.size) {
|
|
11644
|
-
for (let c = start.col; c <= end.col; c++) {
|
|
11645
|
-
const list = cols.get(c);
|
|
11646
|
-
if (list) scan2(list);
|
|
11647
|
-
}
|
|
11648
|
-
} else {
|
|
11649
|
-
for (const [c, list] of cols) if (c >= start.col && c <= end.col) scan2(list);
|
|
11650
|
-
}
|
|
11651
|
-
}
|
|
11652
|
-
};
|
|
11653
|
-
var ReverseIndex = class extends AreaIndex {
|
|
11654
|
-
constructor(nodes) {
|
|
11655
|
-
super();
|
|
11656
|
-
for (const node of nodes) {
|
|
11657
|
-
for (const dep of node.deps) this.add(dep, node);
|
|
11658
|
-
for (const dep of node.dynamicDeps) this.add(dep, node);
|
|
11913
|
+
parseNew(formula) {
|
|
11914
|
+
if (formula.length > MAX_TEMPLATE_LENGTH) return treeOf(makeTemplate(formula, NO_RUNS));
|
|
11915
|
+
const shape2 = formulaShape(formula);
|
|
11916
|
+
const template = this.templates.get(shape2.hash);
|
|
11917
|
+
const reused = template && fromTemplate(template, formula, shape2);
|
|
11918
|
+
if (reused) return reused;
|
|
11919
|
+
const made = makeTemplate(formula, shape2);
|
|
11920
|
+
if (!template && "ast" in made) {
|
|
11921
|
+
if (this.templates.size > MAX_TEMPLATES) this.templates.clear();
|
|
11922
|
+
this.templates.set(shape2.hash, made);
|
|
11659
11923
|
}
|
|
11924
|
+
return treeOf(made);
|
|
11660
11925
|
}
|
|
11661
11926
|
};
|
|
11662
11927
|
|
|
@@ -11796,7 +12061,7 @@ var EngineHost = class {
|
|
|
11796
12061
|
options;
|
|
11797
12062
|
nodes = /* @__PURE__ */ new Map();
|
|
11798
12063
|
footprints = /* @__PURE__ */ new Set();
|
|
11799
|
-
|
|
12064
|
+
parsed = new ParseCache();
|
|
11800
12065
|
boundsCache = /* @__PURE__ */ new Map();
|
|
11801
12066
|
inProgress = /* @__PURE__ */ new Set();
|
|
11802
12067
|
cycles = /* @__PURE__ */ new Set();
|
|
@@ -11820,6 +12085,8 @@ var EngineHost = class {
|
|
|
11820
12085
|
evaluations = 0;
|
|
11821
12086
|
built = false;
|
|
11822
12087
|
needsFull = false;
|
|
12088
|
+
/** No recalculation has run since the workbook was opened: stored values may stand. */
|
|
12089
|
+
fresh = true;
|
|
11823
12090
|
// ---- EvalHost ----
|
|
11824
12091
|
readCell(sheet, row2, col) {
|
|
11825
12092
|
const cell = this.workbook.sheets[sheet]?.rows.get(row2)?.get(col);
|
|
@@ -11908,19 +12175,7 @@ var EngineHost = class {
|
|
|
11908
12175
|
return this.workbook.sheets[sheet]?.rows.get(row2)?.get(col)?.formula;
|
|
11909
12176
|
}
|
|
11910
12177
|
parse(formula) {
|
|
11911
|
-
|
|
11912
|
-
if (!ast) {
|
|
11913
|
-
try {
|
|
11914
|
-
ast = parseFormula(formula);
|
|
11915
|
-
} catch (e) {
|
|
11916
|
-
if (e instanceof RangeError) ast = new FormulaError(e.message, -1, "#VALUE!");
|
|
11917
|
-
else if (!(e instanceof FormulaError)) throw e;
|
|
11918
|
-
else ast = e;
|
|
11919
|
-
}
|
|
11920
|
-
if (this.astCache.size > 1e5) this.astCache.clear();
|
|
11921
|
-
this.astCache.set(formula, ast);
|
|
11922
|
-
}
|
|
11923
|
-
return ast;
|
|
12178
|
+
return this.parsed.parse(formula);
|
|
11924
12179
|
}
|
|
11925
12180
|
now() {
|
|
11926
12181
|
return this.options.now ? this.options.now() : /* @__PURE__ */ new Date();
|
|
@@ -11929,20 +12184,6 @@ var EngineHost = class {
|
|
|
11929
12184
|
return this.options.random ? this.options.random() : Math.random();
|
|
11930
12185
|
}
|
|
11931
12186
|
// ---- graph ----
|
|
11932
|
-
build() {
|
|
11933
|
-
this.nodes.clear();
|
|
11934
|
-
this.footprints.clear();
|
|
11935
|
-
this.footprintIndex = void 0;
|
|
11936
|
-
this.workbook.sheets.forEach((sheet, s) => {
|
|
11937
|
-
for (const [row2, cells] of sheet.rows) {
|
|
11938
|
-
for (const [col, cell] of cells) {
|
|
11939
|
-
if (cell.formula) this.createNode(s, row2, col, cell, true);
|
|
11940
|
-
}
|
|
11941
|
-
}
|
|
11942
|
-
});
|
|
11943
|
-
this.built = true;
|
|
11944
|
-
this.graphChanged();
|
|
11945
|
-
}
|
|
11946
12187
|
createNode(sheet, row2, col, cell, initial) {
|
|
11947
12188
|
const formula = cell.formula ?? "";
|
|
11948
12189
|
const parsed = this.parse(formula);
|
|
@@ -11971,6 +12212,14 @@ var EngineHost = class {
|
|
|
11971
12212
|
map.set(cellKey(row2, col), node);
|
|
11972
12213
|
return node;
|
|
11973
12214
|
}
|
|
12215
|
+
/** Parses a node's text again after a structural edit rewrote it (see `FormulaNode.stale`). */
|
|
12216
|
+
refreshAst(node) {
|
|
12217
|
+
const parsed = this.parse(node.formula);
|
|
12218
|
+
delete node.stale;
|
|
12219
|
+
delete node.parseError;
|
|
12220
|
+
node.ast = parsed instanceof FormulaError ? void 0 : parsed;
|
|
12221
|
+
if (parsed instanceof FormulaError && parsed.code) node.parseError = err(parsed.code);
|
|
12222
|
+
}
|
|
11974
12223
|
removeNode(node, changed) {
|
|
11975
12224
|
const sheet = this.workbook.sheets[node.sheet];
|
|
11976
12225
|
if (node.spill && sheet) {
|
|
@@ -12401,6 +12650,7 @@ var EngineCore = class extends EngineHost {
|
|
|
12401
12650
|
return { host: this, sheet, row: row2, col, scope: void 0, depth: 0, root, legacy };
|
|
12402
12651
|
}
|
|
12403
12652
|
evaluateFormula(node) {
|
|
12653
|
+
if (node.stale) this.refreshAst(node);
|
|
12404
12654
|
if (!node.ast) return node.parseError ?? ERR.NAME;
|
|
12405
12655
|
const ast = node.ast;
|
|
12406
12656
|
const frame = this.frameFor(node.sheet, node.row, node.col, ast, node.legacy);
|
|
@@ -12418,20 +12668,363 @@ var EngineCore = class extends EngineHost {
|
|
|
12418
12668
|
}
|
|
12419
12669
|
};
|
|
12420
12670
|
|
|
12671
|
+
// xlsx/formula/shift-graph.ts
|
|
12672
|
+
var POSITIONAL = /* @__PURE__ */ new Set(["ROW", "COLUMN"]);
|
|
12673
|
+
var DESCRIPTIVE = /* @__PURE__ */ new Set(["FORMULATEXT", "CELL", "SHEET"]);
|
|
12674
|
+
var traitsCache = /* @__PURE__ */ new WeakMap();
|
|
12675
|
+
function astTraits(ast) {
|
|
12676
|
+
const cached = traitsCache.get(ast);
|
|
12677
|
+
if (cached) return cached;
|
|
12678
|
+
const sheets = /* @__PURE__ */ new Set();
|
|
12679
|
+
const traits = { complex: false, opaque: false, positional: false, descriptive: false, sheets };
|
|
12680
|
+
const stack2 = [ast];
|
|
12681
|
+
while (stack2.length) {
|
|
12682
|
+
const node = stack2.pop();
|
|
12683
|
+
switch (node.type) {
|
|
12684
|
+
case "ref":
|
|
12685
|
+
if (node.prefix) {
|
|
12686
|
+
sheets.add(node.prefix.sheet.toLowerCase());
|
|
12687
|
+
if (node.prefix.sheet2 !== void 0) {
|
|
12688
|
+
sheets.add(node.prefix.sheet2.toLowerCase());
|
|
12689
|
+
traits.complex = true;
|
|
12690
|
+
}
|
|
12691
|
+
}
|
|
12692
|
+
break;
|
|
12693
|
+
case "name":
|
|
12694
|
+
if (node.prefix) sheets.add(node.prefix.sheet.toLowerCase());
|
|
12695
|
+
traits.complex = true;
|
|
12696
|
+
break;
|
|
12697
|
+
case "structured":
|
|
12698
|
+
traits.complex = true;
|
|
12699
|
+
break;
|
|
12700
|
+
case "unary":
|
|
12701
|
+
case "percent":
|
|
12702
|
+
stack2.push(node.operand);
|
|
12703
|
+
break;
|
|
12704
|
+
case "binary":
|
|
12705
|
+
stack2.push(node.left, node.right);
|
|
12706
|
+
break;
|
|
12707
|
+
case "call":
|
|
12708
|
+
if (POSITIONAL.has(node.name)) traits.positional = true;
|
|
12709
|
+
if (DESCRIPTIVE.has(node.name)) traits.descriptive = true;
|
|
12710
|
+
if (!getFunction(node.name)) traits.complex = traits.opaque = true;
|
|
12711
|
+
stack2.push(...node.args);
|
|
12712
|
+
break;
|
|
12713
|
+
case "invoke":
|
|
12714
|
+
stack2.push(node.callee, ...node.args);
|
|
12715
|
+
break;
|
|
12716
|
+
}
|
|
12717
|
+
}
|
|
12718
|
+
traitsCache.set(ast, traits);
|
|
12719
|
+
return traits;
|
|
12720
|
+
}
|
|
12721
|
+
function intervalDelta(a, b, shift2) {
|
|
12722
|
+
const { at, count: count2 } = shift2;
|
|
12723
|
+
if (count2 > 0) {
|
|
12724
|
+
if (b < at) return 0;
|
|
12725
|
+
if (a < at) return void 0;
|
|
12726
|
+
return b + count2 > (shift2.axis === "row" ? MAX_ROW : MAX_COL) ? void 0 : count2;
|
|
12727
|
+
}
|
|
12728
|
+
const last = at - count2 - 1;
|
|
12729
|
+
if (b < at) return 0;
|
|
12730
|
+
if (a > last) return count2;
|
|
12731
|
+
return void 0;
|
|
12732
|
+
}
|
|
12733
|
+
function areaDelta(area, sheet, shift2) {
|
|
12734
|
+
if (area.sheet !== sheet) return 0;
|
|
12735
|
+
const { start, end } = area.range;
|
|
12736
|
+
return shift2.axis === "row" ? intervalDelta(start.row, end.row, shift2) : intervalDelta(start.col, end.col, shift2);
|
|
12737
|
+
}
|
|
12738
|
+
function movedRange(range2, axis, delta) {
|
|
12739
|
+
if (delta === 0) return range2;
|
|
12740
|
+
return axis === "row" ? {
|
|
12741
|
+
start: { row: range2.start.row + delta, col: range2.start.col },
|
|
12742
|
+
end: { row: range2.end.row + delta, col: range2.end.col }
|
|
12743
|
+
} : {
|
|
12744
|
+
start: { row: range2.start.row, col: range2.start.col + delta },
|
|
12745
|
+
end: { row: range2.end.row, col: range2.end.col + delta }
|
|
12746
|
+
};
|
|
12747
|
+
}
|
|
12748
|
+
function reachesEdit(areas, sheet, shift2) {
|
|
12749
|
+
for (const area of areas) {
|
|
12750
|
+
if (area.sheet !== sheet) continue;
|
|
12751
|
+
if ((shift2.axis === "row" ? area.range.end.row : area.range.end.col) >= shift2.at) return true;
|
|
12752
|
+
}
|
|
12753
|
+
return false;
|
|
12754
|
+
}
|
|
12755
|
+
function intersectionMoves(area, delta, pos, nodeDelta, axis) {
|
|
12756
|
+
if (delta === nodeDelta) return false;
|
|
12757
|
+
const { start, end } = area.range;
|
|
12758
|
+
const a = axis === "row" ? start.row : start.col;
|
|
12759
|
+
const b = axis === "row" ? end.row : end.col;
|
|
12760
|
+
if (a === b) return false;
|
|
12761
|
+
return pos >= a && pos <= b || pos + nodeDelta >= a + delta && pos + nodeDelta <= b + delta;
|
|
12762
|
+
}
|
|
12763
|
+
|
|
12764
|
+
// xlsx/formula/engine-structure.ts
|
|
12765
|
+
var sameAreas = (a, b) => a.length === b.length && a.every((x, i2) => {
|
|
12766
|
+
const y = b[i2];
|
|
12767
|
+
return x.sheet === y.sheet && sameRange(x.range, y.range);
|
|
12768
|
+
});
|
|
12769
|
+
var EngineStructure = class extends EngineCore {
|
|
12770
|
+
/** Formulas a structural edit left to recalculate (with their dependents) on the next pass. */
|
|
12771
|
+
structuralSeeds = /* @__PURE__ */ new Set();
|
|
12772
|
+
/** Whether the graph describes the workbook as it was before the edit just reported. */
|
|
12773
|
+
graphReady() {
|
|
12774
|
+
return this.built && !this.needsFull;
|
|
12775
|
+
}
|
|
12776
|
+
/** Parses a node's current text again and recomputes its precedents. */
|
|
12777
|
+
reanalyze(node) {
|
|
12778
|
+
const parsed = this.parse(node.formula);
|
|
12779
|
+
delete node.stale;
|
|
12780
|
+
delete node.parseError;
|
|
12781
|
+
if (parsed instanceof FormulaError) {
|
|
12782
|
+
node.ast = void 0;
|
|
12783
|
+
if (parsed.code) node.parseError = err(parsed.code);
|
|
12784
|
+
node.deps = [];
|
|
12785
|
+
node.dynamicDeps = [];
|
|
12786
|
+
return;
|
|
12787
|
+
}
|
|
12788
|
+
node.ast = parsed;
|
|
12789
|
+
const found = analyze(parsed, this, node.sheet, node.row, node.col);
|
|
12790
|
+
node.deps = found.deps;
|
|
12791
|
+
node.dynamicDeps = found.dynamicDeps;
|
|
12792
|
+
node.volatile = found.volatile;
|
|
12793
|
+
node.unsupported = found.unsupported;
|
|
12794
|
+
}
|
|
12795
|
+
/**
|
|
12796
|
+
* Moves the graph for rows or columns inserted or deleted on `sheet`, after the workbook was
|
|
12797
|
+
* changed (cells moved, formulas rewritten). Spills on the sheet, array formulas the edit cuts
|
|
12798
|
+
* and anything unexpected fall back to a rebuild on the next recalculation.
|
|
12799
|
+
*/
|
|
12800
|
+
shiftCells(sheet, shift2) {
|
|
12801
|
+
if (!this.graphReady() || !this.shiftable(sheet, shift2)) {
|
|
12802
|
+
this.invalidate();
|
|
12803
|
+
return;
|
|
12804
|
+
}
|
|
12805
|
+
const ws = this.workbook.sheets[sheet];
|
|
12806
|
+
const own = this.nodes.get(sheet);
|
|
12807
|
+
if (!ws) return;
|
|
12808
|
+
const moved = /* @__PURE__ */ new Map();
|
|
12809
|
+
if (own) {
|
|
12810
|
+
const next = /* @__PURE__ */ new Map();
|
|
12811
|
+
for (const node of own.values()) {
|
|
12812
|
+
const pos = shift2.axis === "row" ? node.row : node.col;
|
|
12813
|
+
const delta = intervalDelta(pos, pos, shift2);
|
|
12814
|
+
if (delta === void 0) {
|
|
12815
|
+
this.dropNode(node);
|
|
12816
|
+
continue;
|
|
12817
|
+
}
|
|
12818
|
+
if (delta !== 0) {
|
|
12819
|
+
moved.set(node, delta);
|
|
12820
|
+
if (shift2.axis === "row") node.row += delta;
|
|
12821
|
+
else node.col += delta;
|
|
12822
|
+
}
|
|
12823
|
+
next.set(cellKey(node.row, node.col), node);
|
|
12824
|
+
}
|
|
12825
|
+
this.nodes.set(sheet, next);
|
|
12826
|
+
}
|
|
12827
|
+
for (const map of this.nodes.values())
|
|
12828
|
+
for (const node of map.values()) {
|
|
12829
|
+
if (!this.shiftNode(node, sheet, shift2, moved.get(node) ?? 0)) {
|
|
12830
|
+
this.invalidate();
|
|
12831
|
+
return;
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
this.boundsCache.clear();
|
|
12835
|
+
this.graphChanged();
|
|
12836
|
+
}
|
|
12837
|
+
/** No spill or stale spilled value on the sheet, and no array formula the edit cuts. */
|
|
12838
|
+
shiftable(sheet, shift2) {
|
|
12839
|
+
for (const node of this.footprints) {
|
|
12840
|
+
if (node.sheet !== sheet) continue;
|
|
12841
|
+
if (node.spill || node.blockedSpill) return false;
|
|
12842
|
+
if (node.arrayRange && areaDelta({ sheet, range: node.arrayRange }, sheet, shift2) === void 0)
|
|
12843
|
+
return false;
|
|
12844
|
+
}
|
|
12845
|
+
const ws = this.workbook.sheets[sheet];
|
|
12846
|
+
let spilled = false;
|
|
12847
|
+
ws?.rows.forEach((cells) => {
|
|
12848
|
+
if (!spilled) cells.forEach((cell) => spilled ||= isSpilledCell(cell));
|
|
12849
|
+
});
|
|
12850
|
+
return !spilled;
|
|
12851
|
+
}
|
|
12852
|
+
dropNode(node) {
|
|
12853
|
+
this.structuralSeeds.delete(node);
|
|
12854
|
+
this.cycles.delete(node);
|
|
12855
|
+
this.footprints.delete(node);
|
|
12856
|
+
}
|
|
12857
|
+
/** Updates one formula for the edit; false when the graph cannot follow it. */
|
|
12858
|
+
shiftNode(node, sheet, shift2, nodeDelta) {
|
|
12859
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12860
|
+
if (cell?.formula === void 0) return false;
|
|
12861
|
+
if (node.arrayRange) {
|
|
12862
|
+
const delta = areaDelta({ sheet: node.sheet, range: node.arrayRange }, sheet, shift2);
|
|
12863
|
+
if (delta === void 0) return false;
|
|
12864
|
+
node.arrayRange = movedRange(node.arrayRange, shift2.axis, delta);
|
|
12865
|
+
if (!cell.arrayRange || !sameRange(node.arrayRange, normalizeRange(cell.arrayRange)))
|
|
12866
|
+
return false;
|
|
12867
|
+
}
|
|
12868
|
+
const changed = cell.formula !== node.formula;
|
|
12869
|
+
const traits = node.ast && astTraits(node.ast);
|
|
12870
|
+
const reached = reachesEdit(node.deps, sheet, shift2) || reachesEdit(node.dynamicDeps, sheet, shift2);
|
|
12871
|
+
if (!changed && !reached && nodeDelta === 0 && !traits?.descriptive && !traits?.opaque)
|
|
12872
|
+
return true;
|
|
12873
|
+
if (traits?.complex) {
|
|
12874
|
+
node.formula = cell.formula;
|
|
12875
|
+
this.reanalyze(node);
|
|
12876
|
+
this.structuralSeeds.add(node);
|
|
12877
|
+
return true;
|
|
12878
|
+
}
|
|
12879
|
+
const pos = shift2.axis === "row" ? node.row - nodeDelta : node.col - nodeDelta;
|
|
12880
|
+
const moves = { seed: !!traits?.descriptive, moved: false, cut: false };
|
|
12881
|
+
const deps = this.moveAreas(node.deps, sheet, shift2, pos, nodeDelta, moves);
|
|
12882
|
+
const dynamicDeps = this.moveAreas(node.dynamicDeps, sheet, shift2, pos, nodeDelta, moves);
|
|
12883
|
+
const { cut, moved: anyMoved } = moves;
|
|
12884
|
+
let seed = moves.seed;
|
|
12885
|
+
if (cut || changed !== anyMoved) {
|
|
12886
|
+
node.formula = cell.formula;
|
|
12887
|
+
this.reanalyze(node);
|
|
12888
|
+
this.structuralSeeds.add(node);
|
|
12889
|
+
return true;
|
|
12890
|
+
}
|
|
12891
|
+
if (traits?.positional && (anyMoved || nodeDelta !== 0)) seed = true;
|
|
12892
|
+
node.deps = deps;
|
|
12893
|
+
node.dynamicDeps = dynamicDeps;
|
|
12894
|
+
if (changed) {
|
|
12895
|
+
node.formula = cell.formula;
|
|
12896
|
+
node.stale = true;
|
|
12897
|
+
}
|
|
12898
|
+
if (seed) this.structuralSeeds.add(node);
|
|
12899
|
+
return true;
|
|
12900
|
+
}
|
|
12901
|
+
/**
|
|
12902
|
+
* Areas moved for the edit (the same list when none moves). Records in `moves` whether one
|
|
12903
|
+
* moved, one was cut (deleted, widened, pushed off the grid) and whether implicit intersection
|
|
12904
|
+
* with one can now pick another cell.
|
|
12905
|
+
*/
|
|
12906
|
+
moveAreas(list, sheet, shift2, pos, nodeDelta, moves) {
|
|
12907
|
+
let out;
|
|
12908
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
12909
|
+
const area = list[i2];
|
|
12910
|
+
const delta = areaDelta(area, sheet, shift2);
|
|
12911
|
+
if (delta === void 0) {
|
|
12912
|
+
moves.cut = true;
|
|
12913
|
+
continue;
|
|
12914
|
+
}
|
|
12915
|
+
if (intersectionMoves(area, delta, pos, nodeDelta, shift2.axis)) moves.seed = true;
|
|
12916
|
+
if (delta === 0) continue;
|
|
12917
|
+
moves.moved = true;
|
|
12918
|
+
out ??= list.slice();
|
|
12919
|
+
out[i2] = { sheet: area.sheet, range: movedRange(area.range, shift2.axis, delta) };
|
|
12920
|
+
}
|
|
12921
|
+
return out ?? list;
|
|
12922
|
+
}
|
|
12923
|
+
/**
|
|
12924
|
+
* Follows a sheet rename (`from` to `to`, formulas already rewritten): precedents are kept by
|
|
12925
|
+
* sheet index, so only rewritten formulas need their text parsed again, and only formulas that
|
|
12926
|
+
* name the new sheet without having been rewritten (previously unresolved), describe sheets
|
|
12927
|
+
* (CELL, SHEET, FORMULATEXT) or read defined names whose areas changed are recalculated.
|
|
12928
|
+
*/
|
|
12929
|
+
renameSheet(from, to) {
|
|
12930
|
+
if (!this.graphReady()) {
|
|
12931
|
+
this.invalidate();
|
|
12932
|
+
return;
|
|
12933
|
+
}
|
|
12934
|
+
const target2 = to.toLowerCase();
|
|
12935
|
+
let depsChanged = false;
|
|
12936
|
+
for (const map of this.nodes.values())
|
|
12937
|
+
for (const node of map.values()) {
|
|
12938
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12939
|
+
if (cell?.formula === void 0) {
|
|
12940
|
+
this.invalidate();
|
|
12941
|
+
return;
|
|
12942
|
+
}
|
|
12943
|
+
const changed = cell.formula !== node.formula;
|
|
12944
|
+
const traits = node.ast && astTraits(node.ast);
|
|
12945
|
+
node.formula = cell.formula;
|
|
12946
|
+
if (traits?.complex || !changed && traits?.sheets.has(target2)) {
|
|
12947
|
+
const deps = node.deps;
|
|
12948
|
+
const dynamicDeps = node.dynamicDeps;
|
|
12949
|
+
this.reanalyze(node);
|
|
12950
|
+
const same4 = sameAreas(deps, node.deps) && sameAreas(dynamicDeps, node.dynamicDeps);
|
|
12951
|
+
if (!same4) depsChanged = true;
|
|
12952
|
+
if (!same4 || !traits?.complex) this.structuralSeeds.add(node);
|
|
12953
|
+
} else if (changed) node.stale = true;
|
|
12954
|
+
if (traits?.descriptive || traits?.opaque) this.structuralSeeds.add(node);
|
|
12955
|
+
}
|
|
12956
|
+
if (depsChanged) this.graphChanged();
|
|
12957
|
+
}
|
|
12958
|
+
/** Takes the formulas queued by structural edits. */
|
|
12959
|
+
takeStructuralSeeds(into) {
|
|
12960
|
+
for (const node of this.structuralSeeds)
|
|
12961
|
+
if (this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node) into.add(node);
|
|
12962
|
+
this.structuralSeeds.clear();
|
|
12963
|
+
}
|
|
12964
|
+
};
|
|
12965
|
+
|
|
12421
12966
|
// xlsx/formula/engine.ts
|
|
12422
|
-
var Engine = class extends
|
|
12967
|
+
var Engine = class extends EngineStructure {
|
|
12968
|
+
preparation;
|
|
12969
|
+
/** The prepared formulas the first recalculation checks (see `trustsStoredValues`). */
|
|
12970
|
+
prepared;
|
|
12971
|
+
// ---- the graph ----
|
|
12972
|
+
prepare(timeRemaining) {
|
|
12973
|
+
if (this.built || this.needsFull) return true;
|
|
12974
|
+
this.preparation ??= this.startPreparation();
|
|
12975
|
+
if (!this.preparation.run(timeRemaining)) return false;
|
|
12976
|
+
this.finishPreparation(this.preparation);
|
|
12977
|
+
return true;
|
|
12978
|
+
}
|
|
12979
|
+
discardPreparation() {
|
|
12980
|
+
if (!this.fresh || this.needsFull) return;
|
|
12981
|
+
this.preparation = void 0;
|
|
12982
|
+
this.prepared = void 0;
|
|
12983
|
+
this.structuralSeeds.clear();
|
|
12984
|
+
this.nodes.clear();
|
|
12985
|
+
this.footprints.clear();
|
|
12986
|
+
this.graphChanged();
|
|
12987
|
+
this.built = false;
|
|
12988
|
+
}
|
|
12989
|
+
/** Completes the graph, continuing a preparation that is under way. */
|
|
12990
|
+
build() {
|
|
12991
|
+
const preparation = this.preparation ?? this.startPreparation();
|
|
12992
|
+
preparation.run();
|
|
12993
|
+
this.finishPreparation(preparation);
|
|
12994
|
+
}
|
|
12995
|
+
startPreparation() {
|
|
12996
|
+
this.nodes.clear();
|
|
12997
|
+
this.footprints.clear();
|
|
12998
|
+
this.footprintIndex = void 0;
|
|
12999
|
+
this.prepared = void 0;
|
|
13000
|
+
return new GraphPreparation(
|
|
13001
|
+
this.workbook,
|
|
13002
|
+
(s, row2, col, cell) => this.createNode(s, row2, col, cell, true)
|
|
13003
|
+
);
|
|
13004
|
+
}
|
|
13005
|
+
finishPreparation(preparation) {
|
|
13006
|
+
this.preparation = void 0;
|
|
13007
|
+
this.built = true;
|
|
13008
|
+
this.graphChanged();
|
|
13009
|
+
this.reverseIndex = preparation.reverse;
|
|
13010
|
+
this.prepared = preparation.formulas;
|
|
13011
|
+
}
|
|
12423
13012
|
// ---- recalculation ----
|
|
12424
13013
|
recalculateAll() {
|
|
13014
|
+
this.fresh = false;
|
|
13015
|
+
this.prepared = void 0;
|
|
12425
13016
|
if (this.needsFull) this.releaseAllSpills();
|
|
12426
13017
|
if (!this.built || this.needsFull) this.build();
|
|
12427
13018
|
this.needsFull = false;
|
|
13019
|
+
this.structuralSeeds.clear();
|
|
12428
13020
|
this.cycles = /* @__PURE__ */ new Set();
|
|
12429
13021
|
this.run(new Set(this.allNodes()), true);
|
|
12430
13022
|
}
|
|
12431
13023
|
recalculateFrom(changes) {
|
|
12432
13024
|
const seeds = /* @__PURE__ */ new Set();
|
|
12433
|
-
if (
|
|
12434
|
-
this.
|
|
13025
|
+
if (this.fresh && !this.needsFull) {
|
|
13026
|
+
this.fresh = false;
|
|
13027
|
+
if (!this.built) this.build();
|
|
12435
13028
|
if (!this.trustsStoredValues(changes, seeds)) {
|
|
12436
13029
|
this.recalculateAll();
|
|
12437
13030
|
return;
|
|
@@ -12475,6 +13068,7 @@ var Engine = class extends EngineCore {
|
|
|
12475
13068
|
}
|
|
12476
13069
|
}
|
|
12477
13070
|
if (structural) this.graphChanged();
|
|
13071
|
+
this.takeStructuralSeeds(seeds);
|
|
12478
13072
|
const reverse = this.reverse();
|
|
12479
13073
|
for (const area of changed) reverse.dependents(area.sheet, area.range, seeds);
|
|
12480
13074
|
for (const node of this.allNodes()) if (node.volatile) seeds.add(node);
|
|
@@ -12486,13 +13080,18 @@ var Engine = class extends EngineCore {
|
|
|
12486
13080
|
* without a value into `missing`.
|
|
12487
13081
|
*/
|
|
12488
13082
|
trustsStoredValues(changes, missing) {
|
|
13083
|
+
const prepared = this.prepared;
|
|
13084
|
+
this.prepared = void 0;
|
|
13085
|
+
if (!prepared) return false;
|
|
12489
13086
|
const changed = new Set(changes.map((c) => `${c.sheet}:${cellKey(c.row, c.col)}`));
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
if (
|
|
13087
|
+
const current = (node) => this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node;
|
|
13088
|
+
for (const node of prepared.dynamic) {
|
|
13089
|
+
if (current(node) && !changed.has(`${node.sheet}:${cellKey(node.row, node.col)}`))
|
|
12493
13090
|
return false;
|
|
13091
|
+
}
|
|
13092
|
+
for (const node of prepared.unvalued) {
|
|
12494
13093
|
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
12495
|
-
if (cell && cell.value === null
|
|
13094
|
+
if (current(node) && cell && cell.value === null) missing.add(node);
|
|
12496
13095
|
}
|
|
12497
13096
|
return true;
|
|
12498
13097
|
}
|
|
@@ -12506,7 +13105,10 @@ var Engine = class extends EngineCore {
|
|
|
12506
13105
|
return !!anchor?.spill && rangeHas(anchor.spill, row2, col);
|
|
12507
13106
|
}
|
|
12508
13107
|
invalidate() {
|
|
13108
|
+
this.structuralSeeds.clear();
|
|
12509
13109
|
this.releaseAllSpills();
|
|
13110
|
+
this.preparation = void 0;
|
|
13111
|
+
this.prepared = void 0;
|
|
12510
13112
|
this.nodes.clear();
|
|
12511
13113
|
this.footprints.clear();
|
|
12512
13114
|
this.graphChanged();
|
|
@@ -12551,7 +13153,7 @@ function createCalcEngine(workbook, options = {}) {
|
|
|
12551
13153
|
return new Engine(workbook, options);
|
|
12552
13154
|
}
|
|
12553
13155
|
|
|
12554
|
-
// xlsx/formula/
|
|
13156
|
+
// xlsx/formula/ref-text.ts
|
|
12555
13157
|
function safeTokens(formula) {
|
|
12556
13158
|
try {
|
|
12557
13159
|
return tokenize(formula);
|
|
@@ -12570,50 +13172,26 @@ function formatRefSpec(spec2) {
|
|
|
12570
13172
|
if (spec2.kind === "cell") return a;
|
|
12571
13173
|
return `${a}:${cornerText(spec2.end, spec2.kind)}`;
|
|
12572
13174
|
}
|
|
12573
|
-
function
|
|
13175
|
+
function rewriteRef(token, ref) {
|
|
12574
13176
|
const prefix = token.prefix?.text ?? "";
|
|
12575
13177
|
if (!ref) return `${prefix}#REF!`;
|
|
12576
13178
|
return `${prefix}${formatRefSpec(ref)}${token.spill ? "#" : ""}`;
|
|
12577
13179
|
}
|
|
12578
13180
|
var sameSpec = (a, b) => a.kind === b.kind && a.start.row === b.start.row && a.start.col === b.start.col && a.end.row === b.end.row && a.end.col === b.end.col;
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
const move = (c) => {
|
|
12586
|
-
const row2 = spec2.kind === "cols" || c.rowAbs ? c.row : c.row + dRow;
|
|
12587
|
-
const col = spec2.kind === "rows" || c.colAbs ? c.col : c.col + dCol;
|
|
12588
|
-
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
12589
|
-
return { ...c, row: row2, col };
|
|
12590
|
-
};
|
|
12591
|
-
const start = move(spec2.start);
|
|
12592
|
-
const end = move(spec2.end);
|
|
12593
|
-
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
12594
|
-
if (next && sameSpec(next, spec2)) continue;
|
|
12595
|
-
token.text = rewrite(token, next);
|
|
12596
|
-
}
|
|
12597
|
-
return joinTokens(tokens);
|
|
13181
|
+
var needsQuote = (name) => !/^[A-Za-z_¡-][A-Za-z0-9_.¡-]*$/.test(name) || /^[A-Za-z]{1,3}\d+$/.test(name) || /^(?:R\d*C?\d*|C\d*)$/i.test(name) || /^(?:TRUE|FALSE)$/i.test(name);
|
|
13182
|
+
function prefixText(prefix) {
|
|
13183
|
+
const sheets = prefix.sheet2 !== void 0 ? `${prefix.sheet}:${prefix.sheet2}` : prefix.sheet;
|
|
13184
|
+
const book = prefix.book !== void 0 ? `[${prefix.book}]` : "";
|
|
13185
|
+
const quote = needsQuote(prefix.sheet) || prefix.sheet2 !== void 0 && needsQuote(prefix.sheet2);
|
|
13186
|
+
return quote ? `'${(book + sheets).replace(/'/g, "''")}'!` : `${book}${sheets}!`;
|
|
12598
13187
|
}
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
const na2 = a >= at ? a + count2 : a;
|
|
12607
|
-
const nb2 = b >= at ? b + count2 : b;
|
|
12608
|
-
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
12609
|
-
return [na2, nb2];
|
|
12610
|
-
}
|
|
12611
|
-
const n = -count2;
|
|
12612
|
-
const last = at + n - 1;
|
|
12613
|
-
if (a >= at && b <= last) return void 0;
|
|
12614
|
-
const na = a < at ? a : a <= last ? at : a - n;
|
|
12615
|
-
const nb = b < at ? b : b <= last ? at - 1 : b - n;
|
|
12616
|
-
return [na, nb];
|
|
13188
|
+
|
|
13189
|
+
// xlsx/formula/shift-formula.ts
|
|
13190
|
+
var templates = /* @__PURE__ */ new Map();
|
|
13191
|
+
var MAX_TEMPLATES2 = 2e5;
|
|
13192
|
+
function remember(text2, template) {
|
|
13193
|
+
if (templates.size >= MAX_TEMPLATES2) templates.clear();
|
|
13194
|
+
templates.set(text2, template);
|
|
12617
13195
|
}
|
|
12618
13196
|
function mergeSpacedAreas(tokens) {
|
|
12619
13197
|
const out = [];
|
|
@@ -12640,63 +13218,145 @@ function mergeSpacedAreas(tokens) {
|
|
|
12640
13218
|
}
|
|
12641
13219
|
return out;
|
|
12642
13220
|
}
|
|
12643
|
-
function
|
|
12644
|
-
|
|
13221
|
+
function templateOf(formula) {
|
|
13222
|
+
const cached = templates.get(formula);
|
|
13223
|
+
if (cached !== void 0) return cached;
|
|
12645
13224
|
const raw = safeTokens(formula);
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
13225
|
+
let template = null;
|
|
13226
|
+
if (raw) {
|
|
13227
|
+
template = [];
|
|
13228
|
+
let literal2 = "";
|
|
13229
|
+
for (const token of mergeSpacedAreas(raw)) {
|
|
13230
|
+
if (token.kind !== "ref" && !(token.kind === "name" && token.prefix)) {
|
|
13231
|
+
literal2 += token.text;
|
|
13232
|
+
continue;
|
|
13233
|
+
}
|
|
13234
|
+
if (literal2) template.push(literal2);
|
|
13235
|
+
literal2 = "";
|
|
13236
|
+
const part = { kind: token.kind, text: token.text };
|
|
13237
|
+
if (token.prefix) {
|
|
13238
|
+
part.prefix = token.prefix;
|
|
13239
|
+
if (token.prefix.book === void 0) part.sheet = token.prefix.sheet.toLowerCase();
|
|
13240
|
+
}
|
|
13241
|
+
if (token.ref) part.ref = token.ref;
|
|
13242
|
+
if (token.spill) part.spill = true;
|
|
13243
|
+
template.push(part);
|
|
13244
|
+
}
|
|
13245
|
+
if (literal2) template.push(literal2);
|
|
13246
|
+
}
|
|
13247
|
+
remember(formula, template);
|
|
13248
|
+
return template;
|
|
13249
|
+
}
|
|
13250
|
+
function rewriteTemplate(formula, rewrite) {
|
|
13251
|
+
const template = templateOf(formula);
|
|
13252
|
+
if (!template) return formula;
|
|
13253
|
+
let next;
|
|
13254
|
+
for (let i2 = 0; i2 < template.length; i2++) {
|
|
13255
|
+
const part = template[i2];
|
|
13256
|
+
if (typeof part === "string") continue;
|
|
13257
|
+
const changed = rewrite(part);
|
|
13258
|
+
if (!changed) continue;
|
|
13259
|
+
next ??= template.slice();
|
|
13260
|
+
next[i2] = changed;
|
|
13261
|
+
}
|
|
13262
|
+
if (!next) return formula;
|
|
13263
|
+
const text2 = next.map((part) => typeof part === "string" ? part : part.text).join("");
|
|
13264
|
+
remember(text2, next);
|
|
13265
|
+
return text2;
|
|
13266
|
+
}
|
|
13267
|
+
function shiftInterval(a, b, at, count2, max) {
|
|
13268
|
+
if (count2 > 0) {
|
|
13269
|
+
const na2 = a >= at ? a + count2 : a;
|
|
13270
|
+
const nb2 = b >= at ? b + count2 : b;
|
|
13271
|
+
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
13272
|
+
return [na2, nb2];
|
|
12674
13273
|
}
|
|
12675
|
-
|
|
13274
|
+
const n = -count2;
|
|
13275
|
+
const last = at + n - 1;
|
|
13276
|
+
if (a >= at && b <= last) return void 0;
|
|
13277
|
+
const na = a < at ? a : a <= last ? at : a - n;
|
|
13278
|
+
const nb = b < at ? b : b <= last ? at - 1 : b - n;
|
|
13279
|
+
return [na, nb];
|
|
12676
13280
|
}
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
const
|
|
12681
|
-
const
|
|
12682
|
-
|
|
13281
|
+
function shiftRef(ref, spec2) {
|
|
13282
|
+
const isRow = spec2.axis === "row";
|
|
13283
|
+
if (isRow && ref.kind === "cols" || !isRow && ref.kind === "rows") return ref;
|
|
13284
|
+
const startFirst = isRow ? ref.start.row <= ref.end.row : ref.start.col <= ref.end.col;
|
|
13285
|
+
const lo = startFirst ? ref.start : ref.end;
|
|
13286
|
+
const hi = startFirst ? ref.end : ref.start;
|
|
13287
|
+
const shifted2 = shiftInterval(
|
|
13288
|
+
isRow ? lo.row : lo.col,
|
|
13289
|
+
isRow ? hi.row : hi.col,
|
|
13290
|
+
spec2.at,
|
|
13291
|
+
spec2.count,
|
|
13292
|
+
isRow ? MAX_ROW : MAX_COL
|
|
13293
|
+
);
|
|
13294
|
+
if (!shifted2) return void 0;
|
|
13295
|
+
const [a, b] = shifted2;
|
|
13296
|
+
const nlo = isRow ? { ...lo, row: a } : { ...lo, col: a };
|
|
13297
|
+
const nhi = isRow ? { ...hi, row: b } : { ...hi, col: b };
|
|
13298
|
+
const next = {
|
|
13299
|
+
kind: ref.kind,
|
|
13300
|
+
start: startFirst ? nlo : nhi,
|
|
13301
|
+
end: startFirst ? nhi : nlo
|
|
13302
|
+
};
|
|
13303
|
+
if (ref.kind === "cell") next.end = next.start;
|
|
13304
|
+
return sameSpec(next, ref) ? ref : next;
|
|
13305
|
+
}
|
|
13306
|
+
function shiftFormula(formula, formulaSheet, spec2) {
|
|
13307
|
+
if (spec2.count === 0) return formula;
|
|
13308
|
+
const sheet = spec2.sheet.toLowerCase();
|
|
13309
|
+
const own = formulaSheet.toLowerCase() === sheet;
|
|
13310
|
+
return rewriteTemplate(formula, (part) => {
|
|
13311
|
+
if (part.kind !== "ref" || !part.ref || (part.prefix ? part.sheet !== sheet : !own))
|
|
13312
|
+
return void 0;
|
|
13313
|
+
const next = shiftRef(part.ref, spec2);
|
|
13314
|
+
if (next === part.ref) return void 0;
|
|
13315
|
+
const out = { kind: "ref", text: rewriteRef(part, next) };
|
|
13316
|
+
if (part.prefix) out.prefix = part.prefix;
|
|
13317
|
+
if (part.sheet !== void 0) out.sheet = part.sheet;
|
|
13318
|
+
if (next) out.ref = next;
|
|
13319
|
+
if (part.spill) out.spill = true;
|
|
13320
|
+
return out;
|
|
13321
|
+
});
|
|
12683
13322
|
}
|
|
12684
13323
|
function renameSheetInFormula(formula, oldName, newName) {
|
|
12685
|
-
const tokens = safeTokens(formula);
|
|
12686
|
-
if (!tokens) return formula;
|
|
12687
13324
|
const lower2 = oldName.toLowerCase();
|
|
12688
|
-
|
|
12689
|
-
const prefix =
|
|
12690
|
-
if (!prefix ||
|
|
12691
|
-
const first2 =
|
|
13325
|
+
return rewriteTemplate(formula, (part) => {
|
|
13326
|
+
const prefix = part.prefix;
|
|
13327
|
+
if (!prefix || part.sheet === void 0) return void 0;
|
|
13328
|
+
const first2 = part.sheet === lower2;
|
|
12692
13329
|
const second = prefix.sheet2?.toLowerCase() === lower2;
|
|
12693
|
-
if (!first2 && !second)
|
|
13330
|
+
if (!first2 && !second) return void 0;
|
|
12694
13331
|
const renamed = { ...prefix, sheet: first2 ? newName : prefix.sheet };
|
|
12695
13332
|
if (prefix.sheet2 !== void 0) renamed.sheet2 = second ? newName : prefix.sheet2;
|
|
12696
13333
|
const text2 = prefixText(renamed);
|
|
12697
|
-
token.text = text2 + token.text.slice(prefix.text.length);
|
|
12698
13334
|
renamed.text = text2;
|
|
12699
|
-
|
|
13335
|
+
const out = { ...part, text: text2 + part.text.slice(prefix.text.length) };
|
|
13336
|
+
out.prefix = renamed;
|
|
13337
|
+
out.sheet = renamed.sheet.toLowerCase();
|
|
13338
|
+
return out;
|
|
13339
|
+
});
|
|
13340
|
+
}
|
|
13341
|
+
|
|
13342
|
+
// xlsx/formula/transform.ts
|
|
13343
|
+
function translateFormula(formula, dRow, dCol) {
|
|
13344
|
+
const tokens = safeTokens(formula);
|
|
13345
|
+
if (!tokens) return formula;
|
|
13346
|
+
for (const token of tokens) {
|
|
13347
|
+
if (token.kind !== "ref" || !token.ref) continue;
|
|
13348
|
+
const spec2 = token.ref;
|
|
13349
|
+
const move = (c) => {
|
|
13350
|
+
const row2 = spec2.kind === "cols" || c.rowAbs ? c.row : c.row + dRow;
|
|
13351
|
+
const col = spec2.kind === "rows" || c.colAbs ? c.col : c.col + dCol;
|
|
13352
|
+
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
13353
|
+
return { ...c, row: row2, col };
|
|
13354
|
+
};
|
|
13355
|
+
const start = move(spec2.start);
|
|
13356
|
+
const end = move(spec2.end);
|
|
13357
|
+
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
13358
|
+
if (next && sameSpec(next, spec2)) continue;
|
|
13359
|
+
token.text = rewriteRef(token, next);
|
|
12700
13360
|
}
|
|
12701
13361
|
return joinTokens(tokens);
|
|
12702
13362
|
}
|
|
@@ -13020,13 +13680,13 @@ function dataBarLengths(rule, node) {
|
|
|
13020
13680
|
maxLength: rule.maxLength ?? numAttr(bar, "maxLength") ?? 90
|
|
13021
13681
|
};
|
|
13022
13682
|
}
|
|
13023
|
-
function rewriteConditionalExtension(rule,
|
|
13683
|
+
function rewriteConditionalExtension(rule, rewrite) {
|
|
13024
13684
|
if (!rule.extensionXml) return;
|
|
13025
13685
|
const doc = parseXml(rule.extensionXml);
|
|
13026
13686
|
let changed = false;
|
|
13027
13687
|
for (const formula of descendants(doc.documentElement, "f", XM)) {
|
|
13028
13688
|
const before = formula.textContent ?? "";
|
|
13029
|
-
const next =
|
|
13689
|
+
const next = rewrite(before);
|
|
13030
13690
|
if (before !== next) {
|
|
13031
13691
|
formula.textContent = next;
|
|
13032
13692
|
changed = true;
|
|
@@ -14053,13 +14713,13 @@ function linearTrend(values2) {
|
|
|
14053
14713
|
const slope = den ? num2 / den : 0;
|
|
14054
14714
|
return (k) => Number((meanY + slope * (k - meanX)).toPrecision(15));
|
|
14055
14715
|
}
|
|
14056
|
-
var
|
|
14716
|
+
var isDigit5 = (ch) => ch !== void 0 && ch >= "0" && ch <= "9";
|
|
14057
14717
|
function matchTextNumber(text2) {
|
|
14058
14718
|
let end = text2.length;
|
|
14059
|
-
while (end > 0 && !
|
|
14719
|
+
while (end > 0 && !isDigit5(text2[end - 1])) end--;
|
|
14060
14720
|
if (end === 0) return null;
|
|
14061
14721
|
let start = end;
|
|
14062
|
-
while (start > 0 &&
|
|
14722
|
+
while (start > 0 && isDigit5(text2[start - 1])) start--;
|
|
14063
14723
|
return [text2, text2.slice(0, start), text2.slice(start, end), text2.slice(end)];
|
|
14064
14724
|
}
|
|
14065
14725
|
var QUARTER = /^(q|qtr|quarter)(\s?)([1-4])$/i;
|
|
@@ -14242,10 +14902,10 @@ function removeValidationArea(rules, area) {
|
|
|
14242
14902
|
}
|
|
14243
14903
|
|
|
14244
14904
|
// xlsx/edit/conditional-formulas.ts
|
|
14245
|
-
function rewriteConditionalRule(rule,
|
|
14905
|
+
function rewriteConditionalRule(rule, rewrite) {
|
|
14246
14906
|
const safe2 = (formula) => {
|
|
14247
14907
|
try {
|
|
14248
|
-
return
|
|
14908
|
+
return rewrite(formula);
|
|
14249
14909
|
} catch {
|
|
14250
14910
|
return formula;
|
|
14251
14911
|
}
|
|
@@ -14764,7 +15424,7 @@ function shiftPreservedXml(sheet, shift2, moveRange, banded) {
|
|
|
14764
15424
|
(xml) => xml.includes("sqref")
|
|
14765
15425
|
);
|
|
14766
15426
|
}
|
|
14767
|
-
function rewritePreservedFormulas(sheet,
|
|
15427
|
+
function rewritePreservedFormulas(sheet, rewrite) {
|
|
14768
15428
|
editEntries(
|
|
14769
15429
|
sheet,
|
|
14770
15430
|
"extLst",
|
|
@@ -14774,7 +15434,7 @@ function rewritePreservedFormulas(sheet, rewrite2) {
|
|
|
14774
15434
|
const text2 = f6.textContent ?? "";
|
|
14775
15435
|
let next = text2;
|
|
14776
15436
|
try {
|
|
14777
|
-
next =
|
|
15437
|
+
next = rewrite(text2, sheet.name);
|
|
14778
15438
|
} catch {
|
|
14779
15439
|
next = text2;
|
|
14780
15440
|
}
|
|
@@ -14789,46 +15449,46 @@ function rewritePreservedFormulas(sheet, rewrite2) {
|
|
|
14789
15449
|
}
|
|
14790
15450
|
|
|
14791
15451
|
// xlsx/edit/shift-formulas.ts
|
|
14792
|
-
function safe(
|
|
15452
|
+
function safe(rewrite, formula, formulaSheet) {
|
|
14793
15453
|
try {
|
|
14794
|
-
return
|
|
15454
|
+
return rewrite(formula, formulaSheet);
|
|
14795
15455
|
} catch {
|
|
14796
15456
|
return formula;
|
|
14797
15457
|
}
|
|
14798
15458
|
}
|
|
14799
|
-
function rewriteFormulas(workbook,
|
|
14800
|
-
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet,
|
|
15459
|
+
function rewriteFormulas(workbook, rewrite) {
|
|
15460
|
+
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet, rewrite);
|
|
14801
15461
|
for (const definedName of workbook.definedNames) {
|
|
14802
15462
|
const local = definedName.localSheet === void 0 ? void 0 : workbook.sheets[definedName.localSheet];
|
|
14803
|
-
definedName.formula = safe(
|
|
15463
|
+
definedName.formula = safe(rewrite, definedName.formula, local?.name ?? "");
|
|
14804
15464
|
}
|
|
14805
15465
|
}
|
|
14806
|
-
function rewriteSheetFormulas(sheet,
|
|
14807
|
-
rewritePreservedFormulas(sheet,
|
|
15466
|
+
function rewriteSheetFormulas(sheet, rewrite) {
|
|
15467
|
+
rewritePreservedFormulas(sheet, rewrite);
|
|
14808
15468
|
{
|
|
14809
15469
|
const name = sheet.name;
|
|
14810
15470
|
for (const table2 of sheet.tables)
|
|
14811
15471
|
for (const column of table2.columns)
|
|
14812
15472
|
if (column.calculatedColumnFormula !== void 0)
|
|
14813
|
-
column.calculatedColumnFormula = safe(
|
|
15473
|
+
column.calculatedColumnFormula = safe(rewrite, column.calculatedColumnFormula, name);
|
|
14814
15474
|
for (const cells of sheet.rows.values())
|
|
14815
15475
|
for (const cell of cells.values())
|
|
14816
|
-
if (cell.formula !== void 0) cell.formula = safe(
|
|
15476
|
+
if (cell.formula !== void 0) cell.formula = safe(rewrite, cell.formula, name);
|
|
14817
15477
|
for (const cf of sheet.conditionalFormats)
|
|
14818
|
-
for (const rule of cf.rules) rewriteConditionalRule(rule, (f6) =>
|
|
15478
|
+
for (const rule of cf.rules) rewriteConditionalRule(rule, (f6) => rewrite(f6, name));
|
|
14819
15479
|
for (const dv of sheet.dataValidations) {
|
|
14820
|
-
if (dv.formula1 !== void 0) dv.formula1 = safe(
|
|
14821
|
-
if (dv.formula2 !== void 0) dv.formula2 = safe(
|
|
15480
|
+
if (dv.formula1 !== void 0) dv.formula1 = safe(rewrite, dv.formula1, name);
|
|
15481
|
+
if (dv.formula2 !== void 0) dv.formula2 = safe(rewrite, dv.formula2, name);
|
|
14822
15482
|
}
|
|
14823
15483
|
for (const link of sheet.hyperlinks)
|
|
14824
15484
|
if (link.location && /![A-Za-z$]/.test(link.location))
|
|
14825
|
-
link.location = safe(
|
|
15485
|
+
link.location = safe(rewrite, link.location, name);
|
|
14826
15486
|
for (const drawing of sheet.drawings) {
|
|
14827
15487
|
if (drawing.kind !== "chart") continue;
|
|
14828
15488
|
for (const series of drawing.series) {
|
|
14829
|
-
if (series.nameRef) series.nameRef = safe(
|
|
14830
|
-
if (series.categoriesRef) series.categoriesRef = safe(
|
|
14831
|
-
if (series.valuesRef) series.valuesRef = safe(
|
|
15489
|
+
if (series.nameRef) series.nameRef = safe(rewrite, series.nameRef, name);
|
|
15490
|
+
if (series.categoriesRef) series.categoriesRef = safe(rewrite, series.categoriesRef, name);
|
|
15491
|
+
if (series.valuesRef) series.valuesRef = safe(rewrite, series.valuesRef, name);
|
|
14832
15492
|
}
|
|
14833
15493
|
}
|
|
14834
15494
|
}
|
|
@@ -15015,7 +15675,7 @@ function shiftAxis(ctx, s, axis, at, count2, insert) {
|
|
|
15015
15675
|
applyAxisShift(ctx, sheet, shift2);
|
|
15016
15676
|
if (insert) inheritFormats(sheet, axis, at, count2);
|
|
15017
15677
|
},
|
|
15018
|
-
{ sheet: s, structural: true }
|
|
15678
|
+
{ sheet: s, structural: true, calc: { kind: "shift", sheet: s, shift: shift2 } }
|
|
15019
15679
|
);
|
|
15020
15680
|
}
|
|
15021
15681
|
var insertRows = (ctx, s, at, count2) => shiftAxis(ctx, s, "row", at, count2, true);
|
|
@@ -16829,6 +17489,14 @@ function setCalcMode(ctx, mode) {
|
|
|
16829
17489
|
|
|
16830
17490
|
// xlsx/edit/session-calc.ts
|
|
16831
17491
|
var isStructural = (step) => step.structural || step.entries.some((entry) => entry.before.kind !== "cells");
|
|
17492
|
+
function hintFor(step, mode) {
|
|
17493
|
+
const hint = step.calc;
|
|
17494
|
+
if (!hint) return void 0;
|
|
17495
|
+
if (hint.kind === "rename")
|
|
17496
|
+
return mode === "undo" ? { kind: "rename", from: hint.to, to: hint.from } : hint;
|
|
17497
|
+
return mode === "undo" ? void 0 : hint;
|
|
17498
|
+
}
|
|
17499
|
+
var settingsOf = (workbook) => `${workbook.iterate ? `${workbook.iterate.count}:${workbook.iterate.delta}` : ""}|${workbook.date1904}`;
|
|
16832
17500
|
var SessionCalculator = class {
|
|
16833
17501
|
constructor(workbook, calc, enabled) {
|
|
16834
17502
|
this.workbook = workbook;
|
|
@@ -16838,43 +17506,113 @@ var SessionCalculator = class {
|
|
|
16838
17506
|
workbook;
|
|
16839
17507
|
calc;
|
|
16840
17508
|
enabled;
|
|
16841
|
-
/** Structural edits
|
|
17509
|
+
/** Structural edits the engine could not follow leave the dependency graph stale (manual mode). */
|
|
16842
17510
|
staleGraph = false;
|
|
17511
|
+
/** Cells changed in manual mode since the last calculation. */
|
|
17512
|
+
dirty = [];
|
|
17513
|
+
/** The settings at the last calculation; undefined before the first. */
|
|
17514
|
+
calculated;
|
|
16843
17515
|
/** Recalculates after an applied, undone or redone step (failures become warnings). */
|
|
16844
|
-
afterStep(step) {
|
|
16845
|
-
if (!this.enabled)
|
|
17516
|
+
afterStep(step, mode = "apply") {
|
|
17517
|
+
if (!this.enabled) {
|
|
17518
|
+
this.calc.discardPreparation();
|
|
17519
|
+
return;
|
|
17520
|
+
}
|
|
17521
|
+
const structural = isStructural(step);
|
|
17522
|
+
const hint = structural ? hintFor(step, mode) : void 0;
|
|
16846
17523
|
if (calcModeOf(this.workbook) === "manual") {
|
|
16847
|
-
if (
|
|
17524
|
+
if (hint && !this.staleGraph && !this.dirty.length) {
|
|
17525
|
+
this.guard(() => this.follow(hint));
|
|
17526
|
+
return;
|
|
17527
|
+
}
|
|
17528
|
+
this.calc.discardPreparation();
|
|
17529
|
+
if (structural) this.staleGraph = true;
|
|
17530
|
+
else this.dirty.push(...touchedCells(step));
|
|
16848
17531
|
return;
|
|
16849
17532
|
}
|
|
16850
|
-
|
|
17533
|
+
if (hint && !this.staleGraph) {
|
|
17534
|
+
this.guard(() => {
|
|
17535
|
+
this.follow(hint);
|
|
17536
|
+
this.calc.recalculateFrom(touchedCells(step));
|
|
17537
|
+
this.calculated = settingsOf(this.workbook);
|
|
17538
|
+
});
|
|
17539
|
+
return;
|
|
17540
|
+
}
|
|
17541
|
+
this.recalc(structural, () => touchedCells(step));
|
|
16851
17542
|
}
|
|
16852
17543
|
/** Recalculates after a change applied outside the history (a collaborator's edit). */
|
|
16853
17544
|
afterExternal(structural, cells) {
|
|
16854
|
-
if (!this.enabled)
|
|
16855
|
-
|
|
17545
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual") {
|
|
17546
|
+
this.calc.discardPreparation();
|
|
17547
|
+
if (!this.enabled) return;
|
|
16856
17548
|
if (structural) this.staleGraph = true;
|
|
17549
|
+
else this.dirty.push(...cells);
|
|
16857
17550
|
return;
|
|
16858
17551
|
}
|
|
16859
17552
|
this.recalc(structural, () => cells);
|
|
16860
17553
|
}
|
|
16861
|
-
|
|
17554
|
+
follow(hint) {
|
|
17555
|
+
if (hint.kind === "shift") this.calc.shiftCells(hint.sheet, hint.shift);
|
|
17556
|
+
else this.calc.renameSheet(hint.from, hint.to);
|
|
17557
|
+
}
|
|
17558
|
+
guard(run) {
|
|
17559
|
+
try {
|
|
17560
|
+
run();
|
|
17561
|
+
} catch (error) {
|
|
17562
|
+
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
17563
|
+
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
17564
|
+
}
|
|
17565
|
+
}
|
|
17566
|
+
/** Builds the dependency graph ahead of the first edit (see `EditSession.prepareCalculation`). */
|
|
17567
|
+
prepare(timeRemaining) {
|
|
17568
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return true;
|
|
16862
17569
|
try {
|
|
17570
|
+
return this.calc.prepare(timeRemaining);
|
|
17571
|
+
} catch {
|
|
17572
|
+
this.calc.discardPreparation();
|
|
17573
|
+
return true;
|
|
17574
|
+
}
|
|
17575
|
+
}
|
|
17576
|
+
/**
|
|
17577
|
+
* Before a structural edit the graph can follow in place: finishes a graph being prepared (or
|
|
17578
|
+
* builds it) while it still matches the workbook, so the edit moves it instead of rebuilding.
|
|
17579
|
+
*/
|
|
17580
|
+
beforeStructural() {
|
|
17581
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return;
|
|
17582
|
+
this.prepare();
|
|
17583
|
+
}
|
|
17584
|
+
recalc(structural, cells) {
|
|
17585
|
+
this.guard(() => {
|
|
16863
17586
|
if (this.staleGraph || structural) this.full();
|
|
16864
17587
|
else {
|
|
16865
17588
|
const changed = cells();
|
|
16866
17589
|
if (changed.length) this.calc.recalculateFrom(changed);
|
|
17590
|
+
this.calculated = settingsOf(this.workbook);
|
|
16867
17591
|
}
|
|
16868
|
-
}
|
|
16869
|
-
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
16870
|
-
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
16871
|
-
}
|
|
17592
|
+
});
|
|
16872
17593
|
}
|
|
16873
|
-
/** Rebuilds the dependency graph and recalculates every formula (F9). */
|
|
17594
|
+
/** Rebuilds the dependency graph and recalculates every formula (Ctrl+Alt+F9). */
|
|
16874
17595
|
full() {
|
|
16875
17596
|
this.staleGraph = false;
|
|
17597
|
+
this.dirty = [];
|
|
16876
17598
|
this.calc.invalidate();
|
|
16877
17599
|
this.calc.recalculateAll();
|
|
17600
|
+
this.calculated = settingsOf(this.workbook);
|
|
17601
|
+
}
|
|
17602
|
+
/**
|
|
17603
|
+
* Calculate Now (F9): the cells changed since the last calculation, the formulas structural
|
|
17604
|
+
* edits queued, their dependents and the volatile functions. Everything when `full`, before
|
|
17605
|
+
* the session's first calculation, after the iteration settings changed or while the graph
|
|
17606
|
+
* is stale.
|
|
17607
|
+
*/
|
|
17608
|
+
now(full) {
|
|
17609
|
+
if (full || this.staleGraph || this.calculated !== settingsOf(this.workbook)) {
|
|
17610
|
+
this.full();
|
|
17611
|
+
return;
|
|
17612
|
+
}
|
|
17613
|
+
const changed = this.dirty;
|
|
17614
|
+
this.dirty = [];
|
|
17615
|
+
this.calc.recalculateFrom(changed);
|
|
16878
17616
|
}
|
|
16879
17617
|
/**
|
|
16880
17618
|
* Recalculates one sheet's formulas and their dependents (Shift+F9); after structural edits
|
|
@@ -20383,12 +21121,12 @@ function renameSheet(ctx, index2, name) {
|
|
|
20383
21121
|
ctx.run(
|
|
20384
21122
|
"Rename sheet",
|
|
20385
21123
|
"sheets",
|
|
20386
|
-
[{ kind: "
|
|
21124
|
+
[{ kind: "refs" }],
|
|
20387
21125
|
() => {
|
|
20388
21126
|
rewriteFormulas(workbook, (formula) => renameSheetInFormula(formula, old, name));
|
|
20389
21127
|
sheet.name = name;
|
|
20390
21128
|
},
|
|
20391
|
-
{ sheet: index2, structural: true }
|
|
21129
|
+
{ sheet: index2, structural: true, calc: { kind: "rename", from: old, to: name } }
|
|
20392
21130
|
);
|
|
20393
21131
|
}
|
|
20394
21132
|
function moveSheet(ctx, from, to) {
|
|
@@ -20764,13 +21502,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
20764
21502
|
for (const listener of [...listeners2]) listener(change);
|
|
20765
21503
|
};
|
|
20766
21504
|
const calculator = new SessionCalculator(workbook, calc, autoRecalc);
|
|
20767
|
-
const recalc = (step) => calculator.afterStep(step);
|
|
20768
|
-
const begin = (label2, kind, info) =>
|
|
20769
|
-
step
|
|
20770
|
-
|
|
20771
|
-
sheet: info.sheet,
|
|
20772
|
-
|
|
20773
|
-
});
|
|
21505
|
+
const recalc = (step, mode = "apply") => calculator.afterStep(step, mode);
|
|
21506
|
+
const begin = (label2, kind, info) => {
|
|
21507
|
+
const step = { label: label2, entries: [], structural: info.structural ?? false };
|
|
21508
|
+
if (info.calc) step.calc = info.calc;
|
|
21509
|
+
return { step, kind, sheet: info.sheet, ranges: [...info.ranges ?? []] };
|
|
21510
|
+
};
|
|
20774
21511
|
const finish = (current) => {
|
|
20775
21512
|
if (!current.step.entries.length) return;
|
|
20776
21513
|
history.push(current.step);
|
|
@@ -20795,10 +21532,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
20795
21532
|
const outer = !open;
|
|
20796
21533
|
const current = open ?? begin(label2, kind, info);
|
|
20797
21534
|
if (!outer) {
|
|
21535
|
+
delete current.step.calc;
|
|
20798
21536
|
if (info.structural) current.step.structural = true;
|
|
20799
21537
|
if (current.sheet === void 0 && info.sheet !== void 0) current.sheet = info.sheet;
|
|
20800
21538
|
current.ranges.push(...info.ranges ?? []);
|
|
20801
21539
|
}
|
|
21540
|
+
if (outer && info.calc) calculator.beforeStructural();
|
|
20802
21541
|
open = current;
|
|
20803
21542
|
const mark = current.step.entries.length;
|
|
20804
21543
|
const befores = scopes.map((scope) => captureScope(workbook, scope));
|
|
@@ -20846,7 +21585,7 @@ function createEditSession(workbook, options = {}) {
|
|
|
20846
21585
|
if (open) throw new Error(`Cannot ${kind} inside a batch`);
|
|
20847
21586
|
const step = kind === "undo" ? history.undo(workbook) : history.redo(workbook);
|
|
20848
21587
|
if (!step) return false;
|
|
20849
|
-
recalc(step);
|
|
21588
|
+
recalc(step, kind);
|
|
20850
21589
|
emit({ kind, label: step.label, structural: step.structural });
|
|
20851
21590
|
return true;
|
|
20852
21591
|
};
|
|
@@ -20925,10 +21664,11 @@ function createEditSession(workbook, options = {}) {
|
|
|
20925
21664
|
setDocumentProperties: (patch) => setDocumentProperties(ctx, patch),
|
|
20926
21665
|
setAutoRecalc: (enabled) => setCalcMode(ctx, enabled ? "auto" : "manual"),
|
|
20927
21666
|
autoRecalc: () => autoRecalc && calcModeOf(workbook) === "auto",
|
|
20928
|
-
calculateNow() {
|
|
20929
|
-
calculator.full
|
|
21667
|
+
calculateNow(options2) {
|
|
21668
|
+
calculator.now(options2?.full ?? false);
|
|
20930
21669
|
emit({ kind: "cells", label: "Calculate now", structural: false });
|
|
20931
21670
|
},
|
|
21671
|
+
prepareCalculation: (opts) => calculator.prepare(opts?.timeRemaining),
|
|
20932
21672
|
calculateSheet(s) {
|
|
20933
21673
|
calculator.sheet(s);
|
|
20934
21674
|
emit({ kind: "cells", label: "Calculate sheet", sheet: s, structural: false });
|