ooxml-core 1.2.0 → 1.2.1
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-VQQS4VS6.mjs} +2 -2
- package/dist/automation/index.cjs +1059 -328
- package/dist/automation/index.mjs +1059 -328
- 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-5U27IVB7.mjs} +3 -3
- package/dist/{chunk-VYTA2OUN.mjs → chunk-5VLNF4OX.mjs} +1 -1
- package/dist/{chunk-CQQAPUAG.mjs → chunk-V2BIGIH4.mjs} +11 -9
- package/dist/{chunk-FI4RSJ24.mjs → chunk-XBNSBDNT.mjs} +1 -1
- package/dist/{chunk-XCZ7U3GZ.mjs → chunk-XSFHGZFH.mjs} +11 -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 +27 -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 +27 -17
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/index.cjs +27 -17
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +157 -82
- package/dist/teams/index.mjs +157 -82
- 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 +1069 -329
- package/dist/xlsx/index.mjs +1069 -330
- 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 +152 -90
- package/dist/xlsx/load/index.mjs +152 -90
- package/dist/xlsx/ui/index.cjs +1071 -340
- package/dist/xlsx/ui/index.mjs +1071 -340
- package/package.json +1 -1
|
@@ -8624,9 +8624,9 @@ function rejectUnsafeRunSegmentation(paragraph2, base, oldRuns) {
|
|
|
8624
8624
|
(run2) => !run2.image && !run2.equation && (run2.restoredRunPropertiesXml || run2.sourceRunPropertiesXml)
|
|
8625
8625
|
))
|
|
8626
8626
|
return;
|
|
8627
|
-
const
|
|
8627
|
+
const sameText2 = paragraph2.runs.map((run2) => run2.text).join("") === base.runs.map((run2) => run2.text).join("");
|
|
8628
8628
|
const sameBoundaries = paragraph2.runs.length === base.runs.length && paragraph2.runs.every((run2, index2) => run2.text === base.runs[index2]?.text);
|
|
8629
|
-
if (sameBoundaries || !
|
|
8629
|
+
if (sameBoundaries || !sameText2 && paragraph2.runs.length === base.runs.length) return;
|
|
8630
8630
|
throw new Error(
|
|
8631
8631
|
`Cannot edit paragraph ${paragraph2.id}: changing run boundaries could drop unsupported run properties. The original DOCX package remains unchanged.`
|
|
8632
8632
|
);
|
|
@@ -12498,7 +12498,7 @@ var NAME_RE = /^[A-Za-z_\\\u00A1-\uFFFF][A-Za-z0-9_.?\\\u00A1-\uFFFF]*/;
|
|
|
12498
12498
|
var CELL_RE = /^(\$?)([A-Za-z]{1,3})(\$?)(\d{1,7})/;
|
|
12499
12499
|
var COLS_RE = /^(\$?)([A-Za-z]{1,3}):(\$?)([A-Za-z]{1,3})/;
|
|
12500
12500
|
var ROWS_RE = /^(\$?)(\d{1,7}):(\$?)(\d{1,7})/;
|
|
12501
|
-
var NUMBER_RE = /^(?:\d
|
|
12501
|
+
var NUMBER_RE = /^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/;
|
|
12502
12502
|
var sticky = (re) => new RegExp(re.source.replace(/^\^/, ""), "y");
|
|
12503
12503
|
var CELL_AT = sticky(CELL_RE);
|
|
12504
12504
|
var COLS_AT = sticky(COLS_RE);
|
|
@@ -12845,7 +12845,7 @@ function readName(source2, at2, start, prefix) {
|
|
|
12845
12845
|
}
|
|
12846
12846
|
var joinTokens = (tokens3) => tokens3.map((t) => t.text).join("");
|
|
12847
12847
|
|
|
12848
|
-
// xlsx/formula/
|
|
12848
|
+
// xlsx/formula/ref-text.ts
|
|
12849
12849
|
function safeTokens(formula) {
|
|
12850
12850
|
try {
|
|
12851
12851
|
return tokenize(formula);
|
|
@@ -12864,50 +12864,26 @@ function formatRefSpec(spec2) {
|
|
|
12864
12864
|
if (spec2.kind === "cell") return a2;
|
|
12865
12865
|
return `${a2}:${cornerText(spec2.end, spec2.kind)}`;
|
|
12866
12866
|
}
|
|
12867
|
-
function
|
|
12867
|
+
function rewriteRef(token, ref) {
|
|
12868
12868
|
const prefix = token.prefix?.text ?? "";
|
|
12869
12869
|
if (!ref) return `${prefix}#REF!`;
|
|
12870
12870
|
return `${prefix}${formatRefSpec(ref)}${token.spill ? "#" : ""}`;
|
|
12871
12871
|
}
|
|
12872
12872
|
var sameSpec = (a2, b) => a2.kind === b.kind && a2.start.row === b.start.row && a2.start.col === b.start.col && a2.end.row === b.end.row && a2.end.col === b.end.col;
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
const move = (c2) => {
|
|
12880
|
-
const row2 = spec2.kind === "cols" || c2.rowAbs ? c2.row : c2.row + dRow;
|
|
12881
|
-
const col = spec2.kind === "rows" || c2.colAbs ? c2.col : c2.col + dCol;
|
|
12882
|
-
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
12883
|
-
return { ...c2, row: row2, col };
|
|
12884
|
-
};
|
|
12885
|
-
const start = move(spec2.start);
|
|
12886
|
-
const end = move(spec2.end);
|
|
12887
|
-
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
12888
|
-
if (next && sameSpec(next, spec2)) continue;
|
|
12889
|
-
token.text = rewrite(token, next);
|
|
12890
|
-
}
|
|
12891
|
-
return joinTokens(tokens3);
|
|
12873
|
+
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);
|
|
12874
|
+
function prefixText(prefix) {
|
|
12875
|
+
const sheets = prefix.sheet2 !== void 0 ? `${prefix.sheet}:${prefix.sheet2}` : prefix.sheet;
|
|
12876
|
+
const book = prefix.book !== void 0 ? `[${prefix.book}]` : "";
|
|
12877
|
+
const quote2 = needsQuote(prefix.sheet) || prefix.sheet2 !== void 0 && needsQuote(prefix.sheet2);
|
|
12878
|
+
return quote2 ? `'${(book + sheets).replace(/'/g, "''")}'!` : `${book}${sheets}!`;
|
|
12892
12879
|
}
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
const na2 = a2 >= at2 ? a2 + count2 : a2;
|
|
12901
|
-
const nb2 = b >= at2 ? b + count2 : b;
|
|
12902
|
-
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
12903
|
-
return [na2, nb2];
|
|
12904
|
-
}
|
|
12905
|
-
const n = -count2;
|
|
12906
|
-
const last = at2 + n - 1;
|
|
12907
|
-
if (a2 >= at2 && b <= last) return void 0;
|
|
12908
|
-
const na = a2 < at2 ? a2 : a2 <= last ? at2 : a2 - n;
|
|
12909
|
-
const nb = b < at2 ? b : b <= last ? at2 - 1 : b - n;
|
|
12910
|
-
return [na, nb];
|
|
12880
|
+
|
|
12881
|
+
// xlsx/formula/shift-formula.ts
|
|
12882
|
+
var templates = /* @__PURE__ */ new Map();
|
|
12883
|
+
var MAX_TEMPLATES = 2e5;
|
|
12884
|
+
function remember2(text2, template) {
|
|
12885
|
+
if (templates.size >= MAX_TEMPLATES) templates.clear();
|
|
12886
|
+
templates.set(text2, template);
|
|
12911
12887
|
}
|
|
12912
12888
|
function mergeSpacedAreas(tokens3) {
|
|
12913
12889
|
const out = [];
|
|
@@ -12934,63 +12910,145 @@ function mergeSpacedAreas(tokens3) {
|
|
|
12934
12910
|
}
|
|
12935
12911
|
return out;
|
|
12936
12912
|
}
|
|
12937
|
-
function
|
|
12938
|
-
|
|
12913
|
+
function templateOf(formula) {
|
|
12914
|
+
const cached3 = templates.get(formula);
|
|
12915
|
+
if (cached3 !== void 0) return cached3;
|
|
12939
12916
|
const raw2 = safeTokens(formula);
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
12952
|
-
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
if (shifted2) {
|
|
12960
|
-
const [a2, b] = shifted2;
|
|
12961
|
-
const nlo = isRow ? { ...lo, row: a2 } : { ...lo, col: a2 };
|
|
12962
|
-
const nhi = isRow ? { ...hi, row: b } : { ...hi, col: b };
|
|
12963
|
-
next = { kind: ref.kind, start: startFirst ? nlo : nhi, end: startFirst ? nhi : nlo };
|
|
12964
|
-
if (ref.kind === "cell") next.end = next.start;
|
|
12917
|
+
let template = null;
|
|
12918
|
+
if (raw2) {
|
|
12919
|
+
template = [];
|
|
12920
|
+
let literal2 = "";
|
|
12921
|
+
for (const token of mergeSpacedAreas(raw2)) {
|
|
12922
|
+
if (token.kind !== "ref" && !(token.kind === "name" && token.prefix)) {
|
|
12923
|
+
literal2 += token.text;
|
|
12924
|
+
continue;
|
|
12925
|
+
}
|
|
12926
|
+
if (literal2) template.push(literal2);
|
|
12927
|
+
literal2 = "";
|
|
12928
|
+
const part = { kind: token.kind, text: token.text };
|
|
12929
|
+
if (token.prefix) {
|
|
12930
|
+
part.prefix = token.prefix;
|
|
12931
|
+
if (token.prefix.book === void 0) part.sheet = token.prefix.sheet.toLowerCase();
|
|
12932
|
+
}
|
|
12933
|
+
if (token.ref) part.ref = token.ref;
|
|
12934
|
+
if (token.spill) part.spill = true;
|
|
12935
|
+
template.push(part);
|
|
12965
12936
|
}
|
|
12966
|
-
if (
|
|
12967
|
-
token.text = rewrite(token, next);
|
|
12937
|
+
if (literal2) template.push(literal2);
|
|
12968
12938
|
}
|
|
12969
|
-
|
|
12939
|
+
remember2(formula, template);
|
|
12940
|
+
return template;
|
|
12970
12941
|
}
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
12976
|
-
|
|
12942
|
+
function rewriteTemplate(formula, rewrite2) {
|
|
12943
|
+
const template = templateOf(formula);
|
|
12944
|
+
if (!template) return formula;
|
|
12945
|
+
let next;
|
|
12946
|
+
for (let i2 = 0; i2 < template.length; i2++) {
|
|
12947
|
+
const part = template[i2];
|
|
12948
|
+
if (typeof part === "string") continue;
|
|
12949
|
+
const changed = rewrite2(part);
|
|
12950
|
+
if (!changed) continue;
|
|
12951
|
+
next ??= template.slice();
|
|
12952
|
+
next[i2] = changed;
|
|
12953
|
+
}
|
|
12954
|
+
if (!next) return formula;
|
|
12955
|
+
const text2 = next.map((part) => typeof part === "string" ? part : part.text).join("");
|
|
12956
|
+
remember2(text2, next);
|
|
12957
|
+
return text2;
|
|
12958
|
+
}
|
|
12959
|
+
function shiftInterval(a2, b, at2, count2, max) {
|
|
12960
|
+
if (count2 > 0) {
|
|
12961
|
+
const na2 = a2 >= at2 ? a2 + count2 : a2;
|
|
12962
|
+
const nb2 = b >= at2 ? b + count2 : b;
|
|
12963
|
+
if (nb2 > max) return na2 > max ? void 0 : [na2, max];
|
|
12964
|
+
return [na2, nb2];
|
|
12965
|
+
}
|
|
12966
|
+
const n = -count2;
|
|
12967
|
+
const last = at2 + n - 1;
|
|
12968
|
+
if (a2 >= at2 && b <= last) return void 0;
|
|
12969
|
+
const na = a2 < at2 ? a2 : a2 <= last ? at2 : a2 - n;
|
|
12970
|
+
const nb = b < at2 ? b : b <= last ? at2 - 1 : b - n;
|
|
12971
|
+
return [na, nb];
|
|
12972
|
+
}
|
|
12973
|
+
function shiftRef(ref, spec2) {
|
|
12974
|
+
const isRow = spec2.axis === "row";
|
|
12975
|
+
if (isRow && ref.kind === "cols" || !isRow && ref.kind === "rows") return ref;
|
|
12976
|
+
const startFirst = isRow ? ref.start.row <= ref.end.row : ref.start.col <= ref.end.col;
|
|
12977
|
+
const lo = startFirst ? ref.start : ref.end;
|
|
12978
|
+
const hi = startFirst ? ref.end : ref.start;
|
|
12979
|
+
const shifted2 = shiftInterval(
|
|
12980
|
+
isRow ? lo.row : lo.col,
|
|
12981
|
+
isRow ? hi.row : hi.col,
|
|
12982
|
+
spec2.at,
|
|
12983
|
+
spec2.count,
|
|
12984
|
+
isRow ? MAX_ROW : MAX_COL
|
|
12985
|
+
);
|
|
12986
|
+
if (!shifted2) return void 0;
|
|
12987
|
+
const [a2, b] = shifted2;
|
|
12988
|
+
const nlo = isRow ? { ...lo, row: a2 } : { ...lo, col: a2 };
|
|
12989
|
+
const nhi = isRow ? { ...hi, row: b } : { ...hi, col: b };
|
|
12990
|
+
const next = {
|
|
12991
|
+
kind: ref.kind,
|
|
12992
|
+
start: startFirst ? nlo : nhi,
|
|
12993
|
+
end: startFirst ? nhi : nlo
|
|
12994
|
+
};
|
|
12995
|
+
if (ref.kind === "cell") next.end = next.start;
|
|
12996
|
+
return sameSpec(next, ref) ? ref : next;
|
|
12997
|
+
}
|
|
12998
|
+
function shiftFormula(formula, formulaSheet, spec2) {
|
|
12999
|
+
if (spec2.count === 0) return formula;
|
|
13000
|
+
const sheet = spec2.sheet.toLowerCase();
|
|
13001
|
+
const own = formulaSheet.toLowerCase() === sheet;
|
|
13002
|
+
return rewriteTemplate(formula, (part) => {
|
|
13003
|
+
if (part.kind !== "ref" || !part.ref || (part.prefix ? part.sheet !== sheet : !own))
|
|
13004
|
+
return void 0;
|
|
13005
|
+
const next = shiftRef(part.ref, spec2);
|
|
13006
|
+
if (next === part.ref) return void 0;
|
|
13007
|
+
const out = { kind: "ref", text: rewriteRef(part, next) };
|
|
13008
|
+
if (part.prefix) out.prefix = part.prefix;
|
|
13009
|
+
if (part.sheet !== void 0) out.sheet = part.sheet;
|
|
13010
|
+
if (next) out.ref = next;
|
|
13011
|
+
if (part.spill) out.spill = true;
|
|
13012
|
+
return out;
|
|
13013
|
+
});
|
|
12977
13014
|
}
|
|
12978
13015
|
function renameSheetInFormula(formula, oldName, newName) {
|
|
12979
|
-
const tokens3 = safeTokens(formula);
|
|
12980
|
-
if (!tokens3) return formula;
|
|
12981
13016
|
const lower2 = oldName.toLowerCase();
|
|
12982
|
-
|
|
12983
|
-
const prefix =
|
|
12984
|
-
if (!prefix ||
|
|
12985
|
-
const first3 =
|
|
13017
|
+
return rewriteTemplate(formula, (part) => {
|
|
13018
|
+
const prefix = part.prefix;
|
|
13019
|
+
if (!prefix || part.sheet === void 0) return void 0;
|
|
13020
|
+
const first3 = part.sheet === lower2;
|
|
12986
13021
|
const second = prefix.sheet2?.toLowerCase() === lower2;
|
|
12987
|
-
if (!first3 && !second)
|
|
13022
|
+
if (!first3 && !second) return void 0;
|
|
12988
13023
|
const renamed = { ...prefix, sheet: first3 ? newName : prefix.sheet };
|
|
12989
13024
|
if (prefix.sheet2 !== void 0) renamed.sheet2 = second ? newName : prefix.sheet2;
|
|
12990
13025
|
const text2 = prefixText(renamed);
|
|
12991
|
-
token.text = text2 + token.text.slice(prefix.text.length);
|
|
12992
13026
|
renamed.text = text2;
|
|
12993
|
-
|
|
13027
|
+
const out = { ...part, text: text2 + part.text.slice(prefix.text.length) };
|
|
13028
|
+
out.prefix = renamed;
|
|
13029
|
+
out.sheet = renamed.sheet.toLowerCase();
|
|
13030
|
+
return out;
|
|
13031
|
+
});
|
|
13032
|
+
}
|
|
13033
|
+
|
|
13034
|
+
// xlsx/formula/transform.ts
|
|
13035
|
+
function translateFormula(formula, dRow, dCol) {
|
|
13036
|
+
const tokens3 = safeTokens(formula);
|
|
13037
|
+
if (!tokens3) return formula;
|
|
13038
|
+
for (const token of tokens3) {
|
|
13039
|
+
if (token.kind !== "ref" || !token.ref) continue;
|
|
13040
|
+
const spec2 = token.ref;
|
|
13041
|
+
const move = (c2) => {
|
|
13042
|
+
const row2 = spec2.kind === "cols" || c2.rowAbs ? c2.row : c2.row + dRow;
|
|
13043
|
+
const col = spec2.kind === "rows" || c2.colAbs ? c2.col : c2.col + dCol;
|
|
13044
|
+
if (row2 < 0 || row2 > MAX_ROW || col < 0 || col > MAX_COL) return void 0;
|
|
13045
|
+
return { ...c2, row: row2, col };
|
|
13046
|
+
};
|
|
13047
|
+
const start = move(spec2.start);
|
|
13048
|
+
const end = move(spec2.end);
|
|
13049
|
+
const next = start && end ? { kind: spec2.kind, start, end } : void 0;
|
|
13050
|
+
if (next && sameSpec(next, spec2)) continue;
|
|
13051
|
+
token.text = rewriteRef(token, next);
|
|
12994
13052
|
}
|
|
12995
13053
|
return joinTokens(tokens3);
|
|
12996
13054
|
}
|
|
@@ -13079,7 +13137,7 @@ var FUTURE_FUNCTIONS = new Set(
|
|
|
13079
13137
|
"AGGREGATE BETA.DIST BETA.INV BINOM.DIST BINOM.INV CEILING.PRECISE CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CONFIDENCE.NORM CONFIDENCE.T COVARIANCE.P COVARIANCE.S ERF.PRECISE ERFC.PRECISE EXPON.DIST F.DIST F.DIST.RT F.INV F.INV.RT F.TEST FLOOR.PRECISE GAMMA.DIST GAMMA.INV GAMMALN.PRECISE HYPGEOM.DIST LOGNORM.DIST LOGNORM.INV MODE.MULT MODE.SNGL NEGBINOM.DIST NETWORKDAYS.INTL NORM.DIST NORM.INV NORM.S.DIST NORM.S.INV PERCENTILE.EXC PERCENTILE.INC PERCENTRANK.EXC PERCENTRANK.INC POISSON.DIST QUARTILE.EXC QUARTILE.INC RANK.AVG RANK.EQ STDEV.P STDEV.S T.DIST T.DIST.2T T.DIST.RT T.INV T.INV.2T T.TEST VAR.P VAR.S WEIBULL.DIST WORKDAY.INTL ACOT ACOTH ARABIC BASE BINOM.DIST.RANGE BITAND BITLSHIFT BITOR BITRSHIFT BITXOR CEILING.MATH COMBINA COT COTH CSC CSCH DAYS DECIMAL ENCODEURL FILTERXML FLOOR.MATH FORMULATEXT GAMMA GAUSS IFNA IMCOSH IMCOT IMCSC IMCSCH IMSEC IMSECH IMSINH IMTAN ISFORMULA ISOWEEKNUM MUNIT NUMBERVALUE PDURATION PERMUTATIONA PHI RRI SEC SECH SHEET SHEETS SKEW.P UNICHAR UNICODE WEBSERVICE XOR CONCAT FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR IFS MAXIFS MINIFS SWITCH TEXTJOIN XLOOKUP XMATCH FILTER SORT SORTBY UNIQUE SEQUENCE RANDARRAY LET LAMBDA TEXTBEFORE TEXTAFTER TEXTSPLIT VSTACK HSTACK TAKE DROP CHOOSEROWS CHOOSECOLS TOCOL TOROW WRAPROWS WRAPCOLS EXPAND ARRAYTOTEXT VALUETOTEXT ISOMITTED BYROW BYCOL MAP REDUCE SCAN MAKEARRAY IMAGE GROUPBY PIVOTBY PERCENTOF REGEXTEST REGEXEXTRACT REGEXREPLACE TRIMRANGE ANCHORARRAY SINGLE STOCKHISTORY FIELDVALUE".split(" ")
|
|
13080
13138
|
);
|
|
13081
13139
|
var WORKSHEET_PREFIXED = /* @__PURE__ */ new Set(["FILTER", "SORT"]);
|
|
13082
|
-
function
|
|
13140
|
+
function rewrite(formula, visit2) {
|
|
13083
13141
|
const out = [];
|
|
13084
13142
|
let i2 = 0;
|
|
13085
13143
|
while (i2 < formula.length) {
|
|
@@ -13122,7 +13180,7 @@ function rewrite2(formula, visit2) {
|
|
|
13122
13180
|
}
|
|
13123
13181
|
function stripFuturePrefixes(formula) {
|
|
13124
13182
|
if (!formula.includes("_xl")) return formula;
|
|
13125
|
-
const plain2 =
|
|
13183
|
+
const plain2 = rewrite(formula, (token, next, out) => {
|
|
13126
13184
|
if (!next.startsWith("(")) return false;
|
|
13127
13185
|
const stripped = token.replace(/^(_xlfn\.)?(_xlws\.)?/i, "");
|
|
13128
13186
|
if (stripped === token) return false;
|
|
@@ -13132,7 +13190,7 @@ function stripFuturePrefixes(formula) {
|
|
|
13132
13190
|
return fromStoredSyntax(plain2);
|
|
13133
13191
|
}
|
|
13134
13192
|
function addFuturePrefixes(formula) {
|
|
13135
|
-
return
|
|
13193
|
+
return rewrite(toStoredSyntax(formula), (token, next, out) => {
|
|
13136
13194
|
if (!next.startsWith("(")) return false;
|
|
13137
13195
|
const upper2 = token.toUpperCase();
|
|
13138
13196
|
if (!FUTURE_FUNCTIONS.has(upper2)) return false;
|
|
@@ -13785,13 +13843,13 @@ function dataBarLengths(rule2, node) {
|
|
|
13785
13843
|
maxLength: rule2.maxLength ?? numAttr(bar, "maxLength") ?? 90
|
|
13786
13844
|
};
|
|
13787
13845
|
}
|
|
13788
|
-
function rewriteConditionalExtension(rule2,
|
|
13846
|
+
function rewriteConditionalExtension(rule2, rewrite2) {
|
|
13789
13847
|
if (!rule2.extensionXml) return;
|
|
13790
13848
|
const doc = parseXml(rule2.extensionXml);
|
|
13791
13849
|
let changed = false;
|
|
13792
13850
|
for (const formula of descendants3(doc.documentElement, "f", XM)) {
|
|
13793
13851
|
const before = formula.textContent ?? "";
|
|
13794
|
-
const next =
|
|
13852
|
+
const next = rewrite2(before);
|
|
13795
13853
|
if (before !== next) {
|
|
13796
13854
|
formula.textContent = next;
|
|
13797
13855
|
changed = true;
|
|
@@ -17024,7 +17082,9 @@ var PREC_INTERSECT = 9;
|
|
|
17024
17082
|
var PREC_RANGE = 10;
|
|
17025
17083
|
var OPERAND_START = /* @__PURE__ */ new Set(["ref", "name", "func", "open", "structured"]);
|
|
17026
17084
|
function parseFormula(formula) {
|
|
17027
|
-
|
|
17085
|
+
return parseTokens(tokenize(formula));
|
|
17086
|
+
}
|
|
17087
|
+
function parseTokens(all2) {
|
|
17028
17088
|
const tokens3 = [];
|
|
17029
17089
|
const wsBefore = [];
|
|
17030
17090
|
let sawWs = false;
|
|
@@ -17365,6 +17425,222 @@ function localDateToSerial(date, date1904 = date1904Mode) {
|
|
|
17365
17425
|
return base + (utc - dayStart) / DAY_MS2;
|
|
17366
17426
|
}
|
|
17367
17427
|
|
|
17428
|
+
// xlsx/formula/area-index.ts
|
|
17429
|
+
var BUCKET_WIDTH = 64;
|
|
17430
|
+
var CHUNK_SHIFT = 6;
|
|
17431
|
+
var CHUNKS = 64;
|
|
17432
|
+
function push(map, key2, value) {
|
|
17433
|
+
const list = map.get(key2);
|
|
17434
|
+
if (list) list.push(value);
|
|
17435
|
+
else map.set(key2, [value]);
|
|
17436
|
+
}
|
|
17437
|
+
function inner(map, sheet) {
|
|
17438
|
+
let found = map.get(sheet);
|
|
17439
|
+
if (!found) map.set(sheet, found = /* @__PURE__ */ new Map());
|
|
17440
|
+
return found;
|
|
17441
|
+
}
|
|
17442
|
+
var AreaIndex = class {
|
|
17443
|
+
cells = /* @__PURE__ */ new Map();
|
|
17444
|
+
chunked = /* @__PURE__ */ new Map();
|
|
17445
|
+
tall = /* @__PURE__ */ new Map();
|
|
17446
|
+
wide = /* @__PURE__ */ new Map();
|
|
17447
|
+
add(area, node) {
|
|
17448
|
+
const { start, end } = area.range;
|
|
17449
|
+
if (start.row === end.row && end.col - start.col + 1 <= BUCKET_WIDTH) {
|
|
17450
|
+
const cells3 = inner(this.cells, area.sheet);
|
|
17451
|
+
for (let col = start.col; col <= end.col; col++) push(cells3, cellKey(start.row, col), node);
|
|
17452
|
+
return;
|
|
17453
|
+
}
|
|
17454
|
+
const entry3 = { range: area.range, node };
|
|
17455
|
+
if (end.col - start.col + 1 > BUCKET_WIDTH) {
|
|
17456
|
+
const list = this.wide.get(area.sheet);
|
|
17457
|
+
if (list) list.push(entry3);
|
|
17458
|
+
else this.wide.set(area.sheet, [entry3]);
|
|
17459
|
+
return;
|
|
17460
|
+
}
|
|
17461
|
+
const first3 = start.row >> CHUNK_SHIFT;
|
|
17462
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
17463
|
+
if (last - first3 + 1 > CHUNKS) {
|
|
17464
|
+
const cols2 = inner(this.tall, area.sheet);
|
|
17465
|
+
for (let c2 = start.col; c2 <= end.col; c2++) push(cols2, c2, entry3);
|
|
17466
|
+
return;
|
|
17467
|
+
}
|
|
17468
|
+
const cols = inner(this.chunked, area.sheet);
|
|
17469
|
+
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
17470
|
+
let chunks = cols.get(c2);
|
|
17471
|
+
if (!chunks) cols.set(c2, chunks = /* @__PURE__ */ new Map());
|
|
17472
|
+
for (let k = first3; k <= last; k++) push(chunks, k, entry3);
|
|
17473
|
+
}
|
|
17474
|
+
}
|
|
17475
|
+
/** Items whose areas intersect `range` on `sheet` (each once). */
|
|
17476
|
+
dependents(sheet, range, out) {
|
|
17477
|
+
const found = out instanceof Set ? out : /* @__PURE__ */ new Set();
|
|
17478
|
+
this.collect(sheet, range, found);
|
|
17479
|
+
if (Array.isArray(out)) for (const node of found) out.push(node);
|
|
17480
|
+
}
|
|
17481
|
+
collect(sheet, range, out) {
|
|
17482
|
+
const { start, end } = range;
|
|
17483
|
+
const check3 = (list) => {
|
|
17484
|
+
if (list) {
|
|
17485
|
+
for (const entry3 of list) if (rangesIntersect(entry3.range, range)) out.add(entry3.node);
|
|
17486
|
+
}
|
|
17487
|
+
};
|
|
17488
|
+
const cells3 = this.cells.get(sheet);
|
|
17489
|
+
if (cells3) {
|
|
17490
|
+
const size = (end.row - start.row + 1) * (end.col - start.col + 1);
|
|
17491
|
+
if (size <= 4096) {
|
|
17492
|
+
for (let r = start.row; r <= end.row; r++) {
|
|
17493
|
+
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
17494
|
+
const list = cells3.get(cellKey(r, c2));
|
|
17495
|
+
if (list) for (const node of list) out.add(node);
|
|
17496
|
+
}
|
|
17497
|
+
}
|
|
17498
|
+
} else {
|
|
17499
|
+
for (const [key2, list] of cells3) {
|
|
17500
|
+
const { row: row2, col } = keyToAddress(key2);
|
|
17501
|
+
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
17502
|
+
for (const node of list) out.add(node);
|
|
17503
|
+
}
|
|
17504
|
+
}
|
|
17505
|
+
}
|
|
17506
|
+
const columns = (map, visit2) => {
|
|
17507
|
+
if (!map) return;
|
|
17508
|
+
if (end.col - start.col + 1 <= map.size) {
|
|
17509
|
+
for (let c2 = start.col; c2 <= end.col; c2++) if (map.has(c2)) visit2(c2);
|
|
17510
|
+
} else for (const c2 of map.keys()) if (c2 >= start.col && c2 <= end.col) visit2(c2);
|
|
17511
|
+
};
|
|
17512
|
+
const chunked = this.chunked.get(sheet);
|
|
17513
|
+
const first3 = start.row >> CHUNK_SHIFT;
|
|
17514
|
+
const last = end.row >> CHUNK_SHIFT;
|
|
17515
|
+
columns(chunked, (c2) => {
|
|
17516
|
+
const chunks = chunked?.get(c2);
|
|
17517
|
+
if (last - first3 + 1 <= chunks.size) {
|
|
17518
|
+
for (let k = first3; k <= last; k++) check3(chunks.get(k));
|
|
17519
|
+
} else for (const [k, list] of chunks) if (k >= first3 && k <= last) check3(list);
|
|
17520
|
+
});
|
|
17521
|
+
const tall = this.tall.get(sheet);
|
|
17522
|
+
columns(tall, (c2) => check3(tall?.get(c2)));
|
|
17523
|
+
check3(this.wide.get(sheet));
|
|
17524
|
+
}
|
|
17525
|
+
};
|
|
17526
|
+
|
|
17527
|
+
// xlsx/formula/graph-index.ts
|
|
17528
|
+
var ColumnIndex = class {
|
|
17529
|
+
sheets = /* @__PURE__ */ new Map();
|
|
17530
|
+
constructor(nodes) {
|
|
17531
|
+
for (const node of nodes) {
|
|
17532
|
+
let cols = this.sheets.get(node.sheet);
|
|
17533
|
+
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
17534
|
+
let list = cols.get(node.col);
|
|
17535
|
+
if (!list) cols.set(node.col, list = []);
|
|
17536
|
+
list.push(node);
|
|
17537
|
+
}
|
|
17538
|
+
for (const cols of this.sheets.values())
|
|
17539
|
+
for (const list of cols.values()) list.sort((a2, b) => a2.row - b.row);
|
|
17540
|
+
}
|
|
17541
|
+
nodesIn(area, out) {
|
|
17542
|
+
const cols = this.sheets.get(area.sheet);
|
|
17543
|
+
if (!cols) return;
|
|
17544
|
+
const { start, end } = area.range;
|
|
17545
|
+
const width = end.col - start.col + 1;
|
|
17546
|
+
const scan3 = (list) => {
|
|
17547
|
+
let lo = 0;
|
|
17548
|
+
let hi = list.length;
|
|
17549
|
+
while (lo < hi) {
|
|
17550
|
+
const mid = lo + hi >> 1;
|
|
17551
|
+
if (list[mid].row < start.row) lo = mid + 1;
|
|
17552
|
+
else hi = mid;
|
|
17553
|
+
}
|
|
17554
|
+
for (let i2 = lo; i2 < list.length; i2++) {
|
|
17555
|
+
const node = list[i2];
|
|
17556
|
+
if (node.row > end.row) break;
|
|
17557
|
+
out.push(node);
|
|
17558
|
+
}
|
|
17559
|
+
};
|
|
17560
|
+
if (width <= cols.size) {
|
|
17561
|
+
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
17562
|
+
const list = cols.get(c2);
|
|
17563
|
+
if (list) scan3(list);
|
|
17564
|
+
}
|
|
17565
|
+
} else {
|
|
17566
|
+
for (const [c2, list] of cols) if (c2 >= start.col && c2 <= end.col) scan3(list);
|
|
17567
|
+
}
|
|
17568
|
+
}
|
|
17569
|
+
};
|
|
17570
|
+
var ReverseIndex = class extends AreaIndex {
|
|
17571
|
+
constructor(nodes = []) {
|
|
17572
|
+
super();
|
|
17573
|
+
for (const node of nodes) this.addNode(node);
|
|
17574
|
+
}
|
|
17575
|
+
/** Indexes one more formula's precedents. */
|
|
17576
|
+
addNode(node) {
|
|
17577
|
+
for (const dep of node.deps) this.add(dep, node);
|
|
17578
|
+
for (const dep of node.dynamicDeps) this.add(dep, node);
|
|
17579
|
+
}
|
|
17580
|
+
};
|
|
17581
|
+
|
|
17582
|
+
// xlsx/formula/engine-prepare.ts
|
|
17583
|
+
var CHECK_EVERY = 32;
|
|
17584
|
+
var GraphPreparation = class {
|
|
17585
|
+
constructor(workbook, create) {
|
|
17586
|
+
this.workbook = workbook;
|
|
17587
|
+
this.create = create;
|
|
17588
|
+
}
|
|
17589
|
+
workbook;
|
|
17590
|
+
create;
|
|
17591
|
+
reverse = new ReverseIndex();
|
|
17592
|
+
formulas = { dynamic: [], unvalued: [] };
|
|
17593
|
+
sheet = 0;
|
|
17594
|
+
rows;
|
|
17595
|
+
row = 0;
|
|
17596
|
+
cells;
|
|
17597
|
+
finished = false;
|
|
17598
|
+
/**
|
|
17599
|
+
* Adds formulas to the graph until `timeRemaining` (milliseconds, as an idle deadline reports
|
|
17600
|
+
* them) reaches zero, or until every formula is in. Returns true when the graph is complete.
|
|
17601
|
+
*/
|
|
17602
|
+
run(timeRemaining) {
|
|
17603
|
+
let visited = 0;
|
|
17604
|
+
while (!this.finished) {
|
|
17605
|
+
const cells3 = this.cells ?? this.nextRow();
|
|
17606
|
+
if (!cells3) continue;
|
|
17607
|
+
const next = cells3.next();
|
|
17608
|
+
if (next.done) {
|
|
17609
|
+
this.cells = void 0;
|
|
17610
|
+
continue;
|
|
17611
|
+
}
|
|
17612
|
+
const [col, cell] = next.value;
|
|
17613
|
+
if (cell.formula) this.add(this.create(this.sheet, this.row, col, cell), cell);
|
|
17614
|
+
if (timeRemaining && ++visited % CHECK_EVERY === 0 && timeRemaining() <= 0) break;
|
|
17615
|
+
}
|
|
17616
|
+
return this.finished;
|
|
17617
|
+
}
|
|
17618
|
+
add(node, cell) {
|
|
17619
|
+
this.reverse.addNode(node);
|
|
17620
|
+
if (!node.legacy && !node.arrayRange) this.formulas.dynamic.push(node);
|
|
17621
|
+
if (cell.value === null && !node.keepCached) this.formulas.unvalued.push(node);
|
|
17622
|
+
}
|
|
17623
|
+
/** Moves to the next stored row (and sheet), or marks the walk finished. */
|
|
17624
|
+
nextRow() {
|
|
17625
|
+
for (; ; ) {
|
|
17626
|
+
const sheet = this.workbook.sheets[this.sheet];
|
|
17627
|
+
if (!sheet) {
|
|
17628
|
+
this.finished = true;
|
|
17629
|
+
return void 0;
|
|
17630
|
+
}
|
|
17631
|
+
this.rows ??= sheet.rows.entries();
|
|
17632
|
+
const next = this.rows.next();
|
|
17633
|
+
if (!next.done) {
|
|
17634
|
+
this.row = next.value[0];
|
|
17635
|
+
this.cells = next.value[1].entries();
|
|
17636
|
+
return this.cells;
|
|
17637
|
+
}
|
|
17638
|
+
this.rows = void 0;
|
|
17639
|
+
this.sheet++;
|
|
17640
|
+
}
|
|
17641
|
+
}
|
|
17642
|
+
};
|
|
17643
|
+
|
|
17368
17644
|
// xlsx/formula/text-number.ts
|
|
17369
17645
|
var MONTHS2 = [
|
|
17370
17646
|
"jan",
|
|
@@ -20499,8 +20775,10 @@ var FINANCIAL_FUNCTIONS = [
|
|
|
20499
20775
|
|
|
20500
20776
|
// xlsx/formula/references.ts
|
|
20501
20777
|
function sheetIndex(host, name) {
|
|
20778
|
+
const sheets = host.workbook.sheets;
|
|
20779
|
+
for (let i2 = 0; i2 < sheets.length; i2++) if (sheets[i2]?.name === name) return i2;
|
|
20502
20780
|
const lower2 = name.toLowerCase();
|
|
20503
|
-
return
|
|
20781
|
+
return sheets.findIndex((sheet) => sheet.name.toLowerCase() === lower2);
|
|
20504
20782
|
}
|
|
20505
20783
|
function prefixSheets(host, prefix, current) {
|
|
20506
20784
|
if (!prefix) return [current];
|
|
@@ -22114,9 +22392,9 @@ function readBlock(ctx, area, rows, cols) {
|
|
|
22114
22392
|
if (host.readBlock) return host.readBlock(area.sheet, range);
|
|
22115
22393
|
return Matrix.build(rows, cols, (r, c2) => ctx.readCell(area.sheet, row2 + r, col + c2));
|
|
22116
22394
|
}
|
|
22117
|
-
function shapedMatrices(ctx, values2,
|
|
22395
|
+
function shapedMatrices(ctx, values2, sameShape2) {
|
|
22118
22396
|
let { rows, cols } = shapeOf(values2[0] ?? null);
|
|
22119
|
-
if (
|
|
22397
|
+
if (sameShape2) {
|
|
22120
22398
|
for (const value of values2) {
|
|
22121
22399
|
const shape2 = shapeOf(value);
|
|
22122
22400
|
if (shape2.rows !== rows || shape2.cols !== cols) fail(ERR.VALUE);
|
|
@@ -22142,12 +22420,12 @@ function shapedMatrices(ctx, values2, sameShape) {
|
|
|
22142
22420
|
});
|
|
22143
22421
|
return { matrices, total: total2, block: rows * cols };
|
|
22144
22422
|
}
|
|
22145
|
-
function matchingCells(ctx, pairs, target,
|
|
22423
|
+
function matchingCells(ctx, pairs, target, sameShape2) {
|
|
22146
22424
|
const ranges = pairs.map((p) => p.range);
|
|
22147
22425
|
const { matrices, total: total2, block } = shapedMatrices(
|
|
22148
22426
|
ctx,
|
|
22149
22427
|
target === void 0 ? ranges : [...ranges, target],
|
|
22150
|
-
|
|
22428
|
+
sameShape2
|
|
22151
22429
|
);
|
|
22152
22430
|
const tests = pairs.map((p) => makeCriteria(scalar(p.criteria)));
|
|
22153
22431
|
const values2 = matrices[matrices.length - 1];
|
|
@@ -22186,7 +22464,7 @@ function indexedCandidates(pairs, matrices) {
|
|
|
22186
22464
|
}
|
|
22187
22465
|
return void 0;
|
|
22188
22466
|
}
|
|
22189
|
-
var matchingValues = (ctx, pairs, target,
|
|
22467
|
+
var matchingValues = (ctx, pairs, target, sameShape2) => matchingCells(ctx, pairs, target, sameShape2).values;
|
|
22190
22468
|
function criteriaPairs(args, from) {
|
|
22191
22469
|
if ((args.length - from) % 2 !== 0) fail(ERR.VALUE);
|
|
22192
22470
|
const pairs = [];
|
|
@@ -26080,7 +26358,7 @@ var REFERENCE_ARGUMENT = /* @__PURE__ */ new Set([
|
|
|
26080
26358
|
"AREAS",
|
|
26081
26359
|
"ISREF"
|
|
26082
26360
|
]);
|
|
26083
|
-
var
|
|
26361
|
+
var push2 = (c2, area) => {
|
|
26084
26362
|
(c2.dynamic > 0 ? c2.dynamicDeps : c2.deps).push(area);
|
|
26085
26363
|
};
|
|
26086
26364
|
function spans(areas) {
|
|
@@ -26106,7 +26384,7 @@ function visit(node, c2) {
|
|
|
26106
26384
|
if (!sheets) return;
|
|
26107
26385
|
const range = specRange(node.ref);
|
|
26108
26386
|
const target = node.spill ? { start: range.start, end: { ...range.start } } : range;
|
|
26109
|
-
for (const sheet of sheets)
|
|
26387
|
+
for (const sheet of sheets) push2(c2, { sheet, range: target });
|
|
26110
26388
|
return;
|
|
26111
26389
|
}
|
|
26112
26390
|
case "name": {
|
|
@@ -26180,7 +26458,7 @@ function visitBinary(node, c2) {
|
|
|
26180
26458
|
const list = c2.dynamic > 0 ? c2.dynamicDeps : c2.deps;
|
|
26181
26459
|
const l = list[list.length - 2];
|
|
26182
26460
|
const r = list[list.length - 1];
|
|
26183
|
-
if (l && r && l.sheet === r.sheet)
|
|
26461
|
+
if (l && r && l.sheet === r.sheet) push2(c2, spans([l, r])[0]);
|
|
26184
26462
|
continue;
|
|
26185
26463
|
}
|
|
26186
26464
|
const mentioned = [...c2.deps.slice(staticStart), ...c2.dynamicDeps.slice(dynamicStart)];
|
|
@@ -26196,7 +26474,7 @@ function addStructured(ref, c2) {
|
|
|
26196
26474
|
sheet: c2.sheet,
|
|
26197
26475
|
row: c2.row,
|
|
26198
26476
|
col: c2.col});
|
|
26199
|
-
if (value instanceof RefValue) for (const area of value.areas)
|
|
26477
|
+
if (value instanceof RefValue) for (const area of value.areas) push2(c2, area);
|
|
26200
26478
|
}
|
|
26201
26479
|
function analyze(ast, host, sheet, row2, col) {
|
|
26202
26480
|
const c2 = {
|
|
@@ -26220,155 +26498,191 @@ function analyze(ast, host, sheet, row2, col) {
|
|
|
26220
26498
|
};
|
|
26221
26499
|
}
|
|
26222
26500
|
|
|
26223
|
-
// xlsx/formula/
|
|
26224
|
-
var
|
|
26225
|
-
|
|
26226
|
-
|
|
26227
|
-
|
|
26228
|
-
|
|
26229
|
-
|
|
26230
|
-
|
|
26501
|
+
// xlsx/formula/formula-shape.ts
|
|
26502
|
+
var isDigit4 = (code) => code >= 48 && code <= 57;
|
|
26503
|
+
function formulaShape(formula) {
|
|
26504
|
+
const starts = [];
|
|
26505
|
+
const ends = [];
|
|
26506
|
+
let hash = 2166136261;
|
|
26507
|
+
for (let i2 = 0; i2 < formula.length; i2++) {
|
|
26508
|
+
let code = formula.charCodeAt(i2);
|
|
26509
|
+
if (isDigit4(code)) {
|
|
26510
|
+
let j = i2 + 1;
|
|
26511
|
+
while (j < formula.length && isDigit4(formula.charCodeAt(j))) j++;
|
|
26512
|
+
starts.push(i2);
|
|
26513
|
+
ends.push(j);
|
|
26514
|
+
i2 = j - 1;
|
|
26515
|
+
code = 0;
|
|
26516
|
+
}
|
|
26517
|
+
hash = Math.imul(hash ^ code, 16777619);
|
|
26518
|
+
}
|
|
26519
|
+
return { hash: hash >>> 0, starts, ends };
|
|
26231
26520
|
}
|
|
26232
|
-
function
|
|
26233
|
-
let
|
|
26234
|
-
|
|
26235
|
-
return
|
|
26521
|
+
function sameText(a2, from, b, at2, length) {
|
|
26522
|
+
for (let k = 0; k < length; k++)
|
|
26523
|
+
if (a2.charCodeAt(from + k) !== b.charCodeAt(at2 + k)) return false;
|
|
26524
|
+
return true;
|
|
26236
26525
|
}
|
|
26237
|
-
|
|
26238
|
-
|
|
26239
|
-
|
|
26240
|
-
|
|
26241
|
-
|
|
26242
|
-
|
|
26243
|
-
const
|
|
26244
|
-
|
|
26245
|
-
|
|
26246
|
-
|
|
26247
|
-
|
|
26526
|
+
function sameShape(a2, as, b, bs) {
|
|
26527
|
+
const runs = as.starts.length;
|
|
26528
|
+
if (runs !== bs.starts.length) return false;
|
|
26529
|
+
let fromA = 0;
|
|
26530
|
+
let fromB = 0;
|
|
26531
|
+
for (let i2 = 0; i2 <= runs; i2++) {
|
|
26532
|
+
const toA = i2 < runs ? as.starts[i2] : a2.length;
|
|
26533
|
+
const toB = i2 < runs ? bs.starts[i2] : b.length;
|
|
26534
|
+
if (toA - fromA !== toB - fromB || !sameText(a2, fromA, b, fromB, toA - fromA)) return false;
|
|
26535
|
+
fromA = as.ends[i2] ?? 0;
|
|
26536
|
+
fromB = bs.ends[i2] ?? 0;
|
|
26537
|
+
}
|
|
26538
|
+
return true;
|
|
26539
|
+
}
|
|
26540
|
+
function makeTemplate(formula, shape2) {
|
|
26541
|
+
let tokens3;
|
|
26542
|
+
let ast;
|
|
26543
|
+
try {
|
|
26544
|
+
tokens3 = tokenize(formula);
|
|
26545
|
+
ast = parseTokens(tokens3);
|
|
26546
|
+
} catch (e) {
|
|
26547
|
+
if (e instanceof RangeError) return new FormulaError(e.message, -1, "#VALUE!");
|
|
26548
|
+
if (e instanceof FormulaError) return e;
|
|
26549
|
+
throw e;
|
|
26550
|
+
}
|
|
26551
|
+
const { starts } = shape2;
|
|
26552
|
+
const slotted = starts.map(() => false);
|
|
26553
|
+
const refs = /* @__PURE__ */ new Map();
|
|
26554
|
+
let run2 = 0;
|
|
26555
|
+
for (const token of tokens3) {
|
|
26556
|
+
const end = token.start + token.text.length;
|
|
26557
|
+
const first3 = run2;
|
|
26558
|
+
while (run2 < starts.length && starts[run2] < end) run2++;
|
|
26559
|
+
const ref = token.kind === "ref" ? token.ref : void 0;
|
|
26560
|
+
if (!ref || ref.kind === "cols") continue;
|
|
26561
|
+
const count2 = ref.kind === "cell" ? 1 : 2;
|
|
26562
|
+
if (run2 - first3 < count2) continue;
|
|
26563
|
+
const at2 = run2 - count2;
|
|
26564
|
+
const indexes2 = count2 === 1 ? [at2] : [at2, at2 + 1];
|
|
26565
|
+
if (indexes2.some((i2) => formula.charCodeAt(starts[i2]) === 48)) continue;
|
|
26566
|
+
for (const i2 of indexes2) slotted[i2] = true;
|
|
26567
|
+
refs.set(ref, count2 === 1 ? { start: at2 } : { start: at2, end: at2 + 1 });
|
|
26568
|
+
}
|
|
26569
|
+
return { formula, shape: shape2, ast, slotted, refs };
|
|
26570
|
+
}
|
|
26571
|
+
function rowsFor(t, formula, shape2) {
|
|
26572
|
+
if (!sameShape(t.formula, t.shape, formula, shape2)) return void 0;
|
|
26573
|
+
const rows = [];
|
|
26574
|
+
for (let i2 = 0; i2 < shape2.starts.length; i2++) {
|
|
26575
|
+
const start = shape2.starts[i2];
|
|
26576
|
+
const length = shape2.ends[i2] - start;
|
|
26577
|
+
if (!t.slotted[i2]) {
|
|
26578
|
+
const own = t.shape.starts[i2];
|
|
26579
|
+
if (t.shape.ends[i2] - own !== length) return void 0;
|
|
26580
|
+
if (!sameText(t.formula, own, formula, start, length)) return void 0;
|
|
26581
|
+
rows.push(-1);
|
|
26582
|
+
continue;
|
|
26248
26583
|
}
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26252
|
-
|
|
26253
|
-
|
|
26254
|
-
|
|
26584
|
+
if (length > 7 || formula.charCodeAt(start) === 48) return void 0;
|
|
26585
|
+
let row2 = 0;
|
|
26586
|
+
for (let k = start; k < start + length; k++) row2 = row2 * 10 + formula.charCodeAt(k) - 48;
|
|
26587
|
+
if (row2 < 1 || row2 > MAX_ROW + 1) return void 0;
|
|
26588
|
+
rows.push(row2 - 1);
|
|
26589
|
+
}
|
|
26590
|
+
return rows;
|
|
26591
|
+
}
|
|
26592
|
+
function shiftSpec(spec2, slots, rows) {
|
|
26593
|
+
const startRow = rows[slots.start];
|
|
26594
|
+
const endRow = slots.end === void 0 ? startRow : rows[slots.end];
|
|
26595
|
+
if (startRow === spec2.start.row && endRow === spec2.end.row) return spec2;
|
|
26596
|
+
const { start: from, end: to } = spec2;
|
|
26597
|
+
const start = { row: startRow, col: from.col, rowAbs: from.rowAbs, colAbs: from.colAbs };
|
|
26598
|
+
if (slots.end === void 0) return { kind: spec2.kind, start, end: start };
|
|
26599
|
+
const end = { row: endRow, col: to.col, rowAbs: to.rowAbs, colAbs: to.colAbs };
|
|
26600
|
+
return { kind: spec2.kind, start, end };
|
|
26601
|
+
}
|
|
26602
|
+
function copyTree(node, t, rows) {
|
|
26603
|
+
switch (node.type) {
|
|
26604
|
+
case "ref": {
|
|
26605
|
+
const slots = node.ref ? t.refs.get(node.ref) : void 0;
|
|
26606
|
+
if (!slots || !node.ref) return node;
|
|
26607
|
+
const ref = shiftSpec(node.ref, slots, rows);
|
|
26608
|
+
if (ref === node.ref) return node;
|
|
26609
|
+
const copy2 = { type: "ref" };
|
|
26610
|
+
if (node.prefix) copy2.prefix = node.prefix;
|
|
26611
|
+
copy2.ref = ref;
|
|
26612
|
+
if (node.spill) copy2.spill = true;
|
|
26613
|
+
return copy2;
|
|
26255
26614
|
}
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
|
|
26259
|
-
|
|
26260
|
-
|
|
26261
|
-
return;
|
|
26615
|
+
case "unary":
|
|
26616
|
+
case "percent": {
|
|
26617
|
+
const operand4 = copyTree(node.operand, t, rows);
|
|
26618
|
+
if (operand4 === node.operand) return node;
|
|
26619
|
+
return node.type === "unary" ? { type: "unary", op: node.op, operand: operand4 } : { type: "percent", operand: operand4 };
|
|
26262
26620
|
}
|
|
26263
|
-
|
|
26264
|
-
|
|
26265
|
-
|
|
26266
|
-
if (
|
|
26267
|
-
|
|
26621
|
+
case "binary": {
|
|
26622
|
+
const left2 = copyTree(node.left, t, rows);
|
|
26623
|
+
const right2 = copyTree(node.right, t, rows);
|
|
26624
|
+
if (left2 === node.left && right2 === node.right) return node;
|
|
26625
|
+
return { type: "binary", op: node.op, left: left2, right: right2 };
|
|
26268
26626
|
}
|
|
26269
|
-
|
|
26270
|
-
|
|
26271
|
-
|
|
26272
|
-
|
|
26273
|
-
this.collect(sheet, range, found);
|
|
26274
|
-
if (Array.isArray(out)) for (const node of found) out.push(node);
|
|
26275
|
-
}
|
|
26276
|
-
collect(sheet, range, out) {
|
|
26277
|
-
const { start, end } = range;
|
|
26278
|
-
const check3 = (list) => {
|
|
26279
|
-
if (list) {
|
|
26280
|
-
for (const entry3 of list) if (rangesIntersect(entry3.range, range)) out.add(entry3.node);
|
|
26281
|
-
}
|
|
26282
|
-
};
|
|
26283
|
-
const cells3 = this.cells.get(sheet);
|
|
26284
|
-
if (cells3) {
|
|
26285
|
-
const size = (end.row - start.row + 1) * (end.col - start.col + 1);
|
|
26286
|
-
if (size <= 4096) {
|
|
26287
|
-
for (let r = start.row; r <= end.row; r++) {
|
|
26288
|
-
for (let c2 = start.col; c2 <= end.col; c2++) {
|
|
26289
|
-
const list = cells3.get(cellKey(r, c2));
|
|
26290
|
-
if (list) for (const node of list) out.add(node);
|
|
26291
|
-
}
|
|
26292
|
-
}
|
|
26293
|
-
} else {
|
|
26294
|
-
for (const [key2, list] of cells3) {
|
|
26295
|
-
const { row: row2, col } = keyToAddress(key2);
|
|
26296
|
-
if (row2 >= start.row && row2 <= end.row && col >= start.col && col <= end.col)
|
|
26297
|
-
for (const node of list) out.add(node);
|
|
26298
|
-
}
|
|
26299
|
-
}
|
|
26627
|
+
case "call": {
|
|
26628
|
+
const args = copyAll(node.args, t, rows);
|
|
26629
|
+
if (args === node.args) return node;
|
|
26630
|
+
return { type: "call", name: node.name, rawName: node.rawName, args };
|
|
26300
26631
|
}
|
|
26301
|
-
|
|
26302
|
-
|
|
26303
|
-
|
|
26304
|
-
|
|
26305
|
-
|
|
26306
|
-
};
|
|
26307
|
-
const chunked = this.chunked.get(sheet);
|
|
26308
|
-
const first3 = start.row >> CHUNK_SHIFT;
|
|
26309
|
-
const last = end.row >> CHUNK_SHIFT;
|
|
26310
|
-
columns(chunked, (c2) => {
|
|
26311
|
-
const chunks = chunked?.get(c2);
|
|
26312
|
-
if (last - first3 + 1 <= chunks.size) {
|
|
26313
|
-
for (let k = first3; k <= last; k++) check3(chunks.get(k));
|
|
26314
|
-
} else for (const [k, list] of chunks) if (k >= first3 && k <= last) check3(list);
|
|
26315
|
-
});
|
|
26316
|
-
const tall = this.tall.get(sheet);
|
|
26317
|
-
columns(tall, (c2) => check3(tall?.get(c2)));
|
|
26318
|
-
check3(this.wide.get(sheet));
|
|
26319
|
-
}
|
|
26320
|
-
};
|
|
26321
|
-
|
|
26322
|
-
// xlsx/formula/graph-index.ts
|
|
26323
|
-
var ColumnIndex = class {
|
|
26324
|
-
sheets = /* @__PURE__ */ new Map();
|
|
26325
|
-
constructor(nodes) {
|
|
26326
|
-
for (const node of nodes) {
|
|
26327
|
-
let cols = this.sheets.get(node.sheet);
|
|
26328
|
-
if (!cols) this.sheets.set(node.sheet, cols = /* @__PURE__ */ new Map());
|
|
26329
|
-
let list = cols.get(node.col);
|
|
26330
|
-
if (!list) cols.set(node.col, list = []);
|
|
26331
|
-
list.push(node);
|
|
26632
|
+
case "invoke": {
|
|
26633
|
+
const callee = copyTree(node.callee, t, rows);
|
|
26634
|
+
const args = copyAll(node.args, t, rows);
|
|
26635
|
+
if (callee === node.callee && args === node.args) return node;
|
|
26636
|
+
return { type: "invoke", callee, args };
|
|
26332
26637
|
}
|
|
26333
|
-
|
|
26334
|
-
|
|
26638
|
+
default:
|
|
26639
|
+
return node;
|
|
26335
26640
|
}
|
|
26336
|
-
|
|
26337
|
-
|
|
26338
|
-
|
|
26339
|
-
|
|
26340
|
-
const
|
|
26341
|
-
const
|
|
26342
|
-
|
|
26343
|
-
|
|
26344
|
-
|
|
26345
|
-
|
|
26346
|
-
|
|
26347
|
-
|
|
26348
|
-
|
|
26349
|
-
|
|
26350
|
-
|
|
26351
|
-
|
|
26352
|
-
|
|
26353
|
-
|
|
26354
|
-
|
|
26355
|
-
|
|
26356
|
-
|
|
26357
|
-
|
|
26358
|
-
|
|
26359
|
-
|
|
26360
|
-
|
|
26361
|
-
|
|
26362
|
-
|
|
26641
|
+
}
|
|
26642
|
+
function copyAll(nodes, t, rows) {
|
|
26643
|
+
let out;
|
|
26644
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
26645
|
+
const node = nodes[i2];
|
|
26646
|
+
const copy2 = copyTree(node, t, rows);
|
|
26647
|
+
if (copy2 !== node && !out) out = nodes.slice(0, i2);
|
|
26648
|
+
out?.push(copy2);
|
|
26649
|
+
}
|
|
26650
|
+
return out ?? nodes;
|
|
26651
|
+
}
|
|
26652
|
+
function fromTemplate(t, formula, shape2) {
|
|
26653
|
+
const rows = rowsFor(t, formula, shape2);
|
|
26654
|
+
return rows ? copyTree(t.ast, t, rows) : void 0;
|
|
26655
|
+
}
|
|
26656
|
+
|
|
26657
|
+
// xlsx/formula/parse-cache.ts
|
|
26658
|
+
var MAX_TEMPLATE_LENGTH = 2048;
|
|
26659
|
+
var MAX_ENTRIES = 1e5;
|
|
26660
|
+
var MAX_TEMPLATES2 = 1e4;
|
|
26661
|
+
var NO_RUNS = { hash: 0, starts: [], ends: [] };
|
|
26662
|
+
var treeOf = (made) => "ast" in made ? made.ast : made;
|
|
26663
|
+
var ParseCache = class {
|
|
26664
|
+
byText = /* @__PURE__ */ new Map();
|
|
26665
|
+
templates = /* @__PURE__ */ new Map();
|
|
26666
|
+
parse(formula) {
|
|
26667
|
+
let ast = this.byText.get(formula);
|
|
26668
|
+
if (ast) return ast;
|
|
26669
|
+
ast = this.parseNew(formula);
|
|
26670
|
+
if (this.byText.size > MAX_ENTRIES) this.byText.clear();
|
|
26671
|
+
this.byText.set(formula, ast);
|
|
26672
|
+
return ast;
|
|
26363
26673
|
}
|
|
26364
|
-
|
|
26365
|
-
|
|
26366
|
-
|
|
26367
|
-
|
|
26368
|
-
|
|
26369
|
-
|
|
26370
|
-
|
|
26674
|
+
parseNew(formula) {
|
|
26675
|
+
if (formula.length > MAX_TEMPLATE_LENGTH) return treeOf(makeTemplate(formula, NO_RUNS));
|
|
26676
|
+
const shape2 = formulaShape(formula);
|
|
26677
|
+
const template = this.templates.get(shape2.hash);
|
|
26678
|
+
const reused = template && fromTemplate(template, formula, shape2);
|
|
26679
|
+
if (reused) return reused;
|
|
26680
|
+
const made = makeTemplate(formula, shape2);
|
|
26681
|
+
if (!template && "ast" in made) {
|
|
26682
|
+
if (this.templates.size > MAX_TEMPLATES2) this.templates.clear();
|
|
26683
|
+
this.templates.set(shape2.hash, made);
|
|
26371
26684
|
}
|
|
26685
|
+
return treeOf(made);
|
|
26372
26686
|
}
|
|
26373
26687
|
};
|
|
26374
26688
|
|
|
@@ -26508,7 +26822,7 @@ var EngineHost = class {
|
|
|
26508
26822
|
options;
|
|
26509
26823
|
nodes = /* @__PURE__ */ new Map();
|
|
26510
26824
|
footprints = /* @__PURE__ */ new Set();
|
|
26511
|
-
|
|
26825
|
+
parsed = new ParseCache();
|
|
26512
26826
|
boundsCache = /* @__PURE__ */ new Map();
|
|
26513
26827
|
inProgress = /* @__PURE__ */ new Set();
|
|
26514
26828
|
cycles = /* @__PURE__ */ new Set();
|
|
@@ -26532,6 +26846,8 @@ var EngineHost = class {
|
|
|
26532
26846
|
evaluations = 0;
|
|
26533
26847
|
built = false;
|
|
26534
26848
|
needsFull = false;
|
|
26849
|
+
/** No recalculation has run since the workbook was opened: stored values may stand. */
|
|
26850
|
+
fresh = true;
|
|
26535
26851
|
// ---- EvalHost ----
|
|
26536
26852
|
readCell(sheet, row2, col) {
|
|
26537
26853
|
const cell = this.workbook.sheets[sheet]?.rows.get(row2)?.get(col);
|
|
@@ -26620,19 +26936,7 @@ var EngineHost = class {
|
|
|
26620
26936
|
return this.workbook.sheets[sheet]?.rows.get(row2)?.get(col)?.formula;
|
|
26621
26937
|
}
|
|
26622
26938
|
parse(formula) {
|
|
26623
|
-
|
|
26624
|
-
if (!ast) {
|
|
26625
|
-
try {
|
|
26626
|
-
ast = parseFormula(formula);
|
|
26627
|
-
} catch (e) {
|
|
26628
|
-
if (e instanceof RangeError) ast = new FormulaError(e.message, -1, "#VALUE!");
|
|
26629
|
-
else if (!(e instanceof FormulaError)) throw e;
|
|
26630
|
-
else ast = e;
|
|
26631
|
-
}
|
|
26632
|
-
if (this.astCache.size > 1e5) this.astCache.clear();
|
|
26633
|
-
this.astCache.set(formula, ast);
|
|
26634
|
-
}
|
|
26635
|
-
return ast;
|
|
26939
|
+
return this.parsed.parse(formula);
|
|
26636
26940
|
}
|
|
26637
26941
|
now() {
|
|
26638
26942
|
return this.options.now ? this.options.now() : /* @__PURE__ */ new Date();
|
|
@@ -26641,20 +26945,6 @@ var EngineHost = class {
|
|
|
26641
26945
|
return this.options.random ? this.options.random() : Math.random();
|
|
26642
26946
|
}
|
|
26643
26947
|
// ---- graph ----
|
|
26644
|
-
build() {
|
|
26645
|
-
this.nodes.clear();
|
|
26646
|
-
this.footprints.clear();
|
|
26647
|
-
this.footprintIndex = void 0;
|
|
26648
|
-
this.workbook.sheets.forEach((sheet, s) => {
|
|
26649
|
-
for (const [row2, cells3] of sheet.rows) {
|
|
26650
|
-
for (const [col, cell] of cells3) {
|
|
26651
|
-
if (cell.formula) this.createNode(s, row2, col, cell, true);
|
|
26652
|
-
}
|
|
26653
|
-
}
|
|
26654
|
-
});
|
|
26655
|
-
this.built = true;
|
|
26656
|
-
this.graphChanged();
|
|
26657
|
-
}
|
|
26658
26948
|
createNode(sheet, row2, col, cell, initial) {
|
|
26659
26949
|
const formula = cell.formula ?? "";
|
|
26660
26950
|
const parsed = this.parse(formula);
|
|
@@ -26683,6 +26973,14 @@ var EngineHost = class {
|
|
|
26683
26973
|
map.set(cellKey(row2, col), node);
|
|
26684
26974
|
return node;
|
|
26685
26975
|
}
|
|
26976
|
+
/** Parses a node's text again after a structural edit rewrote it (see `FormulaNode.stale`). */
|
|
26977
|
+
refreshAst(node) {
|
|
26978
|
+
const parsed = this.parse(node.formula);
|
|
26979
|
+
delete node.stale;
|
|
26980
|
+
delete node.parseError;
|
|
26981
|
+
node.ast = parsed instanceof FormulaError ? void 0 : parsed;
|
|
26982
|
+
if (parsed instanceof FormulaError && parsed.code) node.parseError = err(parsed.code);
|
|
26983
|
+
}
|
|
26686
26984
|
removeNode(node, changed) {
|
|
26687
26985
|
const sheet = this.workbook.sheets[node.sheet];
|
|
26688
26986
|
if (node.spill && sheet) {
|
|
@@ -27113,6 +27411,7 @@ var EngineCore = class extends EngineHost {
|
|
|
27113
27411
|
return { host: this, sheet, row: row2, col, scope: void 0, depth: 0, root, legacy };
|
|
27114
27412
|
}
|
|
27115
27413
|
evaluateFormula(node) {
|
|
27414
|
+
if (node.stale) this.refreshAst(node);
|
|
27116
27415
|
if (!node.ast) return node.parseError ?? ERR.NAME;
|
|
27117
27416
|
const ast = node.ast;
|
|
27118
27417
|
const frame = this.frameFor(node.sheet, node.row, node.col, ast, node.legacy);
|
|
@@ -27130,20 +27429,363 @@ var EngineCore = class extends EngineHost {
|
|
|
27130
27429
|
}
|
|
27131
27430
|
};
|
|
27132
27431
|
|
|
27432
|
+
// xlsx/formula/shift-graph.ts
|
|
27433
|
+
var POSITIONAL = /* @__PURE__ */ new Set(["ROW", "COLUMN"]);
|
|
27434
|
+
var DESCRIPTIVE = /* @__PURE__ */ new Set(["FORMULATEXT", "CELL", "SHEET"]);
|
|
27435
|
+
var traitsCache = /* @__PURE__ */ new WeakMap();
|
|
27436
|
+
function astTraits(ast) {
|
|
27437
|
+
const cached3 = traitsCache.get(ast);
|
|
27438
|
+
if (cached3) return cached3;
|
|
27439
|
+
const sheets = /* @__PURE__ */ new Set();
|
|
27440
|
+
const traits = { complex: false, opaque: false, positional: false, descriptive: false, sheets };
|
|
27441
|
+
const stack2 = [ast];
|
|
27442
|
+
while (stack2.length) {
|
|
27443
|
+
const node = stack2.pop();
|
|
27444
|
+
switch (node.type) {
|
|
27445
|
+
case "ref":
|
|
27446
|
+
if (node.prefix) {
|
|
27447
|
+
sheets.add(node.prefix.sheet.toLowerCase());
|
|
27448
|
+
if (node.prefix.sheet2 !== void 0) {
|
|
27449
|
+
sheets.add(node.prefix.sheet2.toLowerCase());
|
|
27450
|
+
traits.complex = true;
|
|
27451
|
+
}
|
|
27452
|
+
}
|
|
27453
|
+
break;
|
|
27454
|
+
case "name":
|
|
27455
|
+
if (node.prefix) sheets.add(node.prefix.sheet.toLowerCase());
|
|
27456
|
+
traits.complex = true;
|
|
27457
|
+
break;
|
|
27458
|
+
case "structured":
|
|
27459
|
+
traits.complex = true;
|
|
27460
|
+
break;
|
|
27461
|
+
case "unary":
|
|
27462
|
+
case "percent":
|
|
27463
|
+
stack2.push(node.operand);
|
|
27464
|
+
break;
|
|
27465
|
+
case "binary":
|
|
27466
|
+
stack2.push(node.left, node.right);
|
|
27467
|
+
break;
|
|
27468
|
+
case "call":
|
|
27469
|
+
if (POSITIONAL.has(node.name)) traits.positional = true;
|
|
27470
|
+
if (DESCRIPTIVE.has(node.name)) traits.descriptive = true;
|
|
27471
|
+
if (!getFunction(node.name)) traits.complex = traits.opaque = true;
|
|
27472
|
+
stack2.push(...node.args);
|
|
27473
|
+
break;
|
|
27474
|
+
case "invoke":
|
|
27475
|
+
stack2.push(node.callee, ...node.args);
|
|
27476
|
+
break;
|
|
27477
|
+
}
|
|
27478
|
+
}
|
|
27479
|
+
traitsCache.set(ast, traits);
|
|
27480
|
+
return traits;
|
|
27481
|
+
}
|
|
27482
|
+
function intervalDelta(a2, b, shift2) {
|
|
27483
|
+
const { at: at2, count: count2 } = shift2;
|
|
27484
|
+
if (count2 > 0) {
|
|
27485
|
+
if (b < at2) return 0;
|
|
27486
|
+
if (a2 < at2) return void 0;
|
|
27487
|
+
return b + count2 > (shift2.axis === "row" ? MAX_ROW : MAX_COL) ? void 0 : count2;
|
|
27488
|
+
}
|
|
27489
|
+
const last = at2 - count2 - 1;
|
|
27490
|
+
if (b < at2) return 0;
|
|
27491
|
+
if (a2 > last) return count2;
|
|
27492
|
+
return void 0;
|
|
27493
|
+
}
|
|
27494
|
+
function areaDelta(area, sheet, shift2) {
|
|
27495
|
+
if (area.sheet !== sheet) return 0;
|
|
27496
|
+
const { start, end } = area.range;
|
|
27497
|
+
return shift2.axis === "row" ? intervalDelta(start.row, end.row, shift2) : intervalDelta(start.col, end.col, shift2);
|
|
27498
|
+
}
|
|
27499
|
+
function movedRange(range, axis, delta) {
|
|
27500
|
+
if (delta === 0) return range;
|
|
27501
|
+
return axis === "row" ? {
|
|
27502
|
+
start: { row: range.start.row + delta, col: range.start.col },
|
|
27503
|
+
end: { row: range.end.row + delta, col: range.end.col }
|
|
27504
|
+
} : {
|
|
27505
|
+
start: { row: range.start.row, col: range.start.col + delta },
|
|
27506
|
+
end: { row: range.end.row, col: range.end.col + delta }
|
|
27507
|
+
};
|
|
27508
|
+
}
|
|
27509
|
+
function reachesEdit(areas, sheet, shift2) {
|
|
27510
|
+
for (const area of areas) {
|
|
27511
|
+
if (area.sheet !== sheet) continue;
|
|
27512
|
+
if ((shift2.axis === "row" ? area.range.end.row : area.range.end.col) >= shift2.at) return true;
|
|
27513
|
+
}
|
|
27514
|
+
return false;
|
|
27515
|
+
}
|
|
27516
|
+
function intersectionMoves(area, delta, pos, nodeDelta, axis) {
|
|
27517
|
+
if (delta === nodeDelta) return false;
|
|
27518
|
+
const { start, end } = area.range;
|
|
27519
|
+
const a2 = axis === "row" ? start.row : start.col;
|
|
27520
|
+
const b = axis === "row" ? end.row : end.col;
|
|
27521
|
+
if (a2 === b) return false;
|
|
27522
|
+
return pos >= a2 && pos <= b || pos + nodeDelta >= a2 + delta && pos + nodeDelta <= b + delta;
|
|
27523
|
+
}
|
|
27524
|
+
|
|
27525
|
+
// xlsx/formula/engine-structure.ts
|
|
27526
|
+
var sameAreas = (a2, b) => a2.length === b.length && a2.every((x, i2) => {
|
|
27527
|
+
const y = b[i2];
|
|
27528
|
+
return x.sheet === y.sheet && sameRange(x.range, y.range);
|
|
27529
|
+
});
|
|
27530
|
+
var EngineStructure = class extends EngineCore {
|
|
27531
|
+
/** Formulas a structural edit left to recalculate (with their dependents) on the next pass. */
|
|
27532
|
+
structuralSeeds = /* @__PURE__ */ new Set();
|
|
27533
|
+
/** Whether the graph describes the workbook as it was before the edit just reported. */
|
|
27534
|
+
graphReady() {
|
|
27535
|
+
return this.built && !this.needsFull;
|
|
27536
|
+
}
|
|
27537
|
+
/** Parses a node's current text again and recomputes its precedents. */
|
|
27538
|
+
reanalyze(node) {
|
|
27539
|
+
const parsed = this.parse(node.formula);
|
|
27540
|
+
delete node.stale;
|
|
27541
|
+
delete node.parseError;
|
|
27542
|
+
if (parsed instanceof FormulaError) {
|
|
27543
|
+
node.ast = void 0;
|
|
27544
|
+
if (parsed.code) node.parseError = err(parsed.code);
|
|
27545
|
+
node.deps = [];
|
|
27546
|
+
node.dynamicDeps = [];
|
|
27547
|
+
return;
|
|
27548
|
+
}
|
|
27549
|
+
node.ast = parsed;
|
|
27550
|
+
const found = analyze(parsed, this, node.sheet, node.row, node.col);
|
|
27551
|
+
node.deps = found.deps;
|
|
27552
|
+
node.dynamicDeps = found.dynamicDeps;
|
|
27553
|
+
node.volatile = found.volatile;
|
|
27554
|
+
node.unsupported = found.unsupported;
|
|
27555
|
+
}
|
|
27556
|
+
/**
|
|
27557
|
+
* Moves the graph for rows or columns inserted or deleted on `sheet`, after the workbook was
|
|
27558
|
+
* changed (cells moved, formulas rewritten). Spills on the sheet, array formulas the edit cuts
|
|
27559
|
+
* and anything unexpected fall back to a rebuild on the next recalculation.
|
|
27560
|
+
*/
|
|
27561
|
+
shiftCells(sheet, shift2) {
|
|
27562
|
+
if (!this.graphReady() || !this.shiftable(sheet, shift2)) {
|
|
27563
|
+
this.invalidate();
|
|
27564
|
+
return;
|
|
27565
|
+
}
|
|
27566
|
+
const ws = this.workbook.sheets[sheet];
|
|
27567
|
+
const own = this.nodes.get(sheet);
|
|
27568
|
+
if (!ws) return;
|
|
27569
|
+
const moved = /* @__PURE__ */ new Map();
|
|
27570
|
+
if (own) {
|
|
27571
|
+
const next = /* @__PURE__ */ new Map();
|
|
27572
|
+
for (const node of own.values()) {
|
|
27573
|
+
const pos = shift2.axis === "row" ? node.row : node.col;
|
|
27574
|
+
const delta = intervalDelta(pos, pos, shift2);
|
|
27575
|
+
if (delta === void 0) {
|
|
27576
|
+
this.dropNode(node);
|
|
27577
|
+
continue;
|
|
27578
|
+
}
|
|
27579
|
+
if (delta !== 0) {
|
|
27580
|
+
moved.set(node, delta);
|
|
27581
|
+
if (shift2.axis === "row") node.row += delta;
|
|
27582
|
+
else node.col += delta;
|
|
27583
|
+
}
|
|
27584
|
+
next.set(cellKey(node.row, node.col), node);
|
|
27585
|
+
}
|
|
27586
|
+
this.nodes.set(sheet, next);
|
|
27587
|
+
}
|
|
27588
|
+
for (const map of this.nodes.values())
|
|
27589
|
+
for (const node of map.values()) {
|
|
27590
|
+
if (!this.shiftNode(node, sheet, shift2, moved.get(node) ?? 0)) {
|
|
27591
|
+
this.invalidate();
|
|
27592
|
+
return;
|
|
27593
|
+
}
|
|
27594
|
+
}
|
|
27595
|
+
this.boundsCache.clear();
|
|
27596
|
+
this.graphChanged();
|
|
27597
|
+
}
|
|
27598
|
+
/** No spill or stale spilled value on the sheet, and no array formula the edit cuts. */
|
|
27599
|
+
shiftable(sheet, shift2) {
|
|
27600
|
+
for (const node of this.footprints) {
|
|
27601
|
+
if (node.sheet !== sheet) continue;
|
|
27602
|
+
if (node.spill || node.blockedSpill) return false;
|
|
27603
|
+
if (node.arrayRange && areaDelta({ sheet, range: node.arrayRange }, sheet, shift2) === void 0)
|
|
27604
|
+
return false;
|
|
27605
|
+
}
|
|
27606
|
+
const ws = this.workbook.sheets[sheet];
|
|
27607
|
+
let spilled = false;
|
|
27608
|
+
ws?.rows.forEach((cells3) => {
|
|
27609
|
+
if (!spilled) cells3.forEach((cell) => spilled ||= isSpilledCell(cell));
|
|
27610
|
+
});
|
|
27611
|
+
return !spilled;
|
|
27612
|
+
}
|
|
27613
|
+
dropNode(node) {
|
|
27614
|
+
this.structuralSeeds.delete(node);
|
|
27615
|
+
this.cycles.delete(node);
|
|
27616
|
+
this.footprints.delete(node);
|
|
27617
|
+
}
|
|
27618
|
+
/** Updates one formula for the edit; false when the graph cannot follow it. */
|
|
27619
|
+
shiftNode(node, sheet, shift2, nodeDelta) {
|
|
27620
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
27621
|
+
if (cell?.formula === void 0) return false;
|
|
27622
|
+
if (node.arrayRange) {
|
|
27623
|
+
const delta = areaDelta({ sheet: node.sheet, range: node.arrayRange }, sheet, shift2);
|
|
27624
|
+
if (delta === void 0) return false;
|
|
27625
|
+
node.arrayRange = movedRange(node.arrayRange, shift2.axis, delta);
|
|
27626
|
+
if (!cell.arrayRange || !sameRange(node.arrayRange, normalizeRange(cell.arrayRange)))
|
|
27627
|
+
return false;
|
|
27628
|
+
}
|
|
27629
|
+
const changed = cell.formula !== node.formula;
|
|
27630
|
+
const traits = node.ast && astTraits(node.ast);
|
|
27631
|
+
const reached = reachesEdit(node.deps, sheet, shift2) || reachesEdit(node.dynamicDeps, sheet, shift2);
|
|
27632
|
+
if (!changed && !reached && nodeDelta === 0 && !traits?.descriptive && !traits?.opaque)
|
|
27633
|
+
return true;
|
|
27634
|
+
if (traits?.complex) {
|
|
27635
|
+
node.formula = cell.formula;
|
|
27636
|
+
this.reanalyze(node);
|
|
27637
|
+
this.structuralSeeds.add(node);
|
|
27638
|
+
return true;
|
|
27639
|
+
}
|
|
27640
|
+
const pos = shift2.axis === "row" ? node.row - nodeDelta : node.col - nodeDelta;
|
|
27641
|
+
const moves = { seed: !!traits?.descriptive, moved: false, cut: false };
|
|
27642
|
+
const deps = this.moveAreas(node.deps, sheet, shift2, pos, nodeDelta, moves);
|
|
27643
|
+
const dynamicDeps = this.moveAreas(node.dynamicDeps, sheet, shift2, pos, nodeDelta, moves);
|
|
27644
|
+
const { cut, moved: anyMoved } = moves;
|
|
27645
|
+
let seed = moves.seed;
|
|
27646
|
+
if (cut || changed !== anyMoved) {
|
|
27647
|
+
node.formula = cell.formula;
|
|
27648
|
+
this.reanalyze(node);
|
|
27649
|
+
this.structuralSeeds.add(node);
|
|
27650
|
+
return true;
|
|
27651
|
+
}
|
|
27652
|
+
if (traits?.positional && (anyMoved || nodeDelta !== 0)) seed = true;
|
|
27653
|
+
node.deps = deps;
|
|
27654
|
+
node.dynamicDeps = dynamicDeps;
|
|
27655
|
+
if (changed) {
|
|
27656
|
+
node.formula = cell.formula;
|
|
27657
|
+
node.stale = true;
|
|
27658
|
+
}
|
|
27659
|
+
if (seed) this.structuralSeeds.add(node);
|
|
27660
|
+
return true;
|
|
27661
|
+
}
|
|
27662
|
+
/**
|
|
27663
|
+
* Areas moved for the edit (the same list when none moves). Records in `moves` whether one
|
|
27664
|
+
* moved, one was cut (deleted, widened, pushed off the grid) and whether implicit intersection
|
|
27665
|
+
* with one can now pick another cell.
|
|
27666
|
+
*/
|
|
27667
|
+
moveAreas(list, sheet, shift2, pos, nodeDelta, moves) {
|
|
27668
|
+
let out;
|
|
27669
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
27670
|
+
const area = list[i2];
|
|
27671
|
+
const delta = areaDelta(area, sheet, shift2);
|
|
27672
|
+
if (delta === void 0) {
|
|
27673
|
+
moves.cut = true;
|
|
27674
|
+
continue;
|
|
27675
|
+
}
|
|
27676
|
+
if (intersectionMoves(area, delta, pos, nodeDelta, shift2.axis)) moves.seed = true;
|
|
27677
|
+
if (delta === 0) continue;
|
|
27678
|
+
moves.moved = true;
|
|
27679
|
+
out ??= list.slice();
|
|
27680
|
+
out[i2] = { sheet: area.sheet, range: movedRange(area.range, shift2.axis, delta) };
|
|
27681
|
+
}
|
|
27682
|
+
return out ?? list;
|
|
27683
|
+
}
|
|
27684
|
+
/**
|
|
27685
|
+
* Follows a sheet rename (`from` to `to`, formulas already rewritten): precedents are kept by
|
|
27686
|
+
* sheet index, so only rewritten formulas need their text parsed again, and only formulas that
|
|
27687
|
+
* name the new sheet without having been rewritten (previously unresolved), describe sheets
|
|
27688
|
+
* (CELL, SHEET, FORMULATEXT) or read defined names whose areas changed are recalculated.
|
|
27689
|
+
*/
|
|
27690
|
+
renameSheet(from, to) {
|
|
27691
|
+
if (!this.graphReady()) {
|
|
27692
|
+
this.invalidate();
|
|
27693
|
+
return;
|
|
27694
|
+
}
|
|
27695
|
+
const target = to.toLowerCase();
|
|
27696
|
+
let depsChanged = false;
|
|
27697
|
+
for (const map of this.nodes.values())
|
|
27698
|
+
for (const node of map.values()) {
|
|
27699
|
+
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
27700
|
+
if (cell?.formula === void 0) {
|
|
27701
|
+
this.invalidate();
|
|
27702
|
+
return;
|
|
27703
|
+
}
|
|
27704
|
+
const changed = cell.formula !== node.formula;
|
|
27705
|
+
const traits = node.ast && astTraits(node.ast);
|
|
27706
|
+
node.formula = cell.formula;
|
|
27707
|
+
if (traits?.complex || !changed && traits?.sheets.has(target)) {
|
|
27708
|
+
const deps = node.deps;
|
|
27709
|
+
const dynamicDeps = node.dynamicDeps;
|
|
27710
|
+
this.reanalyze(node);
|
|
27711
|
+
const same5 = sameAreas(deps, node.deps) && sameAreas(dynamicDeps, node.dynamicDeps);
|
|
27712
|
+
if (!same5) depsChanged = true;
|
|
27713
|
+
if (!same5 || !traits?.complex) this.structuralSeeds.add(node);
|
|
27714
|
+
} else if (changed) node.stale = true;
|
|
27715
|
+
if (traits?.descriptive || traits?.opaque) this.structuralSeeds.add(node);
|
|
27716
|
+
}
|
|
27717
|
+
if (depsChanged) this.graphChanged();
|
|
27718
|
+
}
|
|
27719
|
+
/** Takes the formulas queued by structural edits. */
|
|
27720
|
+
takeStructuralSeeds(into) {
|
|
27721
|
+
for (const node of this.structuralSeeds)
|
|
27722
|
+
if (this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node) into.add(node);
|
|
27723
|
+
this.structuralSeeds.clear();
|
|
27724
|
+
}
|
|
27725
|
+
};
|
|
27726
|
+
|
|
27133
27727
|
// xlsx/formula/engine.ts
|
|
27134
|
-
var Engine = class extends
|
|
27728
|
+
var Engine = class extends EngineStructure {
|
|
27729
|
+
preparation;
|
|
27730
|
+
/** The prepared formulas the first recalculation checks (see `trustsStoredValues`). */
|
|
27731
|
+
prepared;
|
|
27732
|
+
// ---- the graph ----
|
|
27733
|
+
prepare(timeRemaining) {
|
|
27734
|
+
if (this.built || this.needsFull) return true;
|
|
27735
|
+
this.preparation ??= this.startPreparation();
|
|
27736
|
+
if (!this.preparation.run(timeRemaining)) return false;
|
|
27737
|
+
this.finishPreparation(this.preparation);
|
|
27738
|
+
return true;
|
|
27739
|
+
}
|
|
27740
|
+
discardPreparation() {
|
|
27741
|
+
if (!this.fresh || this.needsFull) return;
|
|
27742
|
+
this.preparation = void 0;
|
|
27743
|
+
this.prepared = void 0;
|
|
27744
|
+
this.structuralSeeds.clear();
|
|
27745
|
+
this.nodes.clear();
|
|
27746
|
+
this.footprints.clear();
|
|
27747
|
+
this.graphChanged();
|
|
27748
|
+
this.built = false;
|
|
27749
|
+
}
|
|
27750
|
+
/** Completes the graph, continuing a preparation that is under way. */
|
|
27751
|
+
build() {
|
|
27752
|
+
const preparation = this.preparation ?? this.startPreparation();
|
|
27753
|
+
preparation.run();
|
|
27754
|
+
this.finishPreparation(preparation);
|
|
27755
|
+
}
|
|
27756
|
+
startPreparation() {
|
|
27757
|
+
this.nodes.clear();
|
|
27758
|
+
this.footprints.clear();
|
|
27759
|
+
this.footprintIndex = void 0;
|
|
27760
|
+
this.prepared = void 0;
|
|
27761
|
+
return new GraphPreparation(
|
|
27762
|
+
this.workbook,
|
|
27763
|
+
(s, row2, col, cell) => this.createNode(s, row2, col, cell, true)
|
|
27764
|
+
);
|
|
27765
|
+
}
|
|
27766
|
+
finishPreparation(preparation) {
|
|
27767
|
+
this.preparation = void 0;
|
|
27768
|
+
this.built = true;
|
|
27769
|
+
this.graphChanged();
|
|
27770
|
+
this.reverseIndex = preparation.reverse;
|
|
27771
|
+
this.prepared = preparation.formulas;
|
|
27772
|
+
}
|
|
27135
27773
|
// ---- recalculation ----
|
|
27136
27774
|
recalculateAll() {
|
|
27775
|
+
this.fresh = false;
|
|
27776
|
+
this.prepared = void 0;
|
|
27137
27777
|
if (this.needsFull) this.releaseAllSpills();
|
|
27138
27778
|
if (!this.built || this.needsFull) this.build();
|
|
27139
27779
|
this.needsFull = false;
|
|
27780
|
+
this.structuralSeeds.clear();
|
|
27140
27781
|
this.cycles = /* @__PURE__ */ new Set();
|
|
27141
27782
|
this.run(new Set(this.allNodes()), true);
|
|
27142
27783
|
}
|
|
27143
27784
|
recalculateFrom(changes) {
|
|
27144
27785
|
const seeds = /* @__PURE__ */ new Set();
|
|
27145
|
-
if (
|
|
27146
|
-
this.
|
|
27786
|
+
if (this.fresh && !this.needsFull) {
|
|
27787
|
+
this.fresh = false;
|
|
27788
|
+
if (!this.built) this.build();
|
|
27147
27789
|
if (!this.trustsStoredValues(changes, seeds)) {
|
|
27148
27790
|
this.recalculateAll();
|
|
27149
27791
|
return;
|
|
@@ -27187,6 +27829,7 @@ var Engine = class extends EngineCore {
|
|
|
27187
27829
|
}
|
|
27188
27830
|
}
|
|
27189
27831
|
if (structural) this.graphChanged();
|
|
27832
|
+
this.takeStructuralSeeds(seeds);
|
|
27190
27833
|
const reverse2 = this.reverse();
|
|
27191
27834
|
for (const area of changed) reverse2.dependents(area.sheet, area.range, seeds);
|
|
27192
27835
|
for (const node of this.allNodes()) if (node.volatile) seeds.add(node);
|
|
@@ -27198,13 +27841,18 @@ var Engine = class extends EngineCore {
|
|
|
27198
27841
|
* without a value into `missing`.
|
|
27199
27842
|
*/
|
|
27200
27843
|
trustsStoredValues(changes, missing) {
|
|
27844
|
+
const prepared = this.prepared;
|
|
27845
|
+
this.prepared = void 0;
|
|
27846
|
+
if (!prepared) return false;
|
|
27201
27847
|
const changed = new Set(changes.map((c2) => `${c2.sheet}:${cellKey(c2.row, c2.col)}`));
|
|
27202
|
-
|
|
27203
|
-
|
|
27204
|
-
if (
|
|
27848
|
+
const current = (node) => this.nodes.get(node.sheet)?.get(cellKey(node.row, node.col)) === node;
|
|
27849
|
+
for (const node of prepared.dynamic) {
|
|
27850
|
+
if (current(node) && !changed.has(`${node.sheet}:${cellKey(node.row, node.col)}`))
|
|
27205
27851
|
return false;
|
|
27852
|
+
}
|
|
27853
|
+
for (const node of prepared.unvalued) {
|
|
27206
27854
|
const cell = this.workbook.sheets[node.sheet]?.rows.get(node.row)?.get(node.col);
|
|
27207
|
-
if (cell && cell.value === null
|
|
27855
|
+
if (current(node) && cell && cell.value === null) missing.add(node);
|
|
27208
27856
|
}
|
|
27209
27857
|
return true;
|
|
27210
27858
|
}
|
|
@@ -27218,7 +27866,10 @@ var Engine = class extends EngineCore {
|
|
|
27218
27866
|
return !!anchor?.spill && rangeHas(anchor.spill, row2, col);
|
|
27219
27867
|
}
|
|
27220
27868
|
invalidate() {
|
|
27869
|
+
this.structuralSeeds.clear();
|
|
27221
27870
|
this.releaseAllSpills();
|
|
27871
|
+
this.preparation = void 0;
|
|
27872
|
+
this.prepared = void 0;
|
|
27222
27873
|
this.nodes.clear();
|
|
27223
27874
|
this.footprints.clear();
|
|
27224
27875
|
this.graphChanged();
|
|
@@ -30149,13 +30800,13 @@ function linearTrend(values2) {
|
|
|
30149
30800
|
const slope = den ? num3 / den : 0;
|
|
30150
30801
|
return (k) => Number((meanY + slope * (k - meanX)).toPrecision(15));
|
|
30151
30802
|
}
|
|
30152
|
-
var
|
|
30803
|
+
var isDigit5 = (ch) => ch !== void 0 && ch >= "0" && ch <= "9";
|
|
30153
30804
|
function matchTextNumber(text2) {
|
|
30154
30805
|
let end = text2.length;
|
|
30155
|
-
while (end > 0 && !
|
|
30806
|
+
while (end > 0 && !isDigit5(text2[end - 1])) end--;
|
|
30156
30807
|
if (end === 0) return null;
|
|
30157
30808
|
let start = end;
|
|
30158
|
-
while (start > 0 &&
|
|
30809
|
+
while (start > 0 && isDigit5(text2[start - 1])) start--;
|
|
30159
30810
|
return [text2, text2.slice(0, start), text2.slice(start, end), text2.slice(end)];
|
|
30160
30811
|
}
|
|
30161
30812
|
var QUARTER = /^(q|qtr|quarter)(\s?)([1-4])$/i;
|
|
@@ -30338,10 +30989,10 @@ function removeValidationArea(rules, area) {
|
|
|
30338
30989
|
}
|
|
30339
30990
|
|
|
30340
30991
|
// xlsx/edit/conditional-formulas.ts
|
|
30341
|
-
function rewriteConditionalRule(rule2,
|
|
30992
|
+
function rewriteConditionalRule(rule2, rewrite2) {
|
|
30342
30993
|
const safe2 = (formula) => {
|
|
30343
30994
|
try {
|
|
30344
|
-
return
|
|
30995
|
+
return rewrite2(formula);
|
|
30345
30996
|
} catch {
|
|
30346
30997
|
return formula;
|
|
30347
30998
|
}
|
|
@@ -30860,7 +31511,7 @@ function shiftPreservedXml(sheet, shift2, moveRange, banded) {
|
|
|
30860
31511
|
(xml) => xml.includes("sqref")
|
|
30861
31512
|
);
|
|
30862
31513
|
}
|
|
30863
|
-
function rewritePreservedFormulas(sheet,
|
|
31514
|
+
function rewritePreservedFormulas(sheet, rewrite2) {
|
|
30864
31515
|
editEntries(
|
|
30865
31516
|
sheet,
|
|
30866
31517
|
"extLst",
|
|
@@ -30870,7 +31521,7 @@ function rewritePreservedFormulas(sheet, rewrite3) {
|
|
|
30870
31521
|
const text2 = f6.textContent ?? "";
|
|
30871
31522
|
let next = text2;
|
|
30872
31523
|
try {
|
|
30873
|
-
next =
|
|
31524
|
+
next = rewrite2(text2, sheet.name);
|
|
30874
31525
|
} catch {
|
|
30875
31526
|
next = text2;
|
|
30876
31527
|
}
|
|
@@ -30885,46 +31536,46 @@ function rewritePreservedFormulas(sheet, rewrite3) {
|
|
|
30885
31536
|
}
|
|
30886
31537
|
|
|
30887
31538
|
// xlsx/edit/shift-formulas.ts
|
|
30888
|
-
function safe(
|
|
31539
|
+
function safe(rewrite2, formula, formulaSheet) {
|
|
30889
31540
|
try {
|
|
30890
|
-
return
|
|
31541
|
+
return rewrite2(formula, formulaSheet);
|
|
30891
31542
|
} catch {
|
|
30892
31543
|
return formula;
|
|
30893
31544
|
}
|
|
30894
31545
|
}
|
|
30895
|
-
function rewriteFormulas(workbook,
|
|
30896
|
-
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet,
|
|
31546
|
+
function rewriteFormulas(workbook, rewrite2) {
|
|
31547
|
+
for (const sheet of workbook.sheets) rewriteSheetFormulas(sheet, rewrite2);
|
|
30897
31548
|
for (const definedName of workbook.definedNames) {
|
|
30898
31549
|
const local = definedName.localSheet === void 0 ? void 0 : workbook.sheets[definedName.localSheet];
|
|
30899
|
-
definedName.formula = safe(
|
|
31550
|
+
definedName.formula = safe(rewrite2, definedName.formula, local?.name ?? "");
|
|
30900
31551
|
}
|
|
30901
31552
|
}
|
|
30902
|
-
function rewriteSheetFormulas(sheet,
|
|
30903
|
-
rewritePreservedFormulas(sheet,
|
|
31553
|
+
function rewriteSheetFormulas(sheet, rewrite2) {
|
|
31554
|
+
rewritePreservedFormulas(sheet, rewrite2);
|
|
30904
31555
|
{
|
|
30905
31556
|
const name = sheet.name;
|
|
30906
31557
|
for (const table2 of sheet.tables)
|
|
30907
31558
|
for (const column of table2.columns)
|
|
30908
31559
|
if (column.calculatedColumnFormula !== void 0)
|
|
30909
|
-
column.calculatedColumnFormula = safe(
|
|
31560
|
+
column.calculatedColumnFormula = safe(rewrite2, column.calculatedColumnFormula, name);
|
|
30910
31561
|
for (const cells3 of sheet.rows.values())
|
|
30911
31562
|
for (const cell of cells3.values())
|
|
30912
|
-
if (cell.formula !== void 0) cell.formula = safe(
|
|
31563
|
+
if (cell.formula !== void 0) cell.formula = safe(rewrite2, cell.formula, name);
|
|
30913
31564
|
for (const cf of sheet.conditionalFormats)
|
|
30914
|
-
for (const rule2 of cf.rules) rewriteConditionalRule(rule2, (f6) =>
|
|
31565
|
+
for (const rule2 of cf.rules) rewriteConditionalRule(rule2, (f6) => rewrite2(f6, name));
|
|
30915
31566
|
for (const dv of sheet.dataValidations) {
|
|
30916
|
-
if (dv.formula1 !== void 0) dv.formula1 = safe(
|
|
30917
|
-
if (dv.formula2 !== void 0) dv.formula2 = safe(
|
|
31567
|
+
if (dv.formula1 !== void 0) dv.formula1 = safe(rewrite2, dv.formula1, name);
|
|
31568
|
+
if (dv.formula2 !== void 0) dv.formula2 = safe(rewrite2, dv.formula2, name);
|
|
30918
31569
|
}
|
|
30919
31570
|
for (const link of sheet.hyperlinks)
|
|
30920
31571
|
if (link.location && /![A-Za-z$]/.test(link.location))
|
|
30921
|
-
link.location = safe(
|
|
31572
|
+
link.location = safe(rewrite2, link.location, name);
|
|
30922
31573
|
for (const drawing of sheet.drawings) {
|
|
30923
31574
|
if (drawing.kind !== "chart") continue;
|
|
30924
31575
|
for (const series of drawing.series) {
|
|
30925
|
-
if (series.nameRef) series.nameRef = safe(
|
|
30926
|
-
if (series.categoriesRef) series.categoriesRef = safe(
|
|
30927
|
-
if (series.valuesRef) series.valuesRef = safe(
|
|
31576
|
+
if (series.nameRef) series.nameRef = safe(rewrite2, series.nameRef, name);
|
|
31577
|
+
if (series.categoriesRef) series.categoriesRef = safe(rewrite2, series.categoriesRef, name);
|
|
31578
|
+
if (series.valuesRef) series.valuesRef = safe(rewrite2, series.valuesRef, name);
|
|
30928
31579
|
}
|
|
30929
31580
|
}
|
|
30930
31581
|
}
|
|
@@ -31111,7 +31762,7 @@ function shiftAxis(ctx, s, axis, at2, count2, insert) {
|
|
|
31111
31762
|
applyAxisShift(ctx, sheet, shift2);
|
|
31112
31763
|
if (insert) inheritFormats(sheet, axis, at2, count2);
|
|
31113
31764
|
},
|
|
31114
|
-
{ sheet: s, structural: true }
|
|
31765
|
+
{ sheet: s, structural: true, calc: { kind: "shift", sheet: s, shift: shift2 } }
|
|
31115
31766
|
);
|
|
31116
31767
|
}
|
|
31117
31768
|
var insertRows = (ctx, s, at2, count2) => shiftAxis(ctx, s, "row", at2, count2, true);
|
|
@@ -32925,6 +33576,14 @@ function setCalcMode(ctx, mode) {
|
|
|
32925
33576
|
|
|
32926
33577
|
// xlsx/edit/session-calc.ts
|
|
32927
33578
|
var isStructural = (step) => step.structural || step.entries.some((entry3) => entry3.before.kind !== "cells");
|
|
33579
|
+
function hintFor(step, mode) {
|
|
33580
|
+
const hint = step.calc;
|
|
33581
|
+
if (!hint) return void 0;
|
|
33582
|
+
if (hint.kind === "rename")
|
|
33583
|
+
return mode === "undo" ? { kind: "rename", from: hint.to, to: hint.from } : hint;
|
|
33584
|
+
return mode === "undo" ? void 0 : hint;
|
|
33585
|
+
}
|
|
33586
|
+
var settingsOf = (workbook) => `${workbook.iterate ? `${workbook.iterate.count}:${workbook.iterate.delta}` : ""}|${workbook.date1904}`;
|
|
32928
33587
|
var SessionCalculator = class {
|
|
32929
33588
|
constructor(workbook, calc, enabled2) {
|
|
32930
33589
|
this.workbook = workbook;
|
|
@@ -32934,43 +33593,113 @@ var SessionCalculator = class {
|
|
|
32934
33593
|
workbook;
|
|
32935
33594
|
calc;
|
|
32936
33595
|
enabled;
|
|
32937
|
-
/** Structural edits
|
|
33596
|
+
/** Structural edits the engine could not follow leave the dependency graph stale (manual mode). */
|
|
32938
33597
|
staleGraph = false;
|
|
33598
|
+
/** Cells changed in manual mode since the last calculation. */
|
|
33599
|
+
dirty = [];
|
|
33600
|
+
/** The settings at the last calculation; undefined before the first. */
|
|
33601
|
+
calculated;
|
|
32939
33602
|
/** Recalculates after an applied, undone or redone step (failures become warnings). */
|
|
32940
|
-
afterStep(step) {
|
|
32941
|
-
if (!this.enabled)
|
|
33603
|
+
afterStep(step, mode = "apply") {
|
|
33604
|
+
if (!this.enabled) {
|
|
33605
|
+
this.calc.discardPreparation();
|
|
33606
|
+
return;
|
|
33607
|
+
}
|
|
33608
|
+
const structural = isStructural(step);
|
|
33609
|
+
const hint = structural ? hintFor(step, mode) : void 0;
|
|
32942
33610
|
if (calcModeOf(this.workbook) === "manual") {
|
|
32943
|
-
if (
|
|
33611
|
+
if (hint && !this.staleGraph && !this.dirty.length) {
|
|
33612
|
+
this.guard(() => this.follow(hint));
|
|
33613
|
+
return;
|
|
33614
|
+
}
|
|
33615
|
+
this.calc.discardPreparation();
|
|
33616
|
+
if (structural) this.staleGraph = true;
|
|
33617
|
+
else this.dirty.push(...touchedCells(step));
|
|
32944
33618
|
return;
|
|
32945
33619
|
}
|
|
32946
|
-
|
|
33620
|
+
if (hint && !this.staleGraph) {
|
|
33621
|
+
this.guard(() => {
|
|
33622
|
+
this.follow(hint);
|
|
33623
|
+
this.calc.recalculateFrom(touchedCells(step));
|
|
33624
|
+
this.calculated = settingsOf(this.workbook);
|
|
33625
|
+
});
|
|
33626
|
+
return;
|
|
33627
|
+
}
|
|
33628
|
+
this.recalc(structural, () => touchedCells(step));
|
|
32947
33629
|
}
|
|
32948
33630
|
/** Recalculates after a change applied outside the history (a collaborator's edit). */
|
|
32949
33631
|
afterExternal(structural, cells3) {
|
|
32950
|
-
if (!this.enabled)
|
|
32951
|
-
|
|
33632
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual") {
|
|
33633
|
+
this.calc.discardPreparation();
|
|
33634
|
+
if (!this.enabled) return;
|
|
32952
33635
|
if (structural) this.staleGraph = true;
|
|
33636
|
+
else this.dirty.push(...cells3);
|
|
32953
33637
|
return;
|
|
32954
33638
|
}
|
|
32955
33639
|
this.recalc(structural, () => cells3);
|
|
32956
33640
|
}
|
|
32957
|
-
|
|
33641
|
+
follow(hint) {
|
|
33642
|
+
if (hint.kind === "shift") this.calc.shiftCells(hint.sheet, hint.shift);
|
|
33643
|
+
else this.calc.renameSheet(hint.from, hint.to);
|
|
33644
|
+
}
|
|
33645
|
+
guard(run2) {
|
|
32958
33646
|
try {
|
|
33647
|
+
run2();
|
|
33648
|
+
} catch (error) {
|
|
33649
|
+
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
33650
|
+
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
33651
|
+
}
|
|
33652
|
+
}
|
|
33653
|
+
/** Builds the dependency graph ahead of the first edit (see `EditSession.prepareCalculation`). */
|
|
33654
|
+
prepare(timeRemaining) {
|
|
33655
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return true;
|
|
33656
|
+
try {
|
|
33657
|
+
return this.calc.prepare(timeRemaining);
|
|
33658
|
+
} catch {
|
|
33659
|
+
this.calc.discardPreparation();
|
|
33660
|
+
return true;
|
|
33661
|
+
}
|
|
33662
|
+
}
|
|
33663
|
+
/**
|
|
33664
|
+
* Before a structural edit the graph can follow in place: finishes a graph being prepared (or
|
|
33665
|
+
* builds it) while it still matches the workbook, so the edit moves it instead of rebuilding.
|
|
33666
|
+
*/
|
|
33667
|
+
beforeStructural() {
|
|
33668
|
+
if (!this.enabled || calcModeOf(this.workbook) === "manual" || this.staleGraph) return;
|
|
33669
|
+
this.prepare();
|
|
33670
|
+
}
|
|
33671
|
+
recalc(structural, cells3) {
|
|
33672
|
+
this.guard(() => {
|
|
32959
33673
|
if (this.staleGraph || structural) this.full();
|
|
32960
33674
|
else {
|
|
32961
33675
|
const changed = cells3();
|
|
32962
33676
|
if (changed.length) this.calc.recalculateFrom(changed);
|
|
33677
|
+
this.calculated = settingsOf(this.workbook);
|
|
32963
33678
|
}
|
|
32964
|
-
}
|
|
32965
|
-
const message = `Recalculation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
32966
|
-
if (!this.workbook.warnings.includes(message)) this.workbook.warnings.push(message);
|
|
32967
|
-
}
|
|
33679
|
+
});
|
|
32968
33680
|
}
|
|
32969
|
-
/** Rebuilds the dependency graph and recalculates every formula (F9). */
|
|
33681
|
+
/** Rebuilds the dependency graph and recalculates every formula (Ctrl+Alt+F9). */
|
|
32970
33682
|
full() {
|
|
32971
33683
|
this.staleGraph = false;
|
|
33684
|
+
this.dirty = [];
|
|
32972
33685
|
this.calc.invalidate();
|
|
32973
33686
|
this.calc.recalculateAll();
|
|
33687
|
+
this.calculated = settingsOf(this.workbook);
|
|
33688
|
+
}
|
|
33689
|
+
/**
|
|
33690
|
+
* Calculate Now (F9): the cells changed since the last calculation, the formulas structural
|
|
33691
|
+
* edits queued, their dependents and the volatile functions. Everything when `full`, before
|
|
33692
|
+
* the session's first calculation, after the iteration settings changed or while the graph
|
|
33693
|
+
* is stale.
|
|
33694
|
+
*/
|
|
33695
|
+
now(full) {
|
|
33696
|
+
if (full || this.staleGraph || this.calculated !== settingsOf(this.workbook)) {
|
|
33697
|
+
this.full();
|
|
33698
|
+
return;
|
|
33699
|
+
}
|
|
33700
|
+
const changed = this.dirty;
|
|
33701
|
+
this.dirty = [];
|
|
33702
|
+
this.calc.recalculateFrom(changed);
|
|
32974
33703
|
}
|
|
32975
33704
|
/**
|
|
32976
33705
|
* Recalculates one sheet's formulas and their dependents (Shift+F9); after structural edits
|
|
@@ -36774,12 +37503,12 @@ function renameSheet(ctx, index2, name) {
|
|
|
36774
37503
|
ctx.run(
|
|
36775
37504
|
"Rename sheet",
|
|
36776
37505
|
"sheets",
|
|
36777
|
-
[{ kind: "
|
|
37506
|
+
[{ kind: "refs" }],
|
|
36778
37507
|
() => {
|
|
36779
37508
|
rewriteFormulas(workbook, (formula) => renameSheetInFormula(formula, old, name));
|
|
36780
37509
|
sheet.name = name;
|
|
36781
37510
|
},
|
|
36782
|
-
{ sheet: index2, structural: true }
|
|
37511
|
+
{ sheet: index2, structural: true, calc: { kind: "rename", from: old, to: name } }
|
|
36783
37512
|
);
|
|
36784
37513
|
}
|
|
36785
37514
|
function moveSheet(ctx, from, to) {
|
|
@@ -37155,13 +37884,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
37155
37884
|
for (const listener of [...listeners]) listener(change);
|
|
37156
37885
|
};
|
|
37157
37886
|
const calculator = new SessionCalculator(workbook, calc, autoRecalc);
|
|
37158
|
-
const recalc = (step) => calculator.afterStep(step);
|
|
37159
|
-
const begin = (label2, kind, info) =>
|
|
37160
|
-
step
|
|
37161
|
-
|
|
37162
|
-
sheet: info.sheet,
|
|
37163
|
-
|
|
37164
|
-
});
|
|
37887
|
+
const recalc = (step, mode = "apply") => calculator.afterStep(step, mode);
|
|
37888
|
+
const begin = (label2, kind, info) => {
|
|
37889
|
+
const step = { label: label2, entries: [], structural: info.structural ?? false };
|
|
37890
|
+
if (info.calc) step.calc = info.calc;
|
|
37891
|
+
return { step, kind, sheet: info.sheet, ranges: [...info.ranges ?? []] };
|
|
37892
|
+
};
|
|
37165
37893
|
const finish = (current) => {
|
|
37166
37894
|
if (!current.step.entries.length) return;
|
|
37167
37895
|
history.push(current.step);
|
|
@@ -37186,10 +37914,12 @@ function createEditSession(workbook, options = {}) {
|
|
|
37186
37914
|
const outer = !open;
|
|
37187
37915
|
const current = open ?? begin(label2, kind, info);
|
|
37188
37916
|
if (!outer) {
|
|
37917
|
+
delete current.step.calc;
|
|
37189
37918
|
if (info.structural) current.step.structural = true;
|
|
37190
37919
|
if (current.sheet === void 0 && info.sheet !== void 0) current.sheet = info.sheet;
|
|
37191
37920
|
current.ranges.push(...info.ranges ?? []);
|
|
37192
37921
|
}
|
|
37922
|
+
if (outer && info.calc) calculator.beforeStructural();
|
|
37193
37923
|
open = current;
|
|
37194
37924
|
const mark = current.step.entries.length;
|
|
37195
37925
|
const befores = scopes.map((scope) => captureScope(workbook, scope));
|
|
@@ -37237,7 +37967,7 @@ function createEditSession(workbook, options = {}) {
|
|
|
37237
37967
|
if (open) throw new Error(`Cannot ${kind} inside a batch`);
|
|
37238
37968
|
const step = kind === "undo" ? history.undo(workbook) : history.redo(workbook);
|
|
37239
37969
|
if (!step) return false;
|
|
37240
|
-
recalc(step);
|
|
37970
|
+
recalc(step, kind);
|
|
37241
37971
|
emit({ kind, label: step.label, structural: step.structural });
|
|
37242
37972
|
return true;
|
|
37243
37973
|
};
|
|
@@ -37316,10 +38046,11 @@ function createEditSession(workbook, options = {}) {
|
|
|
37316
38046
|
setDocumentProperties: (patch) => setDocumentProperties(ctx, patch),
|
|
37317
38047
|
setAutoRecalc: (enabled2) => setCalcMode(ctx, enabled2 ? "auto" : "manual"),
|
|
37318
38048
|
autoRecalc: () => autoRecalc && calcModeOf(workbook) === "auto",
|
|
37319
|
-
calculateNow() {
|
|
37320
|
-
calculator.full
|
|
38049
|
+
calculateNow(options2) {
|
|
38050
|
+
calculator.now(options2?.full ?? false);
|
|
37321
38051
|
emit({ kind: "cells", label: "Calculate now", structural: false });
|
|
37322
38052
|
},
|
|
38053
|
+
prepareCalculation: (opts) => calculator.prepare(opts?.timeRemaining),
|
|
37323
38054
|
calculateSheet(s) {
|
|
37324
38055
|
calculator.sheet(s);
|
|
37325
38056
|
emit({ kind: "cells", label: "Calculate sheet", sheet: s, structural: false });
|
|
@@ -45907,11 +46638,11 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check3) {
|
|
|
45907
46638
|
}
|
|
45908
46639
|
const tops = children3(children3(root, "Shapes")[0], "Shape");
|
|
45909
46640
|
if (tops.length !== 1) problem("Only a uniquely rooted master can prove independence.");
|
|
45910
|
-
const
|
|
46641
|
+
const templates2 = masterShapes(root), context = /* @__PURE__ */ new Map();
|
|
45911
46642
|
assertMasterMarkup(
|
|
45912
46643
|
root,
|
|
45913
46644
|
new Set(
|
|
45914
|
-
|
|
46645
|
+
templates2.flatMap((shape2) => {
|
|
45915
46646
|
charge();
|
|
45916
46647
|
return [...masterCells(shape2, charge).values()];
|
|
45917
46648
|
})
|
|
@@ -45933,7 +46664,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check3) {
|
|
|
45933
46664
|
if (byTemplate.has(id)) problem("MasterShape mappings are ambiguous.");
|
|
45934
46665
|
byTemplate.set(id, local);
|
|
45935
46666
|
}
|
|
45936
|
-
for (const template of
|
|
46667
|
+
for (const template of templates2) {
|
|
45937
46668
|
charge();
|
|
45938
46669
|
if (bindings.length >= 1e4) problem("Master effective binding limit exceeded.");
|
|
45939
46670
|
check3();
|