@borgar/fx 4.12.0 → 5.0.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/index-BMr6cTgc.d.cts +1444 -0
- package/dist/index-BMr6cTgc.d.ts +1444 -0
- package/dist/index.cjs +3054 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2984 -0
- package/dist/index.js.map +1 -0
- package/dist/xlsx/index.cjs +3120 -0
- package/dist/xlsx/index.cjs.map +1 -0
- package/dist/xlsx/index.d.cts +55 -0
- package/dist/xlsx/index.d.ts +55 -0
- package/dist/xlsx/index.js +3049 -0
- package/dist/xlsx/index.js.map +1 -0
- package/docs/API.md +2959 -718
- package/docs/AST_format.md +2 -2
- package/eslint.config.mjs +40 -0
- package/lib/a1.spec.ts +32 -0
- package/lib/a1.ts +26 -0
- package/lib/addA1RangeBounds.ts +50 -0
- package/lib/addTokenMeta.spec.ts +166 -0
- package/lib/{addTokenMeta.js → addTokenMeta.ts} +53 -33
- package/lib/astTypes.ts +211 -0
- package/lib/cloneToken.ts +29 -0
- package/lib/{constants.js → constants.ts} +6 -3
- package/lib/fixRanges.spec.ts +220 -0
- package/lib/fixRanges.ts +260 -0
- package/lib/fromCol.spec.ts +15 -0
- package/lib/{fromCol.js → fromCol.ts} +1 -1
- package/lib/index.spec.ts +119 -0
- package/lib/index.ts +76 -0
- package/lib/isNodeType.ts +151 -0
- package/lib/isType.spec.ts +208 -0
- package/lib/{isType.js → isType.ts} +26 -25
- package/lib/lexers/advRangeOp.ts +18 -0
- package/lib/lexers/canEndRange.ts +25 -0
- package/lib/lexers/lexBoolean.ts +55 -0
- package/lib/lexers/lexContext.ts +104 -0
- package/lib/lexers/lexError.ts +15 -0
- package/lib/lexers/lexFunction.ts +37 -0
- package/lib/lexers/lexNameFuncCntx.ts +112 -0
- package/lib/lexers/lexNamed.ts +60 -0
- package/lib/lexers/lexNewLine.ts +12 -0
- package/lib/lexers/lexNumber.ts +48 -0
- package/lib/lexers/lexOperator.ts +26 -0
- package/lib/lexers/lexRange.ts +15 -0
- package/lib/lexers/lexRangeA1.ts +134 -0
- package/lib/lexers/lexRangeR1C1.ts +146 -0
- package/lib/lexers/lexRangeTrim.ts +26 -0
- package/lib/lexers/lexRefOp.ts +19 -0
- package/lib/lexers/lexString.ts +22 -0
- package/lib/lexers/lexStructured.ts +25 -0
- package/lib/lexers/lexWhitespace.ts +31 -0
- package/lib/lexers/sets.ts +51 -0
- package/lib/mergeRefTokens.spec.ts +141 -0
- package/lib/{mergeRefTokens.js → mergeRefTokens.ts} +47 -32
- package/lib/nodeTypes.ts +54 -0
- package/lib/parse.spec.ts +1410 -0
- package/lib/{parser.js → parse.ts} +81 -63
- package/lib/parseA1Range.spec.ts +233 -0
- package/lib/parseA1Range.ts +206 -0
- package/lib/parseA1Ref.spec.ts +337 -0
- package/lib/parseA1Ref.ts +115 -0
- package/lib/parseR1C1Range.ts +191 -0
- package/lib/parseR1C1Ref.spec.ts +323 -0
- package/lib/parseR1C1Ref.ts +127 -0
- package/lib/parseRef.spec.ts +90 -0
- package/lib/parseRef.ts +240 -0
- package/lib/parseSRange.ts +240 -0
- package/lib/parseStructRef.spec.ts +168 -0
- package/lib/parseStructRef.ts +76 -0
- package/lib/stringifyA1Range.spec.ts +72 -0
- package/lib/stringifyA1Range.ts +72 -0
- package/lib/stringifyA1Ref.spec.ts +64 -0
- package/lib/stringifyA1Ref.ts +59 -0
- package/lib/{stringifyPrefix.js → stringifyPrefix.ts} +17 -2
- package/lib/stringifyR1C1Range.spec.ts +92 -0
- package/lib/stringifyR1C1Range.ts +73 -0
- package/lib/stringifyR1C1Ref.spec.ts +63 -0
- package/lib/stringifyR1C1Ref.ts +67 -0
- package/lib/stringifyStructRef.spec.ts +124 -0
- package/lib/stringifyStructRef.ts +113 -0
- package/lib/stringifyTokens.ts +15 -0
- package/lib/toCol.spec.ts +11 -0
- package/lib/{toCol.js → toCol.ts} +4 -4
- package/lib/tokenTypes.ts +76 -0
- package/lib/tokenize-srefs.spec.ts +429 -0
- package/lib/tokenize.spec.ts +2103 -0
- package/lib/tokenize.ts +346 -0
- package/lib/translate.spec.ts +35 -0
- package/lib/translateToA1.spec.ts +247 -0
- package/lib/translateToA1.ts +231 -0
- package/lib/translateToR1C1.spec.ts +227 -0
- package/lib/translateToR1C1.ts +145 -0
- package/lib/types.ts +179 -0
- package/lib/xlsx/index.spec.ts +27 -0
- package/lib/xlsx/index.ts +32 -0
- package/package.json +46 -30
- package/tsconfig.json +28 -0
- package/typedoc-ignore-links.ts +17 -0
- package/typedoc.json +41 -0
- package/.eslintrc +0 -22
- package/dist/fx.d.ts +0 -823
- package/dist/fx.js +0 -2
- package/dist/package.json +0 -1
- package/lib/a1.js +0 -348
- package/lib/a1.spec.js +0 -458
- package/lib/addTokenMeta.spec.js +0 -153
- package/lib/astTypes.js +0 -96
- package/lib/extraTypes.js +0 -74
- package/lib/fixRanges.js +0 -104
- package/lib/fixRanges.spec.js +0 -170
- package/lib/fromCol.spec.js +0 -11
- package/lib/index.js +0 -134
- package/lib/index.spec.js +0 -67
- package/lib/isType.spec.js +0 -168
- package/lib/lexer-srefs.spec.js +0 -324
- package/lib/lexer.js +0 -283
- package/lib/lexer.spec.js +0 -1953
- package/lib/lexerParts.js +0 -228
- package/lib/mergeRefTokens.spec.js +0 -121
- package/lib/package.json +0 -1
- package/lib/parseRef.js +0 -157
- package/lib/parseRef.spec.js +0 -71
- package/lib/parseSRange.js +0 -167
- package/lib/parseStructRef.js +0 -48
- package/lib/parseStructRef.spec.js +0 -164
- package/lib/parser.spec.js +0 -1208
- package/lib/rc.js +0 -341
- package/lib/rc.spec.js +0 -403
- package/lib/stringifyStructRef.js +0 -80
- package/lib/stringifyStructRef.spec.js +0 -182
- package/lib/toCol.spec.js +0 -11
- package/lib/translate-toA1.spec.js +0 -214
- package/lib/translate-toRC.spec.js +0 -197
- package/lib/translate.js +0 -239
- package/lib/translate.spec.js +0 -21
- package/rollup.config.mjs +0 -22
- package/tsd.json +0 -12
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3054 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// lib/index.ts
|
|
20
|
+
var index_exports = {};
|
|
21
|
+
__export(index_exports, {
|
|
22
|
+
MAX_COLS: () => MAX_COLS,
|
|
23
|
+
MAX_ROWS: () => MAX_ROWS,
|
|
24
|
+
addA1RangeBounds: () => addA1RangeBounds,
|
|
25
|
+
fixFormulaRanges: () => fixFormulaRanges,
|
|
26
|
+
fixTokenRanges: () => fixTokenRanges,
|
|
27
|
+
fromCol: () => fromCol,
|
|
28
|
+
isArrayNode: () => isArrayNode,
|
|
29
|
+
isBinaryNode: () => isBinaryNode,
|
|
30
|
+
isCallNode: () => isCallNode,
|
|
31
|
+
isError: () => isError,
|
|
32
|
+
isErrorNode: () => isErrorNode,
|
|
33
|
+
isExpressionNode: () => isExpressionNode,
|
|
34
|
+
isFunction: () => isFunction,
|
|
35
|
+
isFxPrefix: () => isFxPrefix,
|
|
36
|
+
isIdentifierNode: () => isIdentifierNode,
|
|
37
|
+
isLambdaNode: () => isLambdaNode,
|
|
38
|
+
isLetDeclaratorNode: () => isLetDeclaratorNode,
|
|
39
|
+
isLetNode: () => isLetNode,
|
|
40
|
+
isLiteral: () => isLiteral,
|
|
41
|
+
isLiteralNode: () => isLiteralNode,
|
|
42
|
+
isOperator: () => isOperator,
|
|
43
|
+
isRange: () => isRange,
|
|
44
|
+
isReference: () => isReference,
|
|
45
|
+
isReferenceNode: () => isReferenceNode2,
|
|
46
|
+
isUnaryNode: () => isUnaryNode,
|
|
47
|
+
isWhitespace: () => isWhitespace,
|
|
48
|
+
mergeRefTokens: () => mergeRefTokens,
|
|
49
|
+
nodeTypes: () => nodeTypes,
|
|
50
|
+
parse: () => parse,
|
|
51
|
+
parseA1Range: () => parseA1Range,
|
|
52
|
+
parseA1Ref: () => parseA1Ref,
|
|
53
|
+
parseR1C1Range: () => parseR1C1Range,
|
|
54
|
+
parseR1C1Ref: () => parseR1C1Ref,
|
|
55
|
+
parseStructRef: () => parseStructRef,
|
|
56
|
+
stringifyA1Ref: () => stringifyA1Ref,
|
|
57
|
+
stringifyR1C1Ref: () => stringifyR1C1Ref,
|
|
58
|
+
stringifyStructRef: () => stringifyStructRef,
|
|
59
|
+
stringifyTokens: () => stringifyTokens,
|
|
60
|
+
toCol: () => toCol,
|
|
61
|
+
tokenTypes: () => tokenTypes,
|
|
62
|
+
tokenize: () => tokenize,
|
|
63
|
+
translateFormulaToA1: () => translateFormulaToA1,
|
|
64
|
+
translateFormulaToR1C1: () => translateFormulaToR1C1,
|
|
65
|
+
translateTokensToA1: () => translateTokensToA1,
|
|
66
|
+
translateTokensToR1C1: () => translateTokensToR1C1
|
|
67
|
+
});
|
|
68
|
+
module.exports = __toCommonJS(index_exports);
|
|
69
|
+
|
|
70
|
+
// lib/constants.ts
|
|
71
|
+
var OPERATOR = "operator";
|
|
72
|
+
var OPERATOR_TRIM = "operator-trim";
|
|
73
|
+
var BOOLEAN = "bool";
|
|
74
|
+
var ERROR = "error";
|
|
75
|
+
var NUMBER = "number";
|
|
76
|
+
var FUNCTION = "func";
|
|
77
|
+
var NEWLINE = "newline";
|
|
78
|
+
var WHITESPACE = "whitespace";
|
|
79
|
+
var STRING = "string";
|
|
80
|
+
var CONTEXT_QUOTE = "context_quote";
|
|
81
|
+
var CONTEXT = "context";
|
|
82
|
+
var REF_RANGE = "range";
|
|
83
|
+
var REF_BEAM = "range_beam";
|
|
84
|
+
var REF_TERNARY = "range_ternary";
|
|
85
|
+
var REF_NAMED = "range_named";
|
|
86
|
+
var REF_STRUCT = "structured";
|
|
87
|
+
var FX_PREFIX = "fx_prefix";
|
|
88
|
+
var UNKNOWN = "unknown";
|
|
89
|
+
var UNARY = "UnaryExpression";
|
|
90
|
+
var BINARY = "BinaryExpression";
|
|
91
|
+
var REFERENCE = "ReferenceIdentifier";
|
|
92
|
+
var LITERAL = "Literal";
|
|
93
|
+
var ERROR_LITERAL = "ErrorLiteral";
|
|
94
|
+
var CALL = "CallExpression";
|
|
95
|
+
var LAMBDA = "LambdaExpression";
|
|
96
|
+
var LET = "LetExpression";
|
|
97
|
+
var ARRAY = "ArrayExpression";
|
|
98
|
+
var IDENTIFIER = "Identifier";
|
|
99
|
+
var LET_DECL = "LetDeclarator";
|
|
100
|
+
var MAX_COLS = 2 ** 14 - 1;
|
|
101
|
+
var MAX_ROWS = 2 ** 20 - 1;
|
|
102
|
+
|
|
103
|
+
// lib/mergeRefTokens.ts
|
|
104
|
+
var END = "$";
|
|
105
|
+
var validRunsMerge = [
|
|
106
|
+
[REF_RANGE, ":", REF_RANGE],
|
|
107
|
+
[REF_RANGE, ".:", REF_RANGE],
|
|
108
|
+
[REF_RANGE, ":.", REF_RANGE],
|
|
109
|
+
[REF_RANGE, ".:.", REF_RANGE],
|
|
110
|
+
[REF_RANGE],
|
|
111
|
+
[REF_BEAM],
|
|
112
|
+
[REF_TERNARY],
|
|
113
|
+
[CONTEXT, "!", REF_RANGE, ":", REF_RANGE],
|
|
114
|
+
[CONTEXT, "!", REF_RANGE, ".:", REF_RANGE],
|
|
115
|
+
[CONTEXT, "!", REF_RANGE, ":.", REF_RANGE],
|
|
116
|
+
[CONTEXT, "!", REF_RANGE, ".:.", REF_RANGE],
|
|
117
|
+
[CONTEXT, "!", REF_RANGE],
|
|
118
|
+
[CONTEXT, "!", REF_BEAM],
|
|
119
|
+
[CONTEXT, "!", REF_TERNARY],
|
|
120
|
+
[CONTEXT_QUOTE, "!", REF_RANGE, ":", REF_RANGE],
|
|
121
|
+
[CONTEXT_QUOTE, "!", REF_RANGE, ".:", REF_RANGE],
|
|
122
|
+
[CONTEXT_QUOTE, "!", REF_RANGE, ":.", REF_RANGE],
|
|
123
|
+
[CONTEXT_QUOTE, "!", REF_RANGE, ".:.", REF_RANGE],
|
|
124
|
+
[CONTEXT_QUOTE, "!", REF_RANGE],
|
|
125
|
+
[CONTEXT_QUOTE, "!", REF_BEAM],
|
|
126
|
+
[CONTEXT_QUOTE, "!", REF_TERNARY],
|
|
127
|
+
[REF_NAMED],
|
|
128
|
+
[CONTEXT, "!", REF_NAMED],
|
|
129
|
+
[CONTEXT_QUOTE, "!", REF_NAMED],
|
|
130
|
+
[REF_STRUCT],
|
|
131
|
+
[REF_NAMED, REF_STRUCT],
|
|
132
|
+
[CONTEXT, "!", REF_NAMED, REF_STRUCT],
|
|
133
|
+
[CONTEXT_QUOTE, "!", REF_NAMED, REF_STRUCT]
|
|
134
|
+
];
|
|
135
|
+
var refPartsTree = {};
|
|
136
|
+
function packList(f, node) {
|
|
137
|
+
if (f.length) {
|
|
138
|
+
const key = f[0];
|
|
139
|
+
if (!node[key]) {
|
|
140
|
+
node[key] = {};
|
|
141
|
+
}
|
|
142
|
+
packList(f.slice(1), node[key]);
|
|
143
|
+
} else {
|
|
144
|
+
node[END] = true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
validRunsMerge.forEach((run) => packList(run.concat().reverse(), refPartsTree));
|
|
148
|
+
var matcher = (tokens2, currNode, anchorIndex, index = 0) => {
|
|
149
|
+
let i = index;
|
|
150
|
+
let node = currNode;
|
|
151
|
+
const max = tokens2.length - index;
|
|
152
|
+
while (i <= max) {
|
|
153
|
+
const token = tokens2[anchorIndex - i];
|
|
154
|
+
if (token) {
|
|
155
|
+
const key = token.type === OPERATOR ? token.value : token.type;
|
|
156
|
+
if (key in node) {
|
|
157
|
+
node = node[key];
|
|
158
|
+
i += 1;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return node[END] ? i : 0;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
function mergeRefTokens(tokenlist) {
|
|
166
|
+
const finalTokens = [];
|
|
167
|
+
for (let i = tokenlist.length - 1; i >= 0; i--) {
|
|
168
|
+
let token = tokenlist[i];
|
|
169
|
+
const type = token.type;
|
|
170
|
+
if (type === REF_RANGE || type === REF_BEAM || type === REF_TERNARY || type === REF_NAMED || type === REF_STRUCT) {
|
|
171
|
+
const valid = matcher(tokenlist, refPartsTree, i);
|
|
172
|
+
if (valid > 1) {
|
|
173
|
+
token = { ...token, value: "" };
|
|
174
|
+
const start = i - valid + 1;
|
|
175
|
+
for (let j = start; j <= i; j++) {
|
|
176
|
+
token.value += tokenlist[j].value;
|
|
177
|
+
}
|
|
178
|
+
if (token.loc && tokenlist[start].loc) {
|
|
179
|
+
token.loc[0] = tokenlist[start].loc[0];
|
|
180
|
+
}
|
|
181
|
+
i -= valid - 1;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
finalTokens[finalTokens.length] = token;
|
|
185
|
+
}
|
|
186
|
+
return finalTokens.reverse();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// lib/lexers/lexError.ts
|
|
190
|
+
var re_ERROR = /#(?:NAME\?|FIELD!|CALC!|VALUE!|REF!|DIV\/0!|NULL!|NUM!|N\/A|GETTING_DATA\b|SPILL!|UNKNOWN!|SYNTAX\?|ERROR!|CONNECT!|BLOCKED!|EXTERNAL!)/iy;
|
|
191
|
+
var HASH = 35;
|
|
192
|
+
function lexError(str, pos) {
|
|
193
|
+
if (str.charCodeAt(pos) === HASH) {
|
|
194
|
+
re_ERROR.lastIndex = pos;
|
|
195
|
+
const m = re_ERROR.exec(str);
|
|
196
|
+
if (m) {
|
|
197
|
+
return { type: ERROR, value: m[0] };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// lib/lexers/lexRangeTrim.ts
|
|
203
|
+
var PERIOD = 46;
|
|
204
|
+
var COLON = 58;
|
|
205
|
+
function lexRangeTrim(str, pos) {
|
|
206
|
+
const c0 = str.charCodeAt(pos);
|
|
207
|
+
if (c0 === PERIOD || c0 === COLON) {
|
|
208
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
209
|
+
if (c0 !== c1) {
|
|
210
|
+
if (c1 === COLON) {
|
|
211
|
+
return {
|
|
212
|
+
type: OPERATOR_TRIM,
|
|
213
|
+
value: str.slice(pos, pos + (str.charCodeAt(pos + 2) === PERIOD ? 3 : 2))
|
|
214
|
+
};
|
|
215
|
+
} else if (c1 === PERIOD) {
|
|
216
|
+
return {
|
|
217
|
+
type: OPERATOR_TRIM,
|
|
218
|
+
value: str.slice(pos, pos + 2)
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// lib/lexers/lexOperator.ts
|
|
226
|
+
function lexOperator(str, pos) {
|
|
227
|
+
const c0 = str.charCodeAt(pos);
|
|
228
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
229
|
+
if (c0 === 60 && c1 === 61 || // <=
|
|
230
|
+
c0 === 62 && c1 === 61 || // >=
|
|
231
|
+
c0 === 60 && c1 === 62) {
|
|
232
|
+
return { type: OPERATOR, value: str.slice(pos, pos + 2) };
|
|
233
|
+
}
|
|
234
|
+
if (
|
|
235
|
+
// { } ! # % &
|
|
236
|
+
c0 === 123 || c0 === 125 || c0 === 33 || c0 === 35 || c0 === 37 || c0 === 38 || // ( ) * + , -
|
|
237
|
+
c0 >= 40 && c0 <= 45 || // / : ; < = >
|
|
238
|
+
c0 === 47 || c0 >= 58 && c0 <= 62 || // @ ^
|
|
239
|
+
c0 === 64 || c0 === 94
|
|
240
|
+
) {
|
|
241
|
+
return { type: OPERATOR, value: str[pos] };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// lib/lexers/lexBoolean.ts
|
|
246
|
+
function preventMatch(c) {
|
|
247
|
+
return c >= 65 && c <= 90 || // A-Z
|
|
248
|
+
c >= 97 && c <= 122 || // a-z
|
|
249
|
+
c >= 48 && c <= 57 || // 0-9
|
|
250
|
+
c === 95 || // _
|
|
251
|
+
c === 92 || // \
|
|
252
|
+
c === 40 || // (
|
|
253
|
+
c === 46 || // .
|
|
254
|
+
c === 63 || // ?
|
|
255
|
+
c > 160;
|
|
256
|
+
}
|
|
257
|
+
function lexBoolean(str, pos) {
|
|
258
|
+
const c0 = str.charCodeAt(pos);
|
|
259
|
+
if (c0 === 84 || c0 === 116) {
|
|
260
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
261
|
+
if (c1 === 82 || c1 === 114) {
|
|
262
|
+
const c2 = str.charCodeAt(pos + 2);
|
|
263
|
+
if (c2 === 85 || c2 === 117) {
|
|
264
|
+
const c3 = str.charCodeAt(pos + 3);
|
|
265
|
+
if (c3 === 69 || c3 === 101) {
|
|
266
|
+
const c4 = str.charCodeAt(pos + 4);
|
|
267
|
+
if (!preventMatch(c4)) {
|
|
268
|
+
return { type: BOOLEAN, value: str.slice(pos, pos + 4) };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (c0 === 70 || c0 === 102) {
|
|
275
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
276
|
+
if (c1 === 65 || c1 === 97) {
|
|
277
|
+
const c2 = str.charCodeAt(pos + 2);
|
|
278
|
+
if (c2 === 76 || c2 === 108) {
|
|
279
|
+
const c3 = str.charCodeAt(pos + 3);
|
|
280
|
+
if (c3 === 83 || c3 === 115) {
|
|
281
|
+
const c4 = str.charCodeAt(pos + 4);
|
|
282
|
+
if (c4 === 69 || c4 === 101) {
|
|
283
|
+
const c5 = str.charCodeAt(pos + 5);
|
|
284
|
+
if (!preventMatch(c5)) {
|
|
285
|
+
return { type: BOOLEAN, value: str.slice(pos, pos + 5) };
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// lib/lexers/lexNewLine.ts
|
|
295
|
+
function lexNewLine(str, pos) {
|
|
296
|
+
const start = pos;
|
|
297
|
+
while (str.charCodeAt(pos) === 10) {
|
|
298
|
+
pos++;
|
|
299
|
+
}
|
|
300
|
+
if (pos !== start) {
|
|
301
|
+
return { type: NEWLINE, value: str.slice(start, pos) };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// lib/lexers/lexWhitespace.ts
|
|
306
|
+
function isWS(c) {
|
|
307
|
+
return c === 9 || c === 11 || c === 12 || c === 13 || c === 32 || c === 160 || c === 5760 || c === 8232 || c === 8233 || c === 8239 || c === 8287 || c === 12288 || c === 65279 || c >= 8192 && c <= 8202;
|
|
308
|
+
}
|
|
309
|
+
function lexWhitespace(str, pos) {
|
|
310
|
+
const start = pos;
|
|
311
|
+
while (isWS(str.charCodeAt(pos))) {
|
|
312
|
+
pos++;
|
|
313
|
+
}
|
|
314
|
+
if (pos !== start) {
|
|
315
|
+
return { type: WHITESPACE, value: str.slice(start, pos) };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// lib/lexers/lexString.ts
|
|
320
|
+
var QUOT = 34;
|
|
321
|
+
function lexString(str, pos) {
|
|
322
|
+
const start = pos;
|
|
323
|
+
if (str.charCodeAt(pos) === QUOT) {
|
|
324
|
+
pos++;
|
|
325
|
+
while (pos < str.length) {
|
|
326
|
+
const c = str.charCodeAt(pos);
|
|
327
|
+
if (c === QUOT) {
|
|
328
|
+
pos++;
|
|
329
|
+
if (str.charCodeAt(pos) !== QUOT) {
|
|
330
|
+
return { type: STRING, value: str.slice(start, pos) };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
pos++;
|
|
334
|
+
}
|
|
335
|
+
return { type: STRING, value: str.slice(start, pos), unterminated: true };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// lib/lexers/lexContext.ts
|
|
340
|
+
var QUOT_SINGLE = 39;
|
|
341
|
+
var BR_OPEN = 91;
|
|
342
|
+
var BR_CLOSE = 93;
|
|
343
|
+
var EXCL = 33;
|
|
344
|
+
function lexContextQuoted(str, pos, options) {
|
|
345
|
+
const c0 = str.charCodeAt(pos);
|
|
346
|
+
let br1;
|
|
347
|
+
let br2;
|
|
348
|
+
if (c0 === QUOT_SINGLE) {
|
|
349
|
+
const start = pos;
|
|
350
|
+
pos++;
|
|
351
|
+
while (pos < str.length) {
|
|
352
|
+
const c = str.charCodeAt(pos);
|
|
353
|
+
if (c === BR_OPEN) {
|
|
354
|
+
if (br1) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
br1 = pos;
|
|
358
|
+
} else if (c === BR_CLOSE) {
|
|
359
|
+
if (br2) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
br2 = pos;
|
|
363
|
+
} else if (c === QUOT_SINGLE) {
|
|
364
|
+
pos++;
|
|
365
|
+
if (str.charCodeAt(pos) !== QUOT_SINGLE) {
|
|
366
|
+
let valid = br1 == null && br2 == null;
|
|
367
|
+
if (options.xlsx && br1 === start + 1 && br2 === pos - 2) {
|
|
368
|
+
valid = true;
|
|
369
|
+
}
|
|
370
|
+
if (br1 >= start + 1 && br2 < pos - 2 && br2 > br1 + 1) {
|
|
371
|
+
valid = true;
|
|
372
|
+
}
|
|
373
|
+
if (valid && str.charCodeAt(pos) === EXCL) {
|
|
374
|
+
return { type: CONTEXT_QUOTE, value: str.slice(start, pos) };
|
|
375
|
+
}
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
pos++;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function lexContextUnquoted(str, pos, options) {
|
|
384
|
+
const c0 = str.charCodeAt(pos);
|
|
385
|
+
let br1;
|
|
386
|
+
let br2;
|
|
387
|
+
if (c0 !== QUOT_SINGLE && c0 !== EXCL) {
|
|
388
|
+
const start = pos;
|
|
389
|
+
while (pos < str.length) {
|
|
390
|
+
const c = str.charCodeAt(pos);
|
|
391
|
+
if (c === BR_OPEN) {
|
|
392
|
+
if (br1) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
br1 = pos;
|
|
396
|
+
} else if (c === BR_CLOSE) {
|
|
397
|
+
if (br2) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
br2 = pos;
|
|
401
|
+
} else if (c === EXCL) {
|
|
402
|
+
let valid = br1 == null && br2 == null;
|
|
403
|
+
if (options.xlsx && br1 === start && br2 === pos - 1) {
|
|
404
|
+
valid = true;
|
|
405
|
+
}
|
|
406
|
+
if (br1 >= start && br2 < pos - 1 && br2 > br1 + 1) {
|
|
407
|
+
valid = true;
|
|
408
|
+
}
|
|
409
|
+
if (valid) {
|
|
410
|
+
return { type: CONTEXT, value: str.slice(start, pos) };
|
|
411
|
+
}
|
|
412
|
+
} else if ((br1 == null || br2 != null) && // [0-9A-Za-z._¡¤§¨ª\u00ad¯-\uffff]
|
|
413
|
+
!(c >= 65 && c <= 90 || // A-Z
|
|
414
|
+
c >= 97 && c <= 122 || // a-z
|
|
415
|
+
c >= 48 && c <= 57 || // 0-9
|
|
416
|
+
c === 46 || // .
|
|
417
|
+
c === 95 || // _
|
|
418
|
+
c === 161 || // ¡
|
|
419
|
+
c === 164 || // ¤
|
|
420
|
+
c === 167 || // §
|
|
421
|
+
c === 168 || // ¨
|
|
422
|
+
c === 170 || // ª
|
|
423
|
+
c === 173 || // \u00ad
|
|
424
|
+
c >= 175)) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
pos++;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// lib/lexers/advRangeOp.ts
|
|
433
|
+
var PERIOD2 = 46;
|
|
434
|
+
var COLON2 = 58;
|
|
435
|
+
function advRangeOp(str, pos) {
|
|
436
|
+
const c0 = str.charCodeAt(pos);
|
|
437
|
+
if (c0 === PERIOD2) {
|
|
438
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
439
|
+
if (c1 === COLON2) {
|
|
440
|
+
return str.charCodeAt(pos + 2) === PERIOD2 ? 3 : 2;
|
|
441
|
+
}
|
|
442
|
+
} else if (c0 === COLON2) {
|
|
443
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
444
|
+
return c1 === PERIOD2 ? 2 : 1;
|
|
445
|
+
}
|
|
446
|
+
return 0;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// lib/lexers/canEndRange.ts
|
|
450
|
+
function canEndRange(str, pos) {
|
|
451
|
+
const c = str.charCodeAt(pos);
|
|
452
|
+
return !(c >= 65 && c <= 90 || // A-Z
|
|
453
|
+
c >= 97 && c <= 122 || // a-z
|
|
454
|
+
c >= 48 && c <= 57 || // 0-9
|
|
455
|
+
c === 95 || // _
|
|
456
|
+
c > 160);
|
|
457
|
+
}
|
|
458
|
+
function canEndPartialRange(str, pos) {
|
|
459
|
+
const c = str.charCodeAt(pos);
|
|
460
|
+
return !(c >= 65 && c <= 90 || // A-Z
|
|
461
|
+
c >= 97 && c <= 122 || // a-z
|
|
462
|
+
c >= 48 && c <= 57 || // 0-9
|
|
463
|
+
c === 95 || // _
|
|
464
|
+
c === 40 || // (
|
|
465
|
+
c === 36 || // $
|
|
466
|
+
c === 46);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// lib/lexers/lexRangeA1.ts
|
|
470
|
+
function advA1Col(str, pos) {
|
|
471
|
+
const start = pos;
|
|
472
|
+
if (str.charCodeAt(pos) === 36) {
|
|
473
|
+
pos++;
|
|
474
|
+
}
|
|
475
|
+
const stop = pos + 3;
|
|
476
|
+
let col = 0;
|
|
477
|
+
do {
|
|
478
|
+
const c = str.charCodeAt(pos);
|
|
479
|
+
if (c >= 65 && c <= 90) {
|
|
480
|
+
col = 26 * col + c - 64;
|
|
481
|
+
pos++;
|
|
482
|
+
} else if (c >= 97 && c <= 122) {
|
|
483
|
+
col = 26 * col + c - 96;
|
|
484
|
+
pos++;
|
|
485
|
+
} else {
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
} while (pos < stop && pos < str.length);
|
|
489
|
+
return col && col <= MAX_COLS + 1 ? pos - start : 0;
|
|
490
|
+
}
|
|
491
|
+
function advA1Row(str, pos) {
|
|
492
|
+
const start = pos;
|
|
493
|
+
if (str.charCodeAt(pos) === 36) {
|
|
494
|
+
pos++;
|
|
495
|
+
}
|
|
496
|
+
const stop = pos + 7;
|
|
497
|
+
let row = 0;
|
|
498
|
+
let c = str.charCodeAt(pos);
|
|
499
|
+
if (c >= 49 && c <= 57) {
|
|
500
|
+
row = row * 10 + c - 48;
|
|
501
|
+
pos++;
|
|
502
|
+
do {
|
|
503
|
+
c = str.charCodeAt(pos);
|
|
504
|
+
if (c >= 48 && c <= 57) {
|
|
505
|
+
row = row * 10 + c - 48;
|
|
506
|
+
pos++;
|
|
507
|
+
} else {
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
} while (pos < stop && pos < str.length);
|
|
511
|
+
}
|
|
512
|
+
return row && row <= MAX_ROWS + 1 ? pos - start : 0;
|
|
513
|
+
}
|
|
514
|
+
function lexRangeA1(str, pos, options) {
|
|
515
|
+
let p = pos;
|
|
516
|
+
const left = advA1Col(str, p);
|
|
517
|
+
let right = 0;
|
|
518
|
+
let bottom = 0;
|
|
519
|
+
if (left) {
|
|
520
|
+
p += left;
|
|
521
|
+
const top = advA1Row(str, p);
|
|
522
|
+
p += top;
|
|
523
|
+
const op = advRangeOp(str, p);
|
|
524
|
+
const preOp = p;
|
|
525
|
+
if (op) {
|
|
526
|
+
p += op;
|
|
527
|
+
right = advA1Col(str, p);
|
|
528
|
+
p += right;
|
|
529
|
+
bottom = advA1Row(str, p);
|
|
530
|
+
p += bottom;
|
|
531
|
+
if (top && bottom && right) {
|
|
532
|
+
if (canEndRange(str, p) && options.mergeRefs) {
|
|
533
|
+
return { type: REF_RANGE, value: str.slice(pos, p) };
|
|
534
|
+
}
|
|
535
|
+
} else if (!top && !bottom) {
|
|
536
|
+
if (canEndRange(str, p)) {
|
|
537
|
+
return { type: REF_BEAM, value: str.slice(pos, p) };
|
|
538
|
+
}
|
|
539
|
+
} else if (options.allowTernary && (bottom || right)) {
|
|
540
|
+
if (canEndPartialRange(str, p)) {
|
|
541
|
+
return { type: REF_TERNARY, value: str.slice(pos, p) };
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (top && canEndRange(str, preOp)) {
|
|
546
|
+
return { type: REF_RANGE, value: str.slice(pos, preOp) };
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
const top = advA1Row(str, p);
|
|
550
|
+
if (top) {
|
|
551
|
+
p += top;
|
|
552
|
+
const op = advRangeOp(str, p);
|
|
553
|
+
if (op) {
|
|
554
|
+
p += op;
|
|
555
|
+
right = advA1Col(str, p);
|
|
556
|
+
if (right) {
|
|
557
|
+
p += right;
|
|
558
|
+
}
|
|
559
|
+
bottom = advA1Row(str, p);
|
|
560
|
+
p += bottom;
|
|
561
|
+
if (right && bottom && options.allowTernary) {
|
|
562
|
+
if (canEndPartialRange(str, p)) {
|
|
563
|
+
return { type: REF_TERNARY, value: str.slice(pos, p) };
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (!right && bottom) {
|
|
567
|
+
if (canEndRange(str, p)) {
|
|
568
|
+
return { type: REF_BEAM, value: str.slice(pos, p) };
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// lib/lexers/lexRangeR1C1.ts
|
|
577
|
+
var BR_OPEN2 = 91;
|
|
578
|
+
var BR_CLOSE2 = 93;
|
|
579
|
+
var UC_R = 82;
|
|
580
|
+
var LC_R = 114;
|
|
581
|
+
var UC_C = 67;
|
|
582
|
+
var LC_C = 99;
|
|
583
|
+
var PLUS = 43;
|
|
584
|
+
var MINUS = 45;
|
|
585
|
+
function lexR1C1Part(str, pos, isRow = false) {
|
|
586
|
+
const start = pos;
|
|
587
|
+
const c0 = str.charCodeAt(pos);
|
|
588
|
+
if (isRow ? c0 === UC_R || c0 === LC_R : c0 === UC_C || c0 === LC_C) {
|
|
589
|
+
pos++;
|
|
590
|
+
let digits = 0;
|
|
591
|
+
let value = 0;
|
|
592
|
+
let stop = str.length;
|
|
593
|
+
const c1 = str.charCodeAt(pos);
|
|
594
|
+
let c;
|
|
595
|
+
let sign = 1;
|
|
596
|
+
const relative = c1 === BR_OPEN2;
|
|
597
|
+
if (relative) {
|
|
598
|
+
stop = Math.min(stop, pos + (isRow ? 8 : 6));
|
|
599
|
+
pos++;
|
|
600
|
+
c = str.charCodeAt(pos);
|
|
601
|
+
if (c === PLUS || c === MINUS) {
|
|
602
|
+
pos++;
|
|
603
|
+
stop++;
|
|
604
|
+
sign = c === MINUS ? -1 : 1;
|
|
605
|
+
}
|
|
606
|
+
} else if (c1 < 49 || c1 > 57 || isNaN(c1)) {
|
|
607
|
+
return 1;
|
|
608
|
+
}
|
|
609
|
+
do {
|
|
610
|
+
const c2 = str.charCodeAt(pos);
|
|
611
|
+
if (c2 >= 48 && c2 <= 57) {
|
|
612
|
+
value = value * 10 + c2 - 48;
|
|
613
|
+
digits++;
|
|
614
|
+
pos++;
|
|
615
|
+
} else {
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
} while (pos < stop);
|
|
619
|
+
const MAX = isRow ? MAX_ROWS : MAX_COLS;
|
|
620
|
+
if (relative) {
|
|
621
|
+
const c2 = str.charCodeAt(pos);
|
|
622
|
+
if (c2 !== BR_CLOSE2) {
|
|
623
|
+
return 0;
|
|
624
|
+
}
|
|
625
|
+
pos++;
|
|
626
|
+
value *= sign;
|
|
627
|
+
return digits && -MAX <= value && value <= MAX ? pos - start : 0;
|
|
628
|
+
}
|
|
629
|
+
return digits && value <= MAX + 1 ? pos - start : 0;
|
|
630
|
+
}
|
|
631
|
+
return 0;
|
|
632
|
+
}
|
|
633
|
+
function lexRangeR1C1(str, pos, options) {
|
|
634
|
+
let p = pos;
|
|
635
|
+
const r1 = lexR1C1Part(str, p, true);
|
|
636
|
+
p += r1;
|
|
637
|
+
const c1 = lexR1C1Part(str, p);
|
|
638
|
+
p += c1;
|
|
639
|
+
if (c1 || r1) {
|
|
640
|
+
const op = advRangeOp(str, p);
|
|
641
|
+
const preOp = p;
|
|
642
|
+
if (op) {
|
|
643
|
+
p += op;
|
|
644
|
+
const r2 = lexR1C1Part(str, p, true);
|
|
645
|
+
p += r2;
|
|
646
|
+
const c2 = lexR1C1Part(str, p);
|
|
647
|
+
p += c2;
|
|
648
|
+
if (r1 && !c1 && r2 && c2 || !r1 && c1 && r2 && c2 || r1 && c1 && r2 && !c2 || r1 && c1 && !r2 && c2) {
|
|
649
|
+
if (options.allowTernary && canEndRange(str, p)) {
|
|
650
|
+
return { type: REF_TERNARY, value: str.slice(pos, p) };
|
|
651
|
+
}
|
|
652
|
+
} else if (c1 && c2 && !r1 && !r2 || !c1 && !c2 && r1 && r2) {
|
|
653
|
+
if (canEndRange(str, p)) {
|
|
654
|
+
return { type: REF_BEAM, value: str.slice(pos, p) };
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (canEndRange(str, preOp)) {
|
|
659
|
+
return {
|
|
660
|
+
type: r1 && c1 ? REF_RANGE : REF_BEAM,
|
|
661
|
+
value: str.slice(pos, preOp)
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// lib/lexers/lexRange.ts
|
|
668
|
+
function lexRange(str, pos, options) {
|
|
669
|
+
return options.r1c1 ? lexRangeR1C1(str, pos, options) : lexRangeA1(str, pos, options);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// lib/parseSRange.ts
|
|
673
|
+
var AT = 64;
|
|
674
|
+
var BR_CLOSE3 = 93;
|
|
675
|
+
var BR_OPEN3 = 91;
|
|
676
|
+
var COLON3 = 58;
|
|
677
|
+
var COMMA = 44;
|
|
678
|
+
var HASH2 = 35;
|
|
679
|
+
var QUOT_SINGLE2 = 39;
|
|
680
|
+
var keyTerms = {
|
|
681
|
+
"headers": 1,
|
|
682
|
+
"data": 2,
|
|
683
|
+
"totals": 4,
|
|
684
|
+
"all": 8,
|
|
685
|
+
"this row": 16,
|
|
686
|
+
"@": 16
|
|
687
|
+
};
|
|
688
|
+
var fz = (...a) => Object.freeze(a);
|
|
689
|
+
var sectionMap = {
|
|
690
|
+
// no terms
|
|
691
|
+
0: fz(),
|
|
692
|
+
// single term
|
|
693
|
+
1: fz("headers"),
|
|
694
|
+
2: fz("data"),
|
|
695
|
+
4: fz("totals"),
|
|
696
|
+
8: fz("all"),
|
|
697
|
+
16: fz("this row"),
|
|
698
|
+
// headers+data
|
|
699
|
+
3: fz("headers", "data"),
|
|
700
|
+
// totals+data
|
|
701
|
+
6: fz("data", "totals")
|
|
702
|
+
};
|
|
703
|
+
function matchKeyword(str, pos) {
|
|
704
|
+
let p = pos;
|
|
705
|
+
if (str.charCodeAt(p++) !== BR_OPEN3) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
if (str.charCodeAt(p++) !== HASH2) {
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
do {
|
|
712
|
+
const c = str.charCodeAt(p);
|
|
713
|
+
if (c >= 65 && c <= 90 || // A-Z
|
|
714
|
+
c >= 97 && c <= 122 || // a-z
|
|
715
|
+
c === 32) {
|
|
716
|
+
p++;
|
|
717
|
+
} else {
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
} while (p < pos + 11);
|
|
721
|
+
if (str.charCodeAt(p++) !== BR_CLOSE3) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
return p - pos;
|
|
725
|
+
}
|
|
726
|
+
function skipWhitespace(str, pos) {
|
|
727
|
+
let p = pos;
|
|
728
|
+
while (isWS(str.charCodeAt(p))) {
|
|
729
|
+
p++;
|
|
730
|
+
}
|
|
731
|
+
return p - pos;
|
|
732
|
+
}
|
|
733
|
+
function matchColumn(str, pos, allowUnbraced = true) {
|
|
734
|
+
let p = pos;
|
|
735
|
+
let column = "";
|
|
736
|
+
if (str.charCodeAt(p) === BR_OPEN3) {
|
|
737
|
+
p++;
|
|
738
|
+
let c;
|
|
739
|
+
do {
|
|
740
|
+
c = str.charCodeAt(p);
|
|
741
|
+
if (c === QUOT_SINGLE2) {
|
|
742
|
+
p++;
|
|
743
|
+
c = str.charCodeAt(p);
|
|
744
|
+
if (c === QUOT_SINGLE2 || c === HASH2 || c === AT || c === BR_OPEN3 || c === BR_CLOSE3) {
|
|
745
|
+
column += String.fromCharCode(c);
|
|
746
|
+
p++;
|
|
747
|
+
} else {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
} else if (c === QUOT_SINGLE2 || c === HASH2 || c === AT || c === BR_OPEN3) {
|
|
751
|
+
return;
|
|
752
|
+
} else if (c === BR_CLOSE3) {
|
|
753
|
+
p++;
|
|
754
|
+
return [str.slice(pos, p), column];
|
|
755
|
+
} else {
|
|
756
|
+
column += String.fromCharCode(c);
|
|
757
|
+
p++;
|
|
758
|
+
}
|
|
759
|
+
} while (p < str.length);
|
|
760
|
+
} else if (allowUnbraced) {
|
|
761
|
+
let c;
|
|
762
|
+
do {
|
|
763
|
+
c = str.charCodeAt(p);
|
|
764
|
+
if (c === QUOT_SINGLE2 || c === HASH2 || c === AT || c === BR_OPEN3 || c === BR_CLOSE3 || c === COLON3) {
|
|
765
|
+
break;
|
|
766
|
+
} else {
|
|
767
|
+
column += String.fromCharCode(c);
|
|
768
|
+
p++;
|
|
769
|
+
}
|
|
770
|
+
} while (p < str.length);
|
|
771
|
+
if (p !== pos) {
|
|
772
|
+
return [column, column];
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
function parseSRange(str, pos = 0) {
|
|
777
|
+
const columns = [];
|
|
778
|
+
const start = pos;
|
|
779
|
+
let m;
|
|
780
|
+
let terms = 0;
|
|
781
|
+
if (str.charCodeAt(pos) !== BR_OPEN3) {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
if (m = matchKeyword(str, pos)) {
|
|
785
|
+
const k = str.slice(pos + 2, pos + m - 1);
|
|
786
|
+
pos += m;
|
|
787
|
+
const term = keyTerms[k.toLowerCase()];
|
|
788
|
+
if (!term) {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
terms |= term;
|
|
792
|
+
} else if (m = matchColumn(str, pos, false)) {
|
|
793
|
+
pos += m[0].length;
|
|
794
|
+
if (m[1]) {
|
|
795
|
+
columns.push(m[1]);
|
|
796
|
+
}
|
|
797
|
+
} else {
|
|
798
|
+
let expect_more = true;
|
|
799
|
+
pos++;
|
|
800
|
+
pos += skipWhitespace(str, pos);
|
|
801
|
+
while (expect_more && (m = matchKeyword(str, pos))) {
|
|
802
|
+
const k = str.slice(pos + 2, pos + m - 1);
|
|
803
|
+
const term = keyTerms[k.toLowerCase()];
|
|
804
|
+
if (!term) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
terms |= term;
|
|
808
|
+
pos += m;
|
|
809
|
+
pos += skipWhitespace(str, pos);
|
|
810
|
+
expect_more = str.charCodeAt(pos) === COMMA;
|
|
811
|
+
if (expect_more) {
|
|
812
|
+
pos++;
|
|
813
|
+
pos += skipWhitespace(str, pos);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
if (expect_more && str.charCodeAt(pos) === AT) {
|
|
817
|
+
terms |= keyTerms["@"];
|
|
818
|
+
pos += 1;
|
|
819
|
+
expect_more = str.charCodeAt(pos) !== BR_CLOSE3;
|
|
820
|
+
}
|
|
821
|
+
if (!sectionMap[terms]) {
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
const leftCol = expect_more && matchColumn(str, pos, true);
|
|
825
|
+
if (leftCol) {
|
|
826
|
+
pos += leftCol[0].length;
|
|
827
|
+
columns.push(leftCol[1]);
|
|
828
|
+
if (str.charCodeAt(pos) === COLON3) {
|
|
829
|
+
pos++;
|
|
830
|
+
const rightCol = matchColumn(str, pos, true);
|
|
831
|
+
if (rightCol) {
|
|
832
|
+
pos += rightCol[0].length;
|
|
833
|
+
columns.push(rightCol[1]);
|
|
834
|
+
} else {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
expect_more = false;
|
|
839
|
+
}
|
|
840
|
+
pos += skipWhitespace(str, pos);
|
|
841
|
+
if (expect_more || str.charCodeAt(pos) !== BR_CLOSE3) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
pos++;
|
|
845
|
+
}
|
|
846
|
+
const sections = sectionMap[terms];
|
|
847
|
+
return {
|
|
848
|
+
columns,
|
|
849
|
+
sections: sections ? sections.concat() : sections,
|
|
850
|
+
length: pos - start,
|
|
851
|
+
token: str.slice(start, pos)
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// lib/lexers/lexStructured.ts
|
|
856
|
+
var EXCL2 = 33;
|
|
857
|
+
function lexStructured(str, pos) {
|
|
858
|
+
const structData = parseSRange(str, pos);
|
|
859
|
+
if (structData && structData.length) {
|
|
860
|
+
let i = structData.length;
|
|
861
|
+
while (isWS(str.charCodeAt(pos + i))) {
|
|
862
|
+
i++;
|
|
863
|
+
}
|
|
864
|
+
if (str.charCodeAt(pos + i) !== EXCL2) {
|
|
865
|
+
return {
|
|
866
|
+
type: REF_STRUCT,
|
|
867
|
+
value: structData.token
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// lib/lexers/lexNumber.ts
|
|
874
|
+
function advDigits(str, pos) {
|
|
875
|
+
const start = pos;
|
|
876
|
+
do {
|
|
877
|
+
const c = str.charCodeAt(pos);
|
|
878
|
+
if (c < 48 || c > 57) {
|
|
879
|
+
break;
|
|
880
|
+
}
|
|
881
|
+
pos++;
|
|
882
|
+
} while (pos < str.length);
|
|
883
|
+
return pos - start;
|
|
884
|
+
}
|
|
885
|
+
function lexNumber(str, pos) {
|
|
886
|
+
const start = pos;
|
|
887
|
+
const lead = advDigits(str, pos);
|
|
888
|
+
if (!lead) {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
pos += lead;
|
|
892
|
+
const c0 = str.charCodeAt(pos);
|
|
893
|
+
if (c0 === 46) {
|
|
894
|
+
pos++;
|
|
895
|
+
const frac = advDigits(str, pos);
|
|
896
|
+
if (!frac) {
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
pos += frac;
|
|
900
|
+
}
|
|
901
|
+
const c1 = str.charCodeAt(pos);
|
|
902
|
+
if (c1 === 69 || c1 === 101) {
|
|
903
|
+
pos++;
|
|
904
|
+
const sign = str.charCodeAt(pos);
|
|
905
|
+
if (sign === 43 || sign === 45) {
|
|
906
|
+
pos++;
|
|
907
|
+
}
|
|
908
|
+
const exp = advDigits(str, pos);
|
|
909
|
+
if (!exp) {
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
pos += exp;
|
|
913
|
+
}
|
|
914
|
+
return { type: NUMBER, value: str.slice(start, pos) };
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
// lib/lexers/lexNamed.ts
|
|
918
|
+
function lexNamed(str, pos) {
|
|
919
|
+
const start = pos;
|
|
920
|
+
const s = str.charCodeAt(pos);
|
|
921
|
+
if (s >= 65 && s <= 90 || // A-Z
|
|
922
|
+
s >= 97 && s <= 122 || // a-z
|
|
923
|
+
s === 95 || // _
|
|
924
|
+
s === 92 || // \
|
|
925
|
+
s > 160) {
|
|
926
|
+
pos++;
|
|
927
|
+
} else {
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
let c;
|
|
931
|
+
do {
|
|
932
|
+
c = str.charCodeAt(pos);
|
|
933
|
+
if (c >= 65 && c <= 90 || // A-Z
|
|
934
|
+
c >= 97 && c <= 122 || // a-z
|
|
935
|
+
c >= 48 && c <= 57 || // 0-9
|
|
936
|
+
c === 95 || // _
|
|
937
|
+
c === 92 || // \
|
|
938
|
+
c === 46 || // .
|
|
939
|
+
c === 63 || // ?
|
|
940
|
+
c > 160) {
|
|
941
|
+
pos++;
|
|
942
|
+
} else {
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
} while (isFinite(c));
|
|
946
|
+
const len = pos - start;
|
|
947
|
+
if (len && len < 255) {
|
|
948
|
+
if (s === 92 && len < 3) {
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
if (len === 1 && (s === 114 || s === 82 || s === 99 || s === 67)) {
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
return { type: REF_NAMED, value: str.slice(start, pos) };
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// lib/lexers/lexRefOp.ts
|
|
959
|
+
var EXCL3 = 33;
|
|
960
|
+
function lexRefOp(str, pos, opts) {
|
|
961
|
+
if (str.charCodeAt(pos) === EXCL3) {
|
|
962
|
+
return { type: OPERATOR, value: str[pos] };
|
|
963
|
+
}
|
|
964
|
+
if (!opts.r1c1) {
|
|
965
|
+
const opLen = advRangeOp(str, pos);
|
|
966
|
+
if (opLen) {
|
|
967
|
+
return { type: OPERATOR, value: str.slice(pos, pos + opLen) };
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// lib/lexers/lexNameFuncCntx.ts
|
|
973
|
+
var BR_OPEN4 = 91;
|
|
974
|
+
var PAREN_OPEN = 40;
|
|
975
|
+
var EXCL4 = 33;
|
|
976
|
+
var OFFS = 32;
|
|
977
|
+
var ALLOWED = new Uint8Array(180 - OFFS);
|
|
978
|
+
var OK_NAME_0 = 1;
|
|
979
|
+
var OK_FUNC_0 = 2;
|
|
980
|
+
var OK_CNTX_0 = 4;
|
|
981
|
+
var OK_NAME_N = 8;
|
|
982
|
+
var OK_FUNC_N = 16;
|
|
983
|
+
var OK_CNTX_N = 32;
|
|
984
|
+
var OK_0 = OK_NAME_0 | OK_FUNC_0 | OK_CNTX_0;
|
|
985
|
+
var OK_N = OK_NAME_N | OK_FUNC_N | OK_CNTX_N;
|
|
986
|
+
var OK_HIGHCHAR = OK_NAME_0 | OK_NAME_N | OK_CNTX_0 | OK_CNTX_N;
|
|
987
|
+
for (let c = OFFS; c < 180; c++) {
|
|
988
|
+
const char = String.fromCharCode(c);
|
|
989
|
+
const n0 = /^[a-zA-Z_\\\u00a1-\uffff]$/.test(char);
|
|
990
|
+
const f0 = /^[a-zA-Z_]$/.test(char);
|
|
991
|
+
const nN = /^[a-zA-Z0-9_.\\?\u00a1-\uffff]$/.test(char);
|
|
992
|
+
const fN = /^[a-zA-Z0-9_.]$/.test(char);
|
|
993
|
+
const cX = /^[a-zA-Z0-9_.¡¤§¨ª\u00ad¯-\uffff]$/.test(char);
|
|
994
|
+
ALLOWED[c - OFFS] = (n0 ? OK_NAME_0 : 0) | (nN ? OK_NAME_N : 0) | (f0 ? OK_FUNC_0 : 0) | (fN ? OK_FUNC_N : 0) | (cX ? OK_CNTX_0 : 0) | (cX ? OK_CNTX_N : 0);
|
|
995
|
+
}
|
|
996
|
+
function nameOrUnknown(str, s, start, pos, name) {
|
|
997
|
+
const len = pos - start;
|
|
998
|
+
if (name && len && len < 255) {
|
|
999
|
+
if (s === 92 && len < 3) {
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
if (len === 1 && (s === 114 || s === 82 || s === 99 || s === 67)) {
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
return { type: REF_NAMED, value: str.slice(start, pos) };
|
|
1006
|
+
}
|
|
1007
|
+
return { type: UNKNOWN, value: str.slice(start, pos) };
|
|
1008
|
+
}
|
|
1009
|
+
function lexNameFuncCntx(str, pos, opts) {
|
|
1010
|
+
const start = pos;
|
|
1011
|
+
const s = str.charCodeAt(pos);
|
|
1012
|
+
const a = s > 180 ? OK_HIGHCHAR : ALLOWED[s - OFFS];
|
|
1013
|
+
if (a & OK_CNTX_0 && !(a & OK_NAME_0) && !(a & OK_FUNC_0) || s === BR_OPEN4) {
|
|
1014
|
+
return lexContextUnquoted(str, pos, opts);
|
|
1015
|
+
}
|
|
1016
|
+
if (!(a & OK_0)) {
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
let name = a & OK_NAME_0 ? 1 : 0;
|
|
1020
|
+
let func = a & OK_FUNC_0 ? 1 : 0;
|
|
1021
|
+
let cntx = a & OK_CNTX_0 ? 1 : 0;
|
|
1022
|
+
pos++;
|
|
1023
|
+
let c;
|
|
1024
|
+
do {
|
|
1025
|
+
c = str.charCodeAt(pos);
|
|
1026
|
+
const a2 = s > 180 ? OK_HIGHCHAR : ALLOWED[c - OFFS] ?? 0;
|
|
1027
|
+
if (a2 & OK_N) {
|
|
1028
|
+
if (name && !(a2 & OK_NAME_N)) {
|
|
1029
|
+
name = 0;
|
|
1030
|
+
}
|
|
1031
|
+
if (func && !(a2 & OK_FUNC_N)) {
|
|
1032
|
+
func = 0;
|
|
1033
|
+
}
|
|
1034
|
+
if (cntx && !(a2 & OK_CNTX_N)) {
|
|
1035
|
+
cntx = 0;
|
|
1036
|
+
}
|
|
1037
|
+
} else {
|
|
1038
|
+
if (c === PAREN_OPEN && func) {
|
|
1039
|
+
return { type: FUNCTION, value: str.slice(start, pos) };
|
|
1040
|
+
} else if (c === EXCL4 && cntx) {
|
|
1041
|
+
return { type: CONTEXT, value: str.slice(start, pos) };
|
|
1042
|
+
}
|
|
1043
|
+
return nameOrUnknown(str, s, start, pos, name);
|
|
1044
|
+
}
|
|
1045
|
+
pos++;
|
|
1046
|
+
} while ((name || func || cntx) && pos < str.length);
|
|
1047
|
+
if (start !== pos) {
|
|
1048
|
+
return nameOrUnknown(str, s, start, pos, name);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
// lib/lexers/sets.ts
|
|
1053
|
+
var lexers = [
|
|
1054
|
+
lexError,
|
|
1055
|
+
lexRangeTrim,
|
|
1056
|
+
lexOperator,
|
|
1057
|
+
lexNewLine,
|
|
1058
|
+
lexWhitespace,
|
|
1059
|
+
lexString,
|
|
1060
|
+
lexRange,
|
|
1061
|
+
lexNumber,
|
|
1062
|
+
lexBoolean,
|
|
1063
|
+
lexContextQuoted,
|
|
1064
|
+
lexNameFuncCntx,
|
|
1065
|
+
lexStructured
|
|
1066
|
+
];
|
|
1067
|
+
var lexersRefs = [
|
|
1068
|
+
lexRefOp,
|
|
1069
|
+
lexContextQuoted,
|
|
1070
|
+
lexContextUnquoted,
|
|
1071
|
+
lexRange,
|
|
1072
|
+
lexStructured,
|
|
1073
|
+
lexNamed
|
|
1074
|
+
];
|
|
1075
|
+
|
|
1076
|
+
// lib/tokenize.ts
|
|
1077
|
+
var reLetLambda = /^l(?:ambda|et)$/i;
|
|
1078
|
+
var isType = (t, type) => t && t.type === type;
|
|
1079
|
+
var isTextTokenType = (tokenType) => tokenType === REF_NAMED || tokenType === FUNCTION;
|
|
1080
|
+
var causesBinaryMinus = (token) => {
|
|
1081
|
+
return !isType(token, OPERATOR) || (token.value === "%" || token.value === "}" || token.value === ")" || token.value === "#");
|
|
1082
|
+
};
|
|
1083
|
+
function fixRCNames(tokens2) {
|
|
1084
|
+
let withinCall = 0;
|
|
1085
|
+
let parenDepth = 0;
|
|
1086
|
+
let lastToken;
|
|
1087
|
+
for (const token of tokens2) {
|
|
1088
|
+
if (token.type === OPERATOR) {
|
|
1089
|
+
if (token.value === "(") {
|
|
1090
|
+
parenDepth++;
|
|
1091
|
+
if (lastToken.type === FUNCTION) {
|
|
1092
|
+
if (reLetLambda.test(lastToken.value)) {
|
|
1093
|
+
withinCall = parenDepth;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
} else if (token.value === ")") {
|
|
1097
|
+
parenDepth--;
|
|
1098
|
+
if (parenDepth < withinCall) {
|
|
1099
|
+
withinCall = 0;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
} else if (withinCall && token.type === UNKNOWN && /^[rc]$/.test(token.value)) {
|
|
1103
|
+
token.type = REF_NAMED;
|
|
1104
|
+
}
|
|
1105
|
+
lastToken = token;
|
|
1106
|
+
}
|
|
1107
|
+
return tokens2;
|
|
1108
|
+
}
|
|
1109
|
+
function getTokens(fx, tokenHandlers, options = {}) {
|
|
1110
|
+
const {
|
|
1111
|
+
withLocation = false,
|
|
1112
|
+
mergeRefs = true,
|
|
1113
|
+
negativeNumbers = true
|
|
1114
|
+
} = options;
|
|
1115
|
+
const opts = {
|
|
1116
|
+
withLocation,
|
|
1117
|
+
mergeRefs,
|
|
1118
|
+
allowTernary: options.allowTernary ?? false,
|
|
1119
|
+
negativeNumbers,
|
|
1120
|
+
r1c1: options.r1c1 ?? false,
|
|
1121
|
+
xlsx: options.xlsx ?? false
|
|
1122
|
+
};
|
|
1123
|
+
const tokens2 = [];
|
|
1124
|
+
let pos = 0;
|
|
1125
|
+
let letOrLambda = 0;
|
|
1126
|
+
let unknownRC = 0;
|
|
1127
|
+
const trimOps = [];
|
|
1128
|
+
let tail0;
|
|
1129
|
+
let tail1;
|
|
1130
|
+
let lastToken;
|
|
1131
|
+
const pushToken = (token) => {
|
|
1132
|
+
let tokenType = token.type;
|
|
1133
|
+
const isCurrUnknown = tokenType === UNKNOWN;
|
|
1134
|
+
const isLastUnknown = lastToken && lastToken.type === UNKNOWN;
|
|
1135
|
+
if (lastToken && (isCurrUnknown && isLastUnknown || isCurrUnknown && isTextTokenType(lastToken.type) || isLastUnknown && isTextTokenType(tokenType))) {
|
|
1136
|
+
lastToken.value += token.value;
|
|
1137
|
+
lastToken.type = UNKNOWN;
|
|
1138
|
+
if (withLocation) {
|
|
1139
|
+
lastToken.loc[1] = token.loc[1];
|
|
1140
|
+
}
|
|
1141
|
+
} else {
|
|
1142
|
+
if (tokenType === OPERATOR_TRIM) {
|
|
1143
|
+
trimOps.push(tokens2.length);
|
|
1144
|
+
tokenType = UNKNOWN;
|
|
1145
|
+
token.type = UNKNOWN;
|
|
1146
|
+
}
|
|
1147
|
+
tokens2[tokens2.length] = token;
|
|
1148
|
+
lastToken = token;
|
|
1149
|
+
if (tokenType !== WHITESPACE && tokenType !== NEWLINE) {
|
|
1150
|
+
tail1 = tail0;
|
|
1151
|
+
tail0 = token;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
if (fx.startsWith("=")) {
|
|
1156
|
+
const token = { type: FX_PREFIX, value: "=" };
|
|
1157
|
+
if (withLocation) {
|
|
1158
|
+
token.loc = [0, 1];
|
|
1159
|
+
}
|
|
1160
|
+
pos++;
|
|
1161
|
+
pushToken(token);
|
|
1162
|
+
}
|
|
1163
|
+
const numHandlers = tokenHandlers.length;
|
|
1164
|
+
while (pos < fx.length) {
|
|
1165
|
+
const startPos = pos;
|
|
1166
|
+
let token;
|
|
1167
|
+
for (let i = 0; i < numHandlers; i++) {
|
|
1168
|
+
token = tokenHandlers[i](fx, pos, opts);
|
|
1169
|
+
if (token) {
|
|
1170
|
+
pos += token.value.length;
|
|
1171
|
+
break;
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
if (!token) {
|
|
1175
|
+
token = {
|
|
1176
|
+
type: UNKNOWN,
|
|
1177
|
+
value: fx[pos]
|
|
1178
|
+
};
|
|
1179
|
+
pos++;
|
|
1180
|
+
}
|
|
1181
|
+
if (withLocation) {
|
|
1182
|
+
token.loc = [startPos, pos];
|
|
1183
|
+
}
|
|
1184
|
+
if (lastToken && token.value === "(" && lastToken.type === FUNCTION) {
|
|
1185
|
+
if (reLetLambda.test(lastToken.value)) {
|
|
1186
|
+
letOrLambda++;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
if (token.type === UNKNOWN && token.value.length === 1) {
|
|
1190
|
+
const valLC = token.value.toLowerCase();
|
|
1191
|
+
unknownRC += valLC === "r" || valLC === "c" ? 1 : 0;
|
|
1192
|
+
}
|
|
1193
|
+
if (negativeNumbers && token.type === NUMBER) {
|
|
1194
|
+
const last1 = lastToken;
|
|
1195
|
+
if (last1?.type === OPERATOR && last1.value === "-") {
|
|
1196
|
+
if (!tail1 || tail1.type === FX_PREFIX || !causesBinaryMinus(tail1)) {
|
|
1197
|
+
const minus = tokens2.pop();
|
|
1198
|
+
token.value = "-" + token.value;
|
|
1199
|
+
if (token.loc) {
|
|
1200
|
+
token.loc[0] = minus.loc[0];
|
|
1201
|
+
}
|
|
1202
|
+
tail0 = tail1;
|
|
1203
|
+
lastToken = tokens2[tokens2.length - 1];
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
pushToken(token);
|
|
1208
|
+
}
|
|
1209
|
+
if (unknownRC && letOrLambda) {
|
|
1210
|
+
fixRCNames(tokens2);
|
|
1211
|
+
}
|
|
1212
|
+
for (const index of trimOps) {
|
|
1213
|
+
const before = tokens2[index - 1];
|
|
1214
|
+
const after = tokens2[index + 1];
|
|
1215
|
+
tokens2[index].type = before?.type === REF_RANGE && after?.type === REF_RANGE ? OPERATOR : UNKNOWN;
|
|
1216
|
+
}
|
|
1217
|
+
if (mergeRefs) {
|
|
1218
|
+
return mergeRefTokens(tokens2);
|
|
1219
|
+
}
|
|
1220
|
+
return tokens2;
|
|
1221
|
+
}
|
|
1222
|
+
function tokenize(formula, options = {}) {
|
|
1223
|
+
return getTokens(formula, lexers, options);
|
|
1224
|
+
}
|
|
1225
|
+
function tokenizeXlsx(formula, options = {}) {
|
|
1226
|
+
const opts = {
|
|
1227
|
+
withLocation: options.withLocation ?? false,
|
|
1228
|
+
mergeRefs: options.mergeRefs ?? true,
|
|
1229
|
+
allowTernary: options.allowTernary ?? false,
|
|
1230
|
+
negativeNumbers: options.negativeNumbers ?? true,
|
|
1231
|
+
r1c1: options.r1c1 ?? false,
|
|
1232
|
+
xlsx: true
|
|
1233
|
+
};
|
|
1234
|
+
return getTokens(formula, lexers, opts);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// lib/isType.ts
|
|
1238
|
+
function isRange(token) {
|
|
1239
|
+
return !!token && (token.type === REF_RANGE || token.type === REF_BEAM || token.type === REF_TERNARY);
|
|
1240
|
+
}
|
|
1241
|
+
function isReference(token) {
|
|
1242
|
+
return !!token && (token.type === REF_RANGE || token.type === REF_BEAM || token.type === REF_TERNARY || token.type === REF_STRUCT || token.type === REF_NAMED);
|
|
1243
|
+
}
|
|
1244
|
+
function isLiteral(token) {
|
|
1245
|
+
return !!token && (token.type === BOOLEAN || token.type === ERROR || token.type === NUMBER || token.type === STRING);
|
|
1246
|
+
}
|
|
1247
|
+
function isError(token) {
|
|
1248
|
+
return !!token && token.type === ERROR;
|
|
1249
|
+
}
|
|
1250
|
+
function isWhitespace(token) {
|
|
1251
|
+
return !!token && (token.type === WHITESPACE || token.type === NEWLINE);
|
|
1252
|
+
}
|
|
1253
|
+
function isFunction(token) {
|
|
1254
|
+
return !!token && token.type === FUNCTION;
|
|
1255
|
+
}
|
|
1256
|
+
function isFxPrefix(token) {
|
|
1257
|
+
return !!token && token.type === FX_PREFIX;
|
|
1258
|
+
}
|
|
1259
|
+
function isOperator(token) {
|
|
1260
|
+
return !!token && token.type === OPERATOR;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
// lib/parse.ts
|
|
1264
|
+
var END2 = "(END)";
|
|
1265
|
+
var FUNCTION2 = "(FUNCTION)";
|
|
1266
|
+
var WHITESPACE2 = "(WHITESPACE)";
|
|
1267
|
+
var refFunctions = [
|
|
1268
|
+
"ANCHORARRAY",
|
|
1269
|
+
"CHOOSE",
|
|
1270
|
+
"DROP",
|
|
1271
|
+
"IF",
|
|
1272
|
+
"IFS",
|
|
1273
|
+
"INDEX",
|
|
1274
|
+
"INDIRECT",
|
|
1275
|
+
"LAMBDA",
|
|
1276
|
+
"LET",
|
|
1277
|
+
"OFFSET",
|
|
1278
|
+
"REDUCE",
|
|
1279
|
+
"SINGLE",
|
|
1280
|
+
"SWITCH",
|
|
1281
|
+
"TAKE",
|
|
1282
|
+
"TRIMRANGE",
|
|
1283
|
+
"XLOOKUP"
|
|
1284
|
+
];
|
|
1285
|
+
var symbolTable = {};
|
|
1286
|
+
var currentNode;
|
|
1287
|
+
var tokens;
|
|
1288
|
+
var tokenIndex;
|
|
1289
|
+
var permitArrayRanges = false;
|
|
1290
|
+
var permitArrayCalls = false;
|
|
1291
|
+
var looseRefCalls = false;
|
|
1292
|
+
var isReferenceFunctionName = (fnName) => {
|
|
1293
|
+
return looseRefCalls || refFunctions.includes(fnName.toUpperCase());
|
|
1294
|
+
};
|
|
1295
|
+
var isReferenceToken = (token, allowOperators = false) => {
|
|
1296
|
+
const value = (token && token.value) + "";
|
|
1297
|
+
if (isReference(token)) {
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1300
|
+
if (allowOperators && isOperator(token) && (value === ":" || value === "," || !value.trim())) {
|
|
1301
|
+
return true;
|
|
1302
|
+
}
|
|
1303
|
+
if (isFunction(token) && isReferenceFunctionName(value)) {
|
|
1304
|
+
return true;
|
|
1305
|
+
}
|
|
1306
|
+
if (isError(token) && value === "#REF!") {
|
|
1307
|
+
return true;
|
|
1308
|
+
}
|
|
1309
|
+
return false;
|
|
1310
|
+
};
|
|
1311
|
+
var isReferenceNode = (node) => {
|
|
1312
|
+
return !!node && (node.type === REFERENCE || (node.type === ERROR_LITERAL || node.type === ERROR) && node.value === "#REF!" || node.type === BINARY && (node.operator === ":" || node.operator === " " || node.operator === ",") || isReference(node) || node.type === CALL && isReferenceFunctionName(node.callee.name));
|
|
1313
|
+
};
|
|
1314
|
+
function halt(message, atIndex = null) {
|
|
1315
|
+
const err = new Error(message);
|
|
1316
|
+
err.source = tokens.map((d) => d.value).join("");
|
|
1317
|
+
err.sourceOffset = tokens.slice(0, atIndex ?? tokenIndex).reduce((a, d) => a + d.value.length, 0);
|
|
1318
|
+
throw err;
|
|
1319
|
+
}
|
|
1320
|
+
function refIsUpcoming(allowOperators = false) {
|
|
1321
|
+
let i = tokenIndex;
|
|
1322
|
+
let next;
|
|
1323
|
+
do {
|
|
1324
|
+
next = tokens[++i];
|
|
1325
|
+
} while (next && (isWhitespace(next) || isOperator(next) && next.value === "("));
|
|
1326
|
+
return isReferenceToken(next, allowOperators);
|
|
1327
|
+
}
|
|
1328
|
+
function advance(expectNext = null, leftNode = null) {
|
|
1329
|
+
if (expectNext && expectNext !== currentNode.id) {
|
|
1330
|
+
halt(`Expected ${expectNext} but got ${currentNode.id}`);
|
|
1331
|
+
}
|
|
1332
|
+
if (isWhitespace(tokens[tokenIndex])) {
|
|
1333
|
+
const haveRef = isReferenceNode(leftNode);
|
|
1334
|
+
const possibleWSOp = haveRef && refIsUpcoming(false);
|
|
1335
|
+
const nextIsCall = haveRef && tokens[tokenIndex + 1] && tokens[tokenIndex + 1].value === "(";
|
|
1336
|
+
if (!possibleWSOp && !nextIsCall) {
|
|
1337
|
+
while (isWhitespace(tokens[tokenIndex])) {
|
|
1338
|
+
tokenIndex++;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
if (tokenIndex >= tokens.length) {
|
|
1343
|
+
currentNode = symbolTable[END2];
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
const token = tokens[tokenIndex];
|
|
1347
|
+
tokenIndex += 1;
|
|
1348
|
+
if (token.unterminated) {
|
|
1349
|
+
halt("Encountered an unterminated token");
|
|
1350
|
+
}
|
|
1351
|
+
let node;
|
|
1352
|
+
if (isOperator(token)) {
|
|
1353
|
+
node = symbolTable[token.value];
|
|
1354
|
+
if (!node) {
|
|
1355
|
+
halt(`Unknown operator ${token.value}`);
|
|
1356
|
+
}
|
|
1357
|
+
} else if (isWhitespace(token)) {
|
|
1358
|
+
node = symbolTable[WHITESPACE2];
|
|
1359
|
+
} else if (isLiteral(token)) {
|
|
1360
|
+
node = symbolTable[LITERAL];
|
|
1361
|
+
} else if (isReference(token)) {
|
|
1362
|
+
node = symbolTable[REFERENCE];
|
|
1363
|
+
} else if (isFunction(token)) {
|
|
1364
|
+
node = symbolTable[FUNCTION2];
|
|
1365
|
+
} else {
|
|
1366
|
+
halt(`Unexpected ${token.type} token: ${token.value}`);
|
|
1367
|
+
}
|
|
1368
|
+
currentNode = Object.create(node);
|
|
1369
|
+
currentNode.type = token.type;
|
|
1370
|
+
currentNode.value = token.value;
|
|
1371
|
+
if (token.loc) {
|
|
1372
|
+
currentNode.loc = [...token.loc];
|
|
1373
|
+
}
|
|
1374
|
+
return currentNode;
|
|
1375
|
+
}
|
|
1376
|
+
function expression(rbp) {
|
|
1377
|
+
let t = currentNode;
|
|
1378
|
+
advance(null, t);
|
|
1379
|
+
let left = t.nud();
|
|
1380
|
+
while (rbp < currentNode.lbp) {
|
|
1381
|
+
t = currentNode;
|
|
1382
|
+
advance(null, t);
|
|
1383
|
+
left = t.led(left);
|
|
1384
|
+
}
|
|
1385
|
+
return left;
|
|
1386
|
+
}
|
|
1387
|
+
var original_symbol = {
|
|
1388
|
+
// null denotation
|
|
1389
|
+
nud: () => halt("Invalid syntax"),
|
|
1390
|
+
// Undefined
|
|
1391
|
+
// left denotation
|
|
1392
|
+
led: () => halt("Missing operator")
|
|
1393
|
+
};
|
|
1394
|
+
function symbol(id, bp = 0) {
|
|
1395
|
+
let s = symbolTable[id];
|
|
1396
|
+
if (s) {
|
|
1397
|
+
if (bp >= s.lbp) {
|
|
1398
|
+
s.lbp = bp;
|
|
1399
|
+
}
|
|
1400
|
+
} else {
|
|
1401
|
+
s = { ...original_symbol };
|
|
1402
|
+
s.id = id;
|
|
1403
|
+
s.value = id;
|
|
1404
|
+
s.lbp = bp;
|
|
1405
|
+
symbolTable[id] = s;
|
|
1406
|
+
}
|
|
1407
|
+
return s;
|
|
1408
|
+
}
|
|
1409
|
+
function infix(id, bp, led) {
|
|
1410
|
+
const s = symbol(id, bp);
|
|
1411
|
+
s.led = led || function(left) {
|
|
1412
|
+
this.type = BINARY;
|
|
1413
|
+
this.operator = this.value;
|
|
1414
|
+
delete this.value;
|
|
1415
|
+
const right = expression(bp);
|
|
1416
|
+
this.arguments = [left, right];
|
|
1417
|
+
if (this.loc) {
|
|
1418
|
+
this.loc = [left.loc[0], right.loc[1]];
|
|
1419
|
+
}
|
|
1420
|
+
return this;
|
|
1421
|
+
};
|
|
1422
|
+
return s;
|
|
1423
|
+
}
|
|
1424
|
+
function postfix(id, led) {
|
|
1425
|
+
const s = symbol(id, 0);
|
|
1426
|
+
s.lbp = 70;
|
|
1427
|
+
s.led = led || function(left) {
|
|
1428
|
+
this.type = UNARY;
|
|
1429
|
+
this.operator = this.value;
|
|
1430
|
+
delete this.value;
|
|
1431
|
+
this.arguments = [left];
|
|
1432
|
+
if (this.loc) {
|
|
1433
|
+
this.loc[0] = left.loc[0];
|
|
1434
|
+
}
|
|
1435
|
+
return this;
|
|
1436
|
+
};
|
|
1437
|
+
return s;
|
|
1438
|
+
}
|
|
1439
|
+
function prefix(id, nud) {
|
|
1440
|
+
const s = symbol(id);
|
|
1441
|
+
s.nud = nud || function() {
|
|
1442
|
+
this.type = UNARY;
|
|
1443
|
+
this.operator = this.value;
|
|
1444
|
+
delete this.value;
|
|
1445
|
+
const subexpr = expression(70);
|
|
1446
|
+
this.arguments = [subexpr];
|
|
1447
|
+
if (this.loc) {
|
|
1448
|
+
this.loc[1] = subexpr.loc[1];
|
|
1449
|
+
}
|
|
1450
|
+
return this;
|
|
1451
|
+
};
|
|
1452
|
+
return s;
|
|
1453
|
+
}
|
|
1454
|
+
function rangeInfix(id, bp) {
|
|
1455
|
+
return infix(id, bp, function(left) {
|
|
1456
|
+
if (!isReferenceNode(left)) {
|
|
1457
|
+
halt(`Unexpected ${id} operator`);
|
|
1458
|
+
}
|
|
1459
|
+
const right = expression(bp);
|
|
1460
|
+
if (!isReferenceNode(right)) {
|
|
1461
|
+
halt(`Unexpected ${currentNode.type} following ${this.id}`);
|
|
1462
|
+
}
|
|
1463
|
+
this.type = BINARY;
|
|
1464
|
+
this.operator = this.value.trim() ? this.value : " ";
|
|
1465
|
+
delete this.value;
|
|
1466
|
+
this.arguments = [left, right];
|
|
1467
|
+
if (this.loc) {
|
|
1468
|
+
this.loc = [left.loc[0], right.loc[1]];
|
|
1469
|
+
}
|
|
1470
|
+
return this;
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
symbol(END2);
|
|
1474
|
+
rangeInfix(":", 80);
|
|
1475
|
+
var comma = rangeInfix(",", 80);
|
|
1476
|
+
rangeInfix(WHITESPACE2, 80);
|
|
1477
|
+
var unionRefs = (enable) => {
|
|
1478
|
+
const currState = comma.lbp > 0;
|
|
1479
|
+
if (enable != null) {
|
|
1480
|
+
comma.lbp = enable ? 80 : 0;
|
|
1481
|
+
}
|
|
1482
|
+
return currState;
|
|
1483
|
+
};
|
|
1484
|
+
postfix("%");
|
|
1485
|
+
postfix("#", function(left) {
|
|
1486
|
+
if (!isReferenceNode(left)) {
|
|
1487
|
+
halt("# expects a reference");
|
|
1488
|
+
}
|
|
1489
|
+
this.type = UNARY;
|
|
1490
|
+
this.operator = this.value;
|
|
1491
|
+
delete this.value;
|
|
1492
|
+
this.arguments = [left];
|
|
1493
|
+
return this;
|
|
1494
|
+
});
|
|
1495
|
+
prefix("+");
|
|
1496
|
+
prefix("-");
|
|
1497
|
+
prefix("@");
|
|
1498
|
+
infix("^", 50);
|
|
1499
|
+
infix("*", 40);
|
|
1500
|
+
infix("/", 40);
|
|
1501
|
+
infix("+", 30);
|
|
1502
|
+
infix("-", 30);
|
|
1503
|
+
infix("&", 20);
|
|
1504
|
+
infix("=", 10);
|
|
1505
|
+
infix("<", 10);
|
|
1506
|
+
infix(">", 10);
|
|
1507
|
+
infix("<=", 10);
|
|
1508
|
+
infix(">=", 10);
|
|
1509
|
+
infix("<>", 10);
|
|
1510
|
+
symbol(LITERAL).nud = function() {
|
|
1511
|
+
const { type, value } = this;
|
|
1512
|
+
this.type = LITERAL;
|
|
1513
|
+
this.raw = value;
|
|
1514
|
+
if (type === NUMBER) {
|
|
1515
|
+
this.value = +value;
|
|
1516
|
+
} else if (type === BOOLEAN) {
|
|
1517
|
+
this.value = value.toUpperCase() === "TRUE";
|
|
1518
|
+
} else if (type === ERROR) {
|
|
1519
|
+
this.type = ERROR_LITERAL;
|
|
1520
|
+
this.value = value.toUpperCase();
|
|
1521
|
+
} else if (type === STRING) {
|
|
1522
|
+
this.value = value.slice(1, -1).replace(/""/g, '"');
|
|
1523
|
+
} else {
|
|
1524
|
+
throw new Error("Unsupported literal type: " + type);
|
|
1525
|
+
}
|
|
1526
|
+
return this;
|
|
1527
|
+
};
|
|
1528
|
+
symbol(REFERENCE).nud = function() {
|
|
1529
|
+
if (this.type === REF_NAMED) {
|
|
1530
|
+
this.kind = "name";
|
|
1531
|
+
} else if (this.type === REF_STRUCT) {
|
|
1532
|
+
this.kind = "table";
|
|
1533
|
+
} else if (this.type === REF_BEAM) {
|
|
1534
|
+
this.kind = "beam";
|
|
1535
|
+
} else {
|
|
1536
|
+
this.kind = "range";
|
|
1537
|
+
}
|
|
1538
|
+
this.type = REFERENCE;
|
|
1539
|
+
return this;
|
|
1540
|
+
};
|
|
1541
|
+
symbol(")");
|
|
1542
|
+
prefix("(", function() {
|
|
1543
|
+
const prevState = unionRefs(true);
|
|
1544
|
+
const e = expression(0);
|
|
1545
|
+
advance(")", e);
|
|
1546
|
+
unionRefs(prevState);
|
|
1547
|
+
return e;
|
|
1548
|
+
});
|
|
1549
|
+
symbol(FUNCTION2).nud = function() {
|
|
1550
|
+
return this;
|
|
1551
|
+
};
|
|
1552
|
+
infix("(", 90, function(left) {
|
|
1553
|
+
let callee = {
|
|
1554
|
+
type: IDENTIFIER,
|
|
1555
|
+
name: left.value
|
|
1556
|
+
};
|
|
1557
|
+
if (left.id !== FUNCTION2) {
|
|
1558
|
+
if (left.type === LAMBDA || // Excel only allows calls to "names" and ref functions. Since we don't
|
|
1559
|
+
// differentiate between the two (this requires a table of function names)
|
|
1560
|
+
// we're overly permissive here:
|
|
1561
|
+
left.type === CALL || left.type === LET || left.type === REFERENCE || left.type === UNARY && left.value === "#" || // Because it's really SINGLE(...)()
|
|
1562
|
+
left.type === ERROR_LITERAL && left.value === "#REF!") {
|
|
1563
|
+
callee = left;
|
|
1564
|
+
} else {
|
|
1565
|
+
halt("Unexpected call", tokenIndex - 1);
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
const lcFn = left.value.toLowerCase();
|
|
1569
|
+
if (lcFn === "lambda") {
|
|
1570
|
+
return parseLambda.call(this, left);
|
|
1571
|
+
}
|
|
1572
|
+
if (lcFn === "let") {
|
|
1573
|
+
return parseLet.call(this, left);
|
|
1574
|
+
}
|
|
1575
|
+
const args = [];
|
|
1576
|
+
let lastWasComma = false;
|
|
1577
|
+
if (currentNode.id !== ")") {
|
|
1578
|
+
const prevState = unionRefs(false);
|
|
1579
|
+
while (currentNode.id !== ")") {
|
|
1580
|
+
if (isWhitespace(currentNode)) {
|
|
1581
|
+
advance();
|
|
1582
|
+
}
|
|
1583
|
+
if (currentNode.id === ",") {
|
|
1584
|
+
args.push(null);
|
|
1585
|
+
lastWasComma = true;
|
|
1586
|
+
advance();
|
|
1587
|
+
} else {
|
|
1588
|
+
const arg = expression(0);
|
|
1589
|
+
args.push(arg);
|
|
1590
|
+
lastWasComma = false;
|
|
1591
|
+
if (currentNode.id === ",") {
|
|
1592
|
+
advance(",");
|
|
1593
|
+
lastWasComma = true;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
unionRefs(prevState);
|
|
1598
|
+
}
|
|
1599
|
+
if (lastWasComma) {
|
|
1600
|
+
args.push(null);
|
|
1601
|
+
}
|
|
1602
|
+
const closeParen = currentNode;
|
|
1603
|
+
delete this.value;
|
|
1604
|
+
this.type = CALL;
|
|
1605
|
+
this.callee = callee;
|
|
1606
|
+
if (left.loc) {
|
|
1607
|
+
this.callee.loc = [...left.loc];
|
|
1608
|
+
}
|
|
1609
|
+
this.arguments = args;
|
|
1610
|
+
if (left.loc) {
|
|
1611
|
+
this.loc = [left.loc[0], closeParen.loc[1]];
|
|
1612
|
+
}
|
|
1613
|
+
advance(")", this);
|
|
1614
|
+
return this;
|
|
1615
|
+
});
|
|
1616
|
+
function parseLambda(left) {
|
|
1617
|
+
const args = [];
|
|
1618
|
+
const argNames = {};
|
|
1619
|
+
let body;
|
|
1620
|
+
let done = false;
|
|
1621
|
+
const prevState = unionRefs(false);
|
|
1622
|
+
if (currentNode.id !== ")") {
|
|
1623
|
+
while (!done) {
|
|
1624
|
+
if (isWhitespace(currentNode)) {
|
|
1625
|
+
advance();
|
|
1626
|
+
}
|
|
1627
|
+
const argTokenIndex = tokenIndex;
|
|
1628
|
+
const arg = expression(0);
|
|
1629
|
+
if (currentNode.id === ",") {
|
|
1630
|
+
if (arg.type === REFERENCE && arg.kind === "name") {
|
|
1631
|
+
const currName = arg.value.toLowerCase();
|
|
1632
|
+
if (currName in argNames) {
|
|
1633
|
+
halt("Duplicate name: " + arg.value);
|
|
1634
|
+
}
|
|
1635
|
+
argNames[currName] = 1;
|
|
1636
|
+
const a = { type: IDENTIFIER, name: arg.value };
|
|
1637
|
+
if (arg.loc) {
|
|
1638
|
+
a.loc = arg.loc;
|
|
1639
|
+
}
|
|
1640
|
+
args.push(a);
|
|
1641
|
+
} else {
|
|
1642
|
+
tokenIndex = argTokenIndex;
|
|
1643
|
+
halt("LAMBDA argument is not a name");
|
|
1644
|
+
}
|
|
1645
|
+
advance(",");
|
|
1646
|
+
} else {
|
|
1647
|
+
body = arg;
|
|
1648
|
+
done = true;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
unionRefs(prevState);
|
|
1653
|
+
delete this.value;
|
|
1654
|
+
this.type = LAMBDA;
|
|
1655
|
+
this.params = args;
|
|
1656
|
+
this.body = body || null;
|
|
1657
|
+
if (left.loc) {
|
|
1658
|
+
this.loc = [left.loc[0], currentNode.loc[1]];
|
|
1659
|
+
}
|
|
1660
|
+
advance(")", this);
|
|
1661
|
+
return this;
|
|
1662
|
+
}
|
|
1663
|
+
function parseLet(left) {
|
|
1664
|
+
const args = [];
|
|
1665
|
+
const vals = [];
|
|
1666
|
+
const argNames = {};
|
|
1667
|
+
let body;
|
|
1668
|
+
let argCounter = 0;
|
|
1669
|
+
const addArgument = (arg, lastArg) => {
|
|
1670
|
+
if (body) {
|
|
1671
|
+
halt("Unexpected argument following calculation");
|
|
1672
|
+
}
|
|
1673
|
+
if (lastArg && argCounter >= 2) {
|
|
1674
|
+
body = arg;
|
|
1675
|
+
} else {
|
|
1676
|
+
const wantName = !(argCounter % 2);
|
|
1677
|
+
if (wantName) {
|
|
1678
|
+
if (arg && (arg.type === REFERENCE && arg.kind === "name")) {
|
|
1679
|
+
const currName = arg.value.toLowerCase();
|
|
1680
|
+
if (currName in argNames) {
|
|
1681
|
+
halt("Duplicate name: " + arg.value);
|
|
1682
|
+
}
|
|
1683
|
+
argNames[currName] = 1;
|
|
1684
|
+
args.push({ type: IDENTIFIER, name: arg.value, loc: arg.loc });
|
|
1685
|
+
} else if (argCounter >= 2) {
|
|
1686
|
+
body = arg;
|
|
1687
|
+
} else {
|
|
1688
|
+
halt("Argument is not a name");
|
|
1689
|
+
}
|
|
1690
|
+
} else {
|
|
1691
|
+
vals.push(arg);
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
argCounter++;
|
|
1695
|
+
};
|
|
1696
|
+
const prevState = unionRefs(false);
|
|
1697
|
+
let lastWasComma = false;
|
|
1698
|
+
if (currentNode.id !== ")") {
|
|
1699
|
+
while (currentNode.id !== ")") {
|
|
1700
|
+
if (isWhitespace(currentNode)) {
|
|
1701
|
+
advance();
|
|
1702
|
+
}
|
|
1703
|
+
if (currentNode.id === ",") {
|
|
1704
|
+
addArgument(null);
|
|
1705
|
+
lastWasComma = true;
|
|
1706
|
+
advance();
|
|
1707
|
+
} else {
|
|
1708
|
+
const arg = expression(0);
|
|
1709
|
+
addArgument(arg, currentNode.id !== ",");
|
|
1710
|
+
lastWasComma = false;
|
|
1711
|
+
if (currentNode.id === ",") {
|
|
1712
|
+
advance(",");
|
|
1713
|
+
lastWasComma = true;
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
unionRefs(prevState);
|
|
1718
|
+
}
|
|
1719
|
+
if (lastWasComma) {
|
|
1720
|
+
addArgument(null, true);
|
|
1721
|
+
}
|
|
1722
|
+
if (body === void 0) {
|
|
1723
|
+
halt("Unexpected end of arguments");
|
|
1724
|
+
}
|
|
1725
|
+
unionRefs(prevState);
|
|
1726
|
+
delete this.value;
|
|
1727
|
+
this.type = LET;
|
|
1728
|
+
this.declarations = [];
|
|
1729
|
+
if (!args.length) {
|
|
1730
|
+
halt("Unexpected end of arguments");
|
|
1731
|
+
}
|
|
1732
|
+
for (let i = 0; i < args.length; i++) {
|
|
1733
|
+
const s = {
|
|
1734
|
+
type: LET_DECL,
|
|
1735
|
+
id: args[i],
|
|
1736
|
+
init: vals[i],
|
|
1737
|
+
loc: args[i].loc && [args[i].loc[0], vals[i].loc[1]]
|
|
1738
|
+
};
|
|
1739
|
+
this.declarations.push(s);
|
|
1740
|
+
}
|
|
1741
|
+
this.body = body;
|
|
1742
|
+
if (left.loc) {
|
|
1743
|
+
this.loc = [left.loc[0], currentNode.loc[1]];
|
|
1744
|
+
}
|
|
1745
|
+
advance(")", this);
|
|
1746
|
+
return this;
|
|
1747
|
+
}
|
|
1748
|
+
symbol("}");
|
|
1749
|
+
symbol(";");
|
|
1750
|
+
prefix("{", function() {
|
|
1751
|
+
if (currentNode.id === "}") {
|
|
1752
|
+
halt("Unexpected empty array");
|
|
1753
|
+
}
|
|
1754
|
+
let row = [];
|
|
1755
|
+
let done = false;
|
|
1756
|
+
const rows = [row];
|
|
1757
|
+
const prevState = unionRefs(false);
|
|
1758
|
+
while (!done) {
|
|
1759
|
+
if (isWhitespace(currentNode)) {
|
|
1760
|
+
advance();
|
|
1761
|
+
}
|
|
1762
|
+
if (isLiteral(currentNode)) {
|
|
1763
|
+
row.push(symbolTable[LITERAL].nud.call(currentNode));
|
|
1764
|
+
advance();
|
|
1765
|
+
} else if (permitArrayRanges && isReferenceNode(currentNode)) {
|
|
1766
|
+
row.push(symbolTable[REFERENCE].nud.call(currentNode));
|
|
1767
|
+
advance();
|
|
1768
|
+
} else if (permitArrayCalls && isFunction(currentNode)) {
|
|
1769
|
+
const arg = expression(0);
|
|
1770
|
+
row.push(arg);
|
|
1771
|
+
} else {
|
|
1772
|
+
halt(`Unexpected ${currentNode.type} in array: ${currentNode.value}`);
|
|
1773
|
+
}
|
|
1774
|
+
if (currentNode.id === ",") {
|
|
1775
|
+
advance(",");
|
|
1776
|
+
} else if (currentNode.id === ";") {
|
|
1777
|
+
advance(";");
|
|
1778
|
+
row = [];
|
|
1779
|
+
rows.push(row);
|
|
1780
|
+
} else {
|
|
1781
|
+
done = true;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
const closingBrace = currentNode;
|
|
1785
|
+
advance("}");
|
|
1786
|
+
unionRefs(prevState);
|
|
1787
|
+
this.type = ARRAY;
|
|
1788
|
+
this.elements = rows;
|
|
1789
|
+
if (this.loc) {
|
|
1790
|
+
this.loc[1] = closingBrace.loc[1];
|
|
1791
|
+
}
|
|
1792
|
+
delete this.value;
|
|
1793
|
+
return this;
|
|
1794
|
+
});
|
|
1795
|
+
function parse(tokenlist, options = {}) {
|
|
1796
|
+
if (!Array.isArray(tokenlist)) {
|
|
1797
|
+
throw new Error("Parse requires an array of tokens.");
|
|
1798
|
+
}
|
|
1799
|
+
permitArrayRanges = options?.permitArrayRanges;
|
|
1800
|
+
permitArrayCalls = options?.permitArrayCalls;
|
|
1801
|
+
looseRefCalls = options?.looseRefCalls;
|
|
1802
|
+
tokens = tokenlist;
|
|
1803
|
+
tokenIndex = 0;
|
|
1804
|
+
while (isWhitespace(tokens[tokenIndex]) || isFxPrefix(tokens[tokenIndex])) {
|
|
1805
|
+
tokenIndex++;
|
|
1806
|
+
}
|
|
1807
|
+
advance();
|
|
1808
|
+
unionRefs(true);
|
|
1809
|
+
const root = expression(0);
|
|
1810
|
+
advance(END2);
|
|
1811
|
+
return root;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// lib/stringifyPrefix.ts
|
|
1815
|
+
var reBannedChars = /[^0-9A-Za-z._¡¤§¨ª\u00ad¯-\uffff]/;
|
|
1816
|
+
function stringifyPrefix(ref) {
|
|
1817
|
+
let pre = "";
|
|
1818
|
+
let quote = 0;
|
|
1819
|
+
let nth = 0;
|
|
1820
|
+
const context = ref.context || [];
|
|
1821
|
+
for (let i = context.length; i > -1; i--) {
|
|
1822
|
+
const scope = context[i];
|
|
1823
|
+
if (scope) {
|
|
1824
|
+
const part = nth % 2 ? "[" + scope + "]" : scope;
|
|
1825
|
+
pre = part + pre;
|
|
1826
|
+
quote += +reBannedChars.test(scope);
|
|
1827
|
+
nth++;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
if (quote) {
|
|
1831
|
+
pre = "'" + pre.replace(/'/g, "''") + "'";
|
|
1832
|
+
}
|
|
1833
|
+
return pre ? pre + "!" : pre;
|
|
1834
|
+
}
|
|
1835
|
+
function stringifyPrefixXlsx(ref) {
|
|
1836
|
+
let pre = "";
|
|
1837
|
+
let quote = 0;
|
|
1838
|
+
const { workbookName, sheetName } = ref;
|
|
1839
|
+
if (workbookName) {
|
|
1840
|
+
pre += "[" + workbookName + "]";
|
|
1841
|
+
quote += +reBannedChars.test(workbookName);
|
|
1842
|
+
}
|
|
1843
|
+
if (sheetName) {
|
|
1844
|
+
pre += sheetName;
|
|
1845
|
+
quote += +reBannedChars.test(sheetName);
|
|
1846
|
+
}
|
|
1847
|
+
if (quote) {
|
|
1848
|
+
pre = "'" + pre.replace(/'/g, "''") + "'";
|
|
1849
|
+
}
|
|
1850
|
+
return pre ? pre + "!" : pre;
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// lib/a1.ts
|
|
1854
|
+
function rangeOperator(trim) {
|
|
1855
|
+
if (trim === "both") {
|
|
1856
|
+
return ".:.";
|
|
1857
|
+
} else if (trim === "head") {
|
|
1858
|
+
return ".:";
|
|
1859
|
+
} else if (trim === "tail") {
|
|
1860
|
+
return ":.";
|
|
1861
|
+
}
|
|
1862
|
+
return ":";
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
// lib/stringifyR1C1Range.ts
|
|
1866
|
+
var clamp = (min, val, max) => Math.min(Math.max(val, min), max);
|
|
1867
|
+
function toCoord(value, isAbs) {
|
|
1868
|
+
if (isAbs) {
|
|
1869
|
+
return String(value + 1);
|
|
1870
|
+
}
|
|
1871
|
+
return value ? "[" + value + "]" : "";
|
|
1872
|
+
}
|
|
1873
|
+
function stringifyR1C1Range(range) {
|
|
1874
|
+
let { r0, c0, r1, c1 } = range;
|
|
1875
|
+
const { $c0, $c1, $r0, $r1 } = range;
|
|
1876
|
+
const nullR0 = r0 == null;
|
|
1877
|
+
const nullC0 = c0 == null;
|
|
1878
|
+
let nullR1 = r1 == null;
|
|
1879
|
+
let nullC1 = c1 == null;
|
|
1880
|
+
const op = rangeOperator(range.trim);
|
|
1881
|
+
const hasTrim = !!range.trim;
|
|
1882
|
+
r0 = clamp($r0 ? 0 : -MAX_ROWS, r0 | 0, MAX_ROWS);
|
|
1883
|
+
c0 = clamp($c0 ? 0 : -MAX_COLS, c0 | 0, MAX_COLS);
|
|
1884
|
+
if (!nullR0 && nullR1 && !nullC0 && nullC1) {
|
|
1885
|
+
r1 = r0;
|
|
1886
|
+
nullR1 = false;
|
|
1887
|
+
c1 = c0;
|
|
1888
|
+
nullC1 = false;
|
|
1889
|
+
} else {
|
|
1890
|
+
r1 = clamp($r1 ? 0 : -MAX_ROWS, r1 | 0, MAX_ROWS);
|
|
1891
|
+
c1 = clamp($c1 ? 0 : -MAX_COLS, c1 | 0, MAX_COLS);
|
|
1892
|
+
}
|
|
1893
|
+
const allRows = r0 === 0 && r1 >= MAX_ROWS;
|
|
1894
|
+
if (allRows && !nullC0 && !nullC1 || nullR0 && nullR1) {
|
|
1895
|
+
const a = toCoord(c0, $c0);
|
|
1896
|
+
const b = toCoord(c1, $c1);
|
|
1897
|
+
return "C" + (a === b && !hasTrim ? a : a + op + "C" + b);
|
|
1898
|
+
}
|
|
1899
|
+
const allCols = c0 === 0 && c1 >= MAX_COLS;
|
|
1900
|
+
if (allCols && !nullR0 && !nullR1 || nullC0 && nullC1) {
|
|
1901
|
+
const a = toCoord(r0, $r0);
|
|
1902
|
+
const b = toCoord(r1, $r1);
|
|
1903
|
+
return "R" + (a === b && !hasTrim ? a : a + op + "R" + b);
|
|
1904
|
+
}
|
|
1905
|
+
const s_r0 = toCoord(r0, $r0);
|
|
1906
|
+
const s_r1 = toCoord(r1, $r1);
|
|
1907
|
+
const s_c0 = toCoord(c0, $c0);
|
|
1908
|
+
const s_c1 = toCoord(c1, $c1);
|
|
1909
|
+
if (nullR0 || nullR1 || nullC0 || nullC1) {
|
|
1910
|
+
return (nullR0 ? "" : "R" + s_r0) + (nullC0 ? "" : "C" + s_c0) + op + (nullR1 ? "" : "R" + s_r1) + (nullC1 ? "" : "C" + s_c1);
|
|
1911
|
+
}
|
|
1912
|
+
if (s_r0 !== s_r1 || s_c0 !== s_c1) {
|
|
1913
|
+
return "R" + s_r0 + "C" + s_c0 + op + "R" + s_r1 + "C" + s_c1;
|
|
1914
|
+
}
|
|
1915
|
+
return "R" + s_r0 + "C" + s_c0;
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
// lib/stringifyR1C1Ref.ts
|
|
1919
|
+
function stringifyR1C1Ref(refObject) {
|
|
1920
|
+
const prefix2 = stringifyPrefix(refObject);
|
|
1921
|
+
return prefix2 + ("name" in refObject ? refObject.name : stringifyR1C1Range(refObject.range));
|
|
1922
|
+
}
|
|
1923
|
+
function stringifyR1C1RefXlsx(refObject) {
|
|
1924
|
+
const prefix2 = stringifyPrefixXlsx(refObject);
|
|
1925
|
+
return prefix2 + ("name" in refObject ? refObject.name : stringifyR1C1Range(refObject.range));
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
// lib/parseA1Range.ts
|
|
1929
|
+
var CHAR_DOLLAR = 36;
|
|
1930
|
+
var CHAR_PERIOD = 46;
|
|
1931
|
+
var CHAR_COLON = 58;
|
|
1932
|
+
var CHAR_A_LC = 97;
|
|
1933
|
+
var CHAR_A_UC = 65;
|
|
1934
|
+
var CHAR_Z_LC = 122;
|
|
1935
|
+
var CHAR_Z_UC = 90;
|
|
1936
|
+
var CHAR_0 = 48;
|
|
1937
|
+
var CHAR_1 = 49;
|
|
1938
|
+
var CHAR_9 = 57;
|
|
1939
|
+
function advRangeOp2(str, pos) {
|
|
1940
|
+
const c0 = str.charCodeAt(pos);
|
|
1941
|
+
if (c0 === CHAR_PERIOD) {
|
|
1942
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
1943
|
+
if (c1 === CHAR_COLON) {
|
|
1944
|
+
return str.charCodeAt(pos + 2) === CHAR_PERIOD ? [3, "both"] : [2, "head"];
|
|
1945
|
+
}
|
|
1946
|
+
} else if (c0 === CHAR_COLON) {
|
|
1947
|
+
const c1 = str.charCodeAt(pos + 1);
|
|
1948
|
+
return c1 === CHAR_PERIOD ? [2, "tail"] : [1, ""];
|
|
1949
|
+
}
|
|
1950
|
+
return [0, ""];
|
|
1951
|
+
}
|
|
1952
|
+
function advA1Col2(str, pos) {
|
|
1953
|
+
const start = pos;
|
|
1954
|
+
const lock = str.charCodeAt(pos) === CHAR_DOLLAR;
|
|
1955
|
+
if (lock) {
|
|
1956
|
+
pos++;
|
|
1957
|
+
}
|
|
1958
|
+
const stop = pos + 3;
|
|
1959
|
+
let col = 0;
|
|
1960
|
+
do {
|
|
1961
|
+
const c = str.charCodeAt(pos);
|
|
1962
|
+
if (c >= CHAR_A_UC && c <= CHAR_Z_UC) {
|
|
1963
|
+
col = 26 * col + c - (CHAR_A_UC - 1);
|
|
1964
|
+
pos++;
|
|
1965
|
+
} else if (c >= CHAR_A_LC && c <= CHAR_Z_LC) {
|
|
1966
|
+
col = 26 * col + c - (CHAR_A_LC - 1);
|
|
1967
|
+
pos++;
|
|
1968
|
+
} else {
|
|
1969
|
+
break;
|
|
1970
|
+
}
|
|
1971
|
+
} while (pos < stop && pos < str.length);
|
|
1972
|
+
return col && col <= MAX_COLS + 1 ? [pos - start, col - 1, lock] : [0, 0, false];
|
|
1973
|
+
}
|
|
1974
|
+
function advA1Row2(str, pos) {
|
|
1975
|
+
const start = pos;
|
|
1976
|
+
const lock = str.charCodeAt(pos) === CHAR_DOLLAR;
|
|
1977
|
+
if (lock) {
|
|
1978
|
+
pos++;
|
|
1979
|
+
}
|
|
1980
|
+
const stop = pos + 7;
|
|
1981
|
+
let row = 0;
|
|
1982
|
+
let c = str.charCodeAt(pos);
|
|
1983
|
+
if (c >= CHAR_1 && c <= CHAR_9) {
|
|
1984
|
+
row = row * 10 + c - CHAR_0;
|
|
1985
|
+
pos++;
|
|
1986
|
+
do {
|
|
1987
|
+
c = str.charCodeAt(pos);
|
|
1988
|
+
if (c >= CHAR_0 && c <= CHAR_9) {
|
|
1989
|
+
row = row * 10 + c - CHAR_0;
|
|
1990
|
+
pos++;
|
|
1991
|
+
} else {
|
|
1992
|
+
break;
|
|
1993
|
+
}
|
|
1994
|
+
} while (pos < stop && pos < str.length);
|
|
1995
|
+
}
|
|
1996
|
+
return row && row <= MAX_ROWS + 1 ? [pos - start, row - 1, lock] : [0, 0, false];
|
|
1997
|
+
}
|
|
1998
|
+
function makeRange(top, $top, left, $left, bottom, $bottom, right, $right, trim) {
|
|
1999
|
+
if (right != null && (left == null || left != null && right < left)) {
|
|
2000
|
+
[left, right, $left, $right] = [right, left, $right, $left];
|
|
2001
|
+
}
|
|
2002
|
+
if (bottom != null && (top == null || top != null && bottom < top)) {
|
|
2003
|
+
[top, bottom, $top, $bottom] = [bottom, top, $bottom, $top];
|
|
2004
|
+
}
|
|
2005
|
+
const range = { top, left, bottom, right, $top, $left, $bottom, $right };
|
|
2006
|
+
if (trim) {
|
|
2007
|
+
range.trim = trim;
|
|
2008
|
+
}
|
|
2009
|
+
return range;
|
|
2010
|
+
}
|
|
2011
|
+
function parseA1Range(rangeString, allowTernary = true) {
|
|
2012
|
+
let p = 0;
|
|
2013
|
+
const [leftChars, left, $left] = advA1Col2(rangeString, p);
|
|
2014
|
+
let right = 0;
|
|
2015
|
+
let $right = false;
|
|
2016
|
+
let bottom = 0;
|
|
2017
|
+
let $bottom = false;
|
|
2018
|
+
let rightChars;
|
|
2019
|
+
let bottomChars;
|
|
2020
|
+
if (leftChars) {
|
|
2021
|
+
p += leftChars;
|
|
2022
|
+
const [topChars, top, $top] = advA1Row2(rangeString, p);
|
|
2023
|
+
p += topChars;
|
|
2024
|
+
const [op, trim] = advRangeOp2(rangeString, p);
|
|
2025
|
+
if (op) {
|
|
2026
|
+
p += op;
|
|
2027
|
+
[rightChars, right, $right] = advA1Col2(rangeString, p);
|
|
2028
|
+
p += rightChars;
|
|
2029
|
+
[bottomChars, bottom, $bottom] = advA1Row2(rangeString, p);
|
|
2030
|
+
p += bottomChars;
|
|
2031
|
+
if (topChars && bottomChars && rightChars) {
|
|
2032
|
+
if (p === rangeString.length) {
|
|
2033
|
+
return makeRange(top, $top, left, $left, bottom, $bottom, right, $right, trim);
|
|
2034
|
+
}
|
|
2035
|
+
} else if (!topChars && !bottomChars) {
|
|
2036
|
+
if (p === rangeString.length) {
|
|
2037
|
+
return makeRange(null, false, left, $left, null, false, right, $right, trim);
|
|
2038
|
+
}
|
|
2039
|
+
} else if (allowTernary && (bottomChars || rightChars) && p === rangeString.length) {
|
|
2040
|
+
if (!topChars) {
|
|
2041
|
+
return makeRange(null, false, left, $left, bottom, $bottom, right, $right, trim);
|
|
2042
|
+
} else if (!bottomChars) {
|
|
2043
|
+
return makeRange(top, $top, left, $left, null, false, right, $right, trim);
|
|
2044
|
+
} else {
|
|
2045
|
+
return makeRange(top, $top, left, $left, bottom, $bottom, null, false, trim);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
if (topChars && p === rangeString.length) {
|
|
2050
|
+
return makeRange(top, $top, left, $left, top, $top, left, $left, trim);
|
|
2051
|
+
}
|
|
2052
|
+
} else {
|
|
2053
|
+
const [topChars, top, $top] = advA1Row2(rangeString, p);
|
|
2054
|
+
if (topChars) {
|
|
2055
|
+
p += topChars;
|
|
2056
|
+
const [op, trim] = advRangeOp2(rangeString, p);
|
|
2057
|
+
if (op) {
|
|
2058
|
+
p += op;
|
|
2059
|
+
[rightChars, right, $right] = advA1Col2(rangeString, p);
|
|
2060
|
+
p += rightChars;
|
|
2061
|
+
[bottomChars, bottom, $bottom] = advA1Row2(rangeString, p);
|
|
2062
|
+
p += bottomChars;
|
|
2063
|
+
if (rightChars && bottomChars && allowTernary) {
|
|
2064
|
+
if (p === rangeString.length) {
|
|
2065
|
+
return makeRange(top, $top, null, false, bottom, $bottom, right, $right, trim);
|
|
2066
|
+
}
|
|
2067
|
+
} else if (!rightChars && bottomChars) {
|
|
2068
|
+
if (p === rangeString.length) {
|
|
2069
|
+
return makeRange(top, $top, null, false, bottom, $bottom, null, false, trim);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
// lib/stringifyTokens.ts
|
|
2078
|
+
function stringifyTokens(tokens2) {
|
|
2079
|
+
let s = "";
|
|
2080
|
+
for (const token of tokens2) {
|
|
2081
|
+
s += token.value;
|
|
2082
|
+
}
|
|
2083
|
+
return s;
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
// lib/cloneToken.ts
|
|
2087
|
+
function cloneToken(token) {
|
|
2088
|
+
const newToken = {
|
|
2089
|
+
type: token.type,
|
|
2090
|
+
value: token.value
|
|
2091
|
+
};
|
|
2092
|
+
if (token.loc) {
|
|
2093
|
+
newToken.loc = [token.loc[0], token.loc[1]];
|
|
2094
|
+
}
|
|
2095
|
+
if (token.unterminated != null) {
|
|
2096
|
+
newToken.unterminated = token.unterminated;
|
|
2097
|
+
}
|
|
2098
|
+
if (typeof token.index === "number") {
|
|
2099
|
+
newToken.index = token.index;
|
|
2100
|
+
if (typeof token.groupId === "string") {
|
|
2101
|
+
newToken.groupId = token.groupId;
|
|
2102
|
+
}
|
|
2103
|
+
if (typeof token.depth === "number") {
|
|
2104
|
+
newToken.depth = token.depth;
|
|
2105
|
+
}
|
|
2106
|
+
if (typeof token.error === "boolean") {
|
|
2107
|
+
newToken.error = token.error;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
return newToken;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
// lib/parseRef.ts
|
|
2114
|
+
function splitPrefix(str, stringsOnly = false) {
|
|
2115
|
+
let inBrace = false;
|
|
2116
|
+
let currStr = "";
|
|
2117
|
+
const parts = [];
|
|
2118
|
+
const flush = () => {
|
|
2119
|
+
if (currStr) {
|
|
2120
|
+
parts.push(
|
|
2121
|
+
stringsOnly ? currStr : { value: currStr, braced: inBrace }
|
|
2122
|
+
);
|
|
2123
|
+
}
|
|
2124
|
+
currStr = "";
|
|
2125
|
+
};
|
|
2126
|
+
for (let i = 0; i < str.length; i++) {
|
|
2127
|
+
const char = str[i];
|
|
2128
|
+
if (char === "[") {
|
|
2129
|
+
flush();
|
|
2130
|
+
inBrace = true;
|
|
2131
|
+
} else if (char === "]") {
|
|
2132
|
+
flush();
|
|
2133
|
+
inBrace = false;
|
|
2134
|
+
} else {
|
|
2135
|
+
currStr += char;
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
flush();
|
|
2139
|
+
return parts;
|
|
2140
|
+
}
|
|
2141
|
+
function splitContext(contextString, data, xlsx) {
|
|
2142
|
+
const ctx = splitPrefix(contextString, !xlsx);
|
|
2143
|
+
if (xlsx) {
|
|
2144
|
+
if (ctx.length > 1) {
|
|
2145
|
+
data.workbookName = ctx[ctx.length - 2].value;
|
|
2146
|
+
data.sheetName = ctx[ctx.length - 1].value;
|
|
2147
|
+
} else if (ctx.length === 1) {
|
|
2148
|
+
const item = ctx[0];
|
|
2149
|
+
if (item.braced) {
|
|
2150
|
+
data.workbookName = item.value;
|
|
2151
|
+
} else {
|
|
2152
|
+
data.sheetName = item.value;
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
} else {
|
|
2156
|
+
data.context = ctx;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
var unquote = (d) => d.slice(1, -1).replace(/''/g, "'");
|
|
2160
|
+
var pRangeOp = (t, data) => {
|
|
2161
|
+
const value = t?.value;
|
|
2162
|
+
if (value === ":" || value === ".:" || value === ":." || value === ".:.") {
|
|
2163
|
+
data.operator = value;
|
|
2164
|
+
return 1;
|
|
2165
|
+
}
|
|
2166
|
+
};
|
|
2167
|
+
var pRange = (t, data) => {
|
|
2168
|
+
if (t?.type === REF_RANGE) {
|
|
2169
|
+
data.r0 = t.value;
|
|
2170
|
+
return 1;
|
|
2171
|
+
}
|
|
2172
|
+
};
|
|
2173
|
+
var pPartial = (t, data) => {
|
|
2174
|
+
if (t?.type === REF_TERNARY) {
|
|
2175
|
+
data.r0 = t.value;
|
|
2176
|
+
return 1;
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
var pRange2 = (t, data) => {
|
|
2180
|
+
if (t?.type === REF_RANGE) {
|
|
2181
|
+
data.r1 = t.value;
|
|
2182
|
+
return 1;
|
|
2183
|
+
}
|
|
2184
|
+
};
|
|
2185
|
+
var pBang = (t) => {
|
|
2186
|
+
if (t?.type === OPERATOR && t.value === "!") {
|
|
2187
|
+
return 1;
|
|
2188
|
+
}
|
|
2189
|
+
};
|
|
2190
|
+
var pBeam = (t, data) => {
|
|
2191
|
+
if (t?.type === REF_BEAM) {
|
|
2192
|
+
data.r0 = t.value;
|
|
2193
|
+
return 1;
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2196
|
+
var pStrucured = (t, data) => {
|
|
2197
|
+
if (t.type === REF_STRUCT) {
|
|
2198
|
+
data.struct = t.value;
|
|
2199
|
+
return 1;
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
var pContext = (t, data, xlsx) => {
|
|
2203
|
+
const type = t?.type;
|
|
2204
|
+
if (type === CONTEXT) {
|
|
2205
|
+
splitContext(t.value, data, xlsx);
|
|
2206
|
+
return 1;
|
|
2207
|
+
}
|
|
2208
|
+
if (type === CONTEXT_QUOTE) {
|
|
2209
|
+
splitContext(unquote(t.value), data, xlsx);
|
|
2210
|
+
return 1;
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
2213
|
+
var pNamed = (t, data) => {
|
|
2214
|
+
if (t?.type === REF_NAMED) {
|
|
2215
|
+
data.name = t.value;
|
|
2216
|
+
return 1;
|
|
2217
|
+
}
|
|
2218
|
+
};
|
|
2219
|
+
var validRuns = [
|
|
2220
|
+
[pPartial],
|
|
2221
|
+
[pRange, pRangeOp, pRange2],
|
|
2222
|
+
[pRange],
|
|
2223
|
+
[pBeam],
|
|
2224
|
+
[pContext, pBang, pPartial],
|
|
2225
|
+
[pContext, pBang, pRange, pRangeOp, pRange2],
|
|
2226
|
+
[pContext, pBang, pRange],
|
|
2227
|
+
[pContext, pBang, pBeam]
|
|
2228
|
+
];
|
|
2229
|
+
var validRunsNamed = validRuns.concat([
|
|
2230
|
+
[pNamed],
|
|
2231
|
+
[pContext, pBang, pNamed],
|
|
2232
|
+
[pStrucured],
|
|
2233
|
+
[pNamed, pStrucured],
|
|
2234
|
+
[pContext, pBang, pNamed, pStrucured]
|
|
2235
|
+
]);
|
|
2236
|
+
function parseRefCtx(ref, opts = {}) {
|
|
2237
|
+
const options = {
|
|
2238
|
+
withLocation: opts.withLocation ?? false,
|
|
2239
|
+
mergeRefs: opts.mergeRefs ?? false,
|
|
2240
|
+
allowTernary: opts.allowTernary ?? false,
|
|
2241
|
+
allowNamed: opts.allowNamed ?? true,
|
|
2242
|
+
r1c1: opts.r1c1 ?? false
|
|
2243
|
+
};
|
|
2244
|
+
const tokens2 = getTokens(ref, lexersRefs, options);
|
|
2245
|
+
if (tokens2.length && tokens2[0].type === FX_PREFIX) {
|
|
2246
|
+
tokens2.shift();
|
|
2247
|
+
}
|
|
2248
|
+
const runs = options.allowNamed ? validRunsNamed : validRuns;
|
|
2249
|
+
for (const run of runs) {
|
|
2250
|
+
if (run.length === tokens2.length) {
|
|
2251
|
+
const data = {
|
|
2252
|
+
context: [],
|
|
2253
|
+
r0: "",
|
|
2254
|
+
r1: "",
|
|
2255
|
+
name: "",
|
|
2256
|
+
struct: "",
|
|
2257
|
+
operator: ""
|
|
2258
|
+
};
|
|
2259
|
+
const valid = run.every((parse2, i) => parse2(tokens2[i], data, false));
|
|
2260
|
+
if (valid) {
|
|
2261
|
+
return data;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
function parseRefXlsx(ref, opts = {}) {
|
|
2267
|
+
const options = {
|
|
2268
|
+
withLocation: opts.withLocation ?? false,
|
|
2269
|
+
mergeRefs: opts.mergeRefs ?? false,
|
|
2270
|
+
allowTernary: opts.allowTernary ?? false,
|
|
2271
|
+
allowNamed: opts.allowNamed ?? true,
|
|
2272
|
+
r1c1: opts.r1c1 ?? false,
|
|
2273
|
+
xlsx: true
|
|
2274
|
+
};
|
|
2275
|
+
const tokens2 = getTokens(ref, lexersRefs, options);
|
|
2276
|
+
if (tokens2.length && tokens2[0].type === FX_PREFIX) {
|
|
2277
|
+
tokens2.shift();
|
|
2278
|
+
}
|
|
2279
|
+
const runs = options.allowNamed ? validRunsNamed : validRuns;
|
|
2280
|
+
for (const run of runs) {
|
|
2281
|
+
if (run.length === tokens2.length) {
|
|
2282
|
+
const data = {
|
|
2283
|
+
workbookName: "",
|
|
2284
|
+
sheetName: "",
|
|
2285
|
+
r0: "",
|
|
2286
|
+
r1: "",
|
|
2287
|
+
name: "",
|
|
2288
|
+
struct: "",
|
|
2289
|
+
operator: ""
|
|
2290
|
+
};
|
|
2291
|
+
const valid = run.every((parse2, i) => parse2(tokens2[i], data, true));
|
|
2292
|
+
if (valid) {
|
|
2293
|
+
return data;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
// lib/translateToR1C1.ts
|
|
2300
|
+
var calc = (abs, vX, aX) => {
|
|
2301
|
+
if (vX == null) {
|
|
2302
|
+
return null;
|
|
2303
|
+
}
|
|
2304
|
+
return abs ? vX : vX - aX;
|
|
2305
|
+
};
|
|
2306
|
+
var unquote2 = (d) => d.slice(1, -1).replace(/''/g, "'");
|
|
2307
|
+
function quickParseA1(ref) {
|
|
2308
|
+
const split = ref.lastIndexOf("!");
|
|
2309
|
+
const data = {};
|
|
2310
|
+
if (split > -1) {
|
|
2311
|
+
if (ref.startsWith("'")) {
|
|
2312
|
+
splitContext(unquote2(ref.slice(0, split)), data, true);
|
|
2313
|
+
} else {
|
|
2314
|
+
splitContext(ref.slice(0, split), data, true);
|
|
2315
|
+
}
|
|
2316
|
+
data.range = parseA1Range(ref.slice(split + 1));
|
|
2317
|
+
} else {
|
|
2318
|
+
data.range = parseA1Range(ref);
|
|
2319
|
+
}
|
|
2320
|
+
return data;
|
|
2321
|
+
}
|
|
2322
|
+
function translateTokensToR1C1(tokens2, anchorCell) {
|
|
2323
|
+
const anchorRange = parseA1Range(anchorCell);
|
|
2324
|
+
if (!anchorRange) {
|
|
2325
|
+
throw new Error("translateTokensToR1C1 got an invalid anchorCell: " + anchorCell);
|
|
2326
|
+
}
|
|
2327
|
+
const { top, left } = anchorRange;
|
|
2328
|
+
let offsetSkew = 0;
|
|
2329
|
+
const outTokens = [];
|
|
2330
|
+
for (let token of tokens2) {
|
|
2331
|
+
const tokenType = token?.type;
|
|
2332
|
+
if (tokenType === REF_RANGE || tokenType === REF_BEAM || tokenType === REF_TERNARY) {
|
|
2333
|
+
token = cloneToken(token);
|
|
2334
|
+
const tokenValue = token.value;
|
|
2335
|
+
const ref = quickParseA1(tokenValue);
|
|
2336
|
+
const d = ref.range;
|
|
2337
|
+
const range = {};
|
|
2338
|
+
range.r0 = calc(d.$top, d.top, top);
|
|
2339
|
+
range.r1 = calc(d.$bottom, d.bottom, top);
|
|
2340
|
+
range.c0 = calc(d.$left, d.left, left);
|
|
2341
|
+
range.c1 = calc(d.$right, d.right, left);
|
|
2342
|
+
range.$r0 = d.$top;
|
|
2343
|
+
range.$r1 = d.$bottom;
|
|
2344
|
+
range.$c0 = d.$left;
|
|
2345
|
+
range.$c1 = d.$right;
|
|
2346
|
+
if (d.trim) {
|
|
2347
|
+
range.trim = d.trim;
|
|
2348
|
+
}
|
|
2349
|
+
ref.range = range;
|
|
2350
|
+
token.value = stringifyR1C1RefXlsx(ref);
|
|
2351
|
+
if (token.loc) {
|
|
2352
|
+
token.loc[0] += offsetSkew;
|
|
2353
|
+
offsetSkew += token.value.length - tokenValue.length;
|
|
2354
|
+
token.loc[1] += offsetSkew;
|
|
2355
|
+
}
|
|
2356
|
+
} else if (offsetSkew && token.loc) {
|
|
2357
|
+
token = cloneToken(token);
|
|
2358
|
+
token.loc[0] += offsetSkew;
|
|
2359
|
+
token.loc[1] += offsetSkew;
|
|
2360
|
+
}
|
|
2361
|
+
outTokens[outTokens.length] = token;
|
|
2362
|
+
}
|
|
2363
|
+
return outTokens;
|
|
2364
|
+
}
|
|
2365
|
+
function translateFormulaToR1C1(formula, anchorCell, options = {}) {
|
|
2366
|
+
if (typeof formula === "string") {
|
|
2367
|
+
const tokens2 = tokenizeXlsx(formula, {
|
|
2368
|
+
mergeRefs: false,
|
|
2369
|
+
allowTernary: options.allowTernary ?? true
|
|
2370
|
+
});
|
|
2371
|
+
return stringifyTokens(translateTokensToR1C1(tokens2, anchorCell));
|
|
2372
|
+
}
|
|
2373
|
+
throw new Error("translateFormulaToA1 expects a formula string");
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
// lib/toCol.ts
|
|
2377
|
+
var charFrom = String.fromCharCode;
|
|
2378
|
+
function toCol(columnIndex) {
|
|
2379
|
+
return (columnIndex >= 702 ? charFrom(((columnIndex - 702) / 676 - 0) % 26 + 65) : "") + (columnIndex >= 26 ? charFrom((columnIndex / 26 - 1) % 26 + 65) : "") + charFrom(columnIndex % 26 + 65);
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
// lib/stringifyA1Range.ts
|
|
2383
|
+
var clamp2 = (min, val, max) => Math.min(Math.max(val, min), max);
|
|
2384
|
+
var toColStr = (c, a) => (a ? "$" : "") + toCol(c);
|
|
2385
|
+
var toRowStr = (r, a) => (a ? "$" : "") + toRow(r);
|
|
2386
|
+
var toRow = (top) => String(top + 1);
|
|
2387
|
+
function stringifyA1Range(range) {
|
|
2388
|
+
let { top, left, bottom, right, trim } = range;
|
|
2389
|
+
const { $left, $right, $top, $bottom } = range;
|
|
2390
|
+
const noLeft = left == null;
|
|
2391
|
+
const noRight = right == null;
|
|
2392
|
+
const noTop = top == null;
|
|
2393
|
+
const noBottom = bottom == null;
|
|
2394
|
+
top = clamp2(0, top | 0, MAX_ROWS);
|
|
2395
|
+
left = clamp2(0, left | 0, MAX_COLS);
|
|
2396
|
+
if (!noLeft && !noTop && noRight && noBottom) {
|
|
2397
|
+
bottom = top;
|
|
2398
|
+
right = left;
|
|
2399
|
+
} else {
|
|
2400
|
+
bottom = clamp2(0, bottom | 0, MAX_ROWS);
|
|
2401
|
+
right = clamp2(0, right | 0, MAX_COLS);
|
|
2402
|
+
}
|
|
2403
|
+
const op = rangeOperator(trim);
|
|
2404
|
+
const allRows = top === 0 && bottom >= MAX_ROWS;
|
|
2405
|
+
const haveAbsCol = $left && !noLeft || $right && !noRight;
|
|
2406
|
+
if (allRows && !noLeft && !noRight && (!haveAbsCol || left === right) || noTop && noBottom) {
|
|
2407
|
+
return toColStr(left, $left) + op + toColStr(right, $right);
|
|
2408
|
+
}
|
|
2409
|
+
const allCols = left === 0 && right >= MAX_COLS;
|
|
2410
|
+
const haveAbsRow = $top && !noTop || $bottom && !noBottom;
|
|
2411
|
+
if (allCols && !noTop && !noBottom && (!haveAbsRow || top === bottom) || noLeft && noRight) {
|
|
2412
|
+
return toRowStr(top, $top) + op + toRowStr(bottom, $bottom);
|
|
2413
|
+
}
|
|
2414
|
+
if (!noLeft && !noTop && !noRight && noBottom) {
|
|
2415
|
+
return toColStr(left, $left) + toRowStr(top, $top) + op + toColStr(right, $right);
|
|
2416
|
+
}
|
|
2417
|
+
if (!noLeft && noTop && !noRight && !noBottom) {
|
|
2418
|
+
return toColStr(left, $left) + toRowStr(bottom, $bottom) + op + toColStr(right, $right);
|
|
2419
|
+
}
|
|
2420
|
+
if (!noLeft && !noTop && noRight && !noBottom) {
|
|
2421
|
+
return toColStr(left, $left) + toRowStr(top, $top) + op + toRowStr(bottom, $bottom);
|
|
2422
|
+
}
|
|
2423
|
+
if (noLeft && !noTop && !noRight && !noBottom) {
|
|
2424
|
+
return toColStr(right, $right) + toRowStr(top, $top) + op + toRowStr(bottom, $bottom);
|
|
2425
|
+
}
|
|
2426
|
+
if (right !== left || bottom !== top || $right !== $left || $bottom !== $top) {
|
|
2427
|
+
return toColStr(left, $left) + toRowStr(top, $top) + op + toColStr(right, $right) + toRowStr(bottom, $bottom);
|
|
2428
|
+
}
|
|
2429
|
+
return toColStr(left, $left) + toRowStr(top, $top);
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
// lib/stringifyA1Ref.ts
|
|
2433
|
+
function stringifyA1Ref(refObject) {
|
|
2434
|
+
const prefix2 = stringifyPrefix(refObject);
|
|
2435
|
+
return prefix2 + ("name" in refObject ? refObject.name : stringifyA1Range(refObject.range));
|
|
2436
|
+
}
|
|
2437
|
+
function stringifyA1RefXlsx(refObject) {
|
|
2438
|
+
const prefix2 = stringifyPrefixXlsx(refObject);
|
|
2439
|
+
return prefix2 + ("name" in refObject ? refObject.name : stringifyA1Range(refObject.range));
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
// lib/parseR1C1Range.ts
|
|
2443
|
+
function trimDirection(head, tail) {
|
|
2444
|
+
if (head && tail) {
|
|
2445
|
+
return "both";
|
|
2446
|
+
}
|
|
2447
|
+
if (head) {
|
|
2448
|
+
return "head";
|
|
2449
|
+
}
|
|
2450
|
+
if (tail) {
|
|
2451
|
+
return "tail";
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
function parseR1C1Part(ref) {
|
|
2455
|
+
let r0 = null;
|
|
2456
|
+
let c0 = null;
|
|
2457
|
+
let $r0 = null;
|
|
2458
|
+
let $c0 = null;
|
|
2459
|
+
const rm = /^R(?:\[([+-]?\d+)\]|(\d+))?/.exec(ref);
|
|
2460
|
+
if (rm) {
|
|
2461
|
+
if (rm[1]) {
|
|
2462
|
+
r0 = parseInt(rm[1], 10);
|
|
2463
|
+
$r0 = false;
|
|
2464
|
+
} else if (rm[2]) {
|
|
2465
|
+
r0 = parseInt(rm[2], 10) - 1;
|
|
2466
|
+
$r0 = true;
|
|
2467
|
+
} else {
|
|
2468
|
+
r0 = 0;
|
|
2469
|
+
$r0 = false;
|
|
2470
|
+
}
|
|
2471
|
+
ref = ref.slice(rm[0].length);
|
|
2472
|
+
}
|
|
2473
|
+
const cm = /^C(?:\[([+-]?\d+)\]|(\d+))?/.exec(ref);
|
|
2474
|
+
if (cm) {
|
|
2475
|
+
if (cm[1]) {
|
|
2476
|
+
c0 = parseInt(cm[1], 10);
|
|
2477
|
+
$c0 = false;
|
|
2478
|
+
} else if (cm[2]) {
|
|
2479
|
+
c0 = parseInt(cm[2], 10) - 1;
|
|
2480
|
+
$c0 = true;
|
|
2481
|
+
} else {
|
|
2482
|
+
c0 = 0;
|
|
2483
|
+
$c0 = false;
|
|
2484
|
+
}
|
|
2485
|
+
ref = ref.slice(cm[0].length);
|
|
2486
|
+
}
|
|
2487
|
+
if (!rm && !cm || ref.length) {
|
|
2488
|
+
return null;
|
|
2489
|
+
}
|
|
2490
|
+
return [r0, c0, $r0, $c0];
|
|
2491
|
+
}
|
|
2492
|
+
function parseR1C1Range(rangeString) {
|
|
2493
|
+
let final = void 0;
|
|
2494
|
+
const [part1, op, part2, overflow] = rangeString.split(/(\.?:\.?)/);
|
|
2495
|
+
if (overflow) {
|
|
2496
|
+
return null;
|
|
2497
|
+
}
|
|
2498
|
+
const range = parseR1C1Part(part1);
|
|
2499
|
+
const trim = trimDirection(!!op && op[0] === ".", !!op && op[op.length - 1] === ".");
|
|
2500
|
+
if (range) {
|
|
2501
|
+
const [r0, c0, $r0, $c0] = range;
|
|
2502
|
+
if (part2) {
|
|
2503
|
+
const extendTo = parseR1C1Part(part2);
|
|
2504
|
+
if (extendTo) {
|
|
2505
|
+
final = {};
|
|
2506
|
+
const [r1, c1, $r1, $c1] = extendTo;
|
|
2507
|
+
if (r0 != null && r1 != null) {
|
|
2508
|
+
final.r0 = $r0 === $r1 ? Math.min(r0, r1) : r0;
|
|
2509
|
+
final.$r0 = $r0;
|
|
2510
|
+
final.r1 = $r0 === $r1 ? Math.max(r0, r1) : r1;
|
|
2511
|
+
final.$r1 = $r1;
|
|
2512
|
+
} else if (r0 != null && r1 == null) {
|
|
2513
|
+
final.r0 = r0;
|
|
2514
|
+
final.$r0 = $r0;
|
|
2515
|
+
final.r1 = null;
|
|
2516
|
+
final.$r1 = $r0;
|
|
2517
|
+
} else if (r0 == null && r1 != null) {
|
|
2518
|
+
final.r0 = r1;
|
|
2519
|
+
final.$r0 = $r1;
|
|
2520
|
+
final.r1 = null;
|
|
2521
|
+
final.$r1 = $r1;
|
|
2522
|
+
} else if (r0 == null && r1 == null) {
|
|
2523
|
+
final.r0 = null;
|
|
2524
|
+
final.$r0 = false;
|
|
2525
|
+
final.r1 = null;
|
|
2526
|
+
final.$r1 = false;
|
|
2527
|
+
}
|
|
2528
|
+
if (c0 != null && c1 != null) {
|
|
2529
|
+
final.c0 = $c0 === $c1 ? Math.min(c0, c1) : c0;
|
|
2530
|
+
final.$c0 = $c0;
|
|
2531
|
+
final.c1 = $c0 === $c1 ? Math.max(c0, c1) : c1;
|
|
2532
|
+
final.$c1 = $c1;
|
|
2533
|
+
} else if (c0 != null && c1 == null) {
|
|
2534
|
+
final.c0 = c0;
|
|
2535
|
+
final.$c0 = $c0;
|
|
2536
|
+
final.c1 = null;
|
|
2537
|
+
final.$c1 = $c0;
|
|
2538
|
+
} else if (c0 == null && c1 != null) {
|
|
2539
|
+
final.c0 = c1;
|
|
2540
|
+
final.$c0 = $c1;
|
|
2541
|
+
final.c1 = null;
|
|
2542
|
+
final.$c1 = $c1;
|
|
2543
|
+
} else if (c0 == null && c1 == null) {
|
|
2544
|
+
final.c0 = null;
|
|
2545
|
+
final.$c0 = false;
|
|
2546
|
+
final.c1 = null;
|
|
2547
|
+
final.$c1 = false;
|
|
2548
|
+
}
|
|
2549
|
+
} else {
|
|
2550
|
+
return null;
|
|
2551
|
+
}
|
|
2552
|
+
} else if (r0 != null && c0 == null) {
|
|
2553
|
+
final = {
|
|
2554
|
+
r0,
|
|
2555
|
+
c0: null,
|
|
2556
|
+
r1: r0,
|
|
2557
|
+
c1: null,
|
|
2558
|
+
$r0,
|
|
2559
|
+
$c0: false,
|
|
2560
|
+
$r1: $r0,
|
|
2561
|
+
$c1: false
|
|
2562
|
+
};
|
|
2563
|
+
} else if (r0 == null && c0 != null) {
|
|
2564
|
+
final = {
|
|
2565
|
+
r0: null,
|
|
2566
|
+
c0,
|
|
2567
|
+
r1: null,
|
|
2568
|
+
c1: c0,
|
|
2569
|
+
$r0: false,
|
|
2570
|
+
$c0,
|
|
2571
|
+
$r1: false,
|
|
2572
|
+
$c1: $c0
|
|
2573
|
+
};
|
|
2574
|
+
} else {
|
|
2575
|
+
final = {
|
|
2576
|
+
r0: r0 || 0,
|
|
2577
|
+
c0: c0 || 0,
|
|
2578
|
+
r1: r0 || 0,
|
|
2579
|
+
c1: c0 || 0,
|
|
2580
|
+
$r0: $r0 || false,
|
|
2581
|
+
$c0: $c0 || false,
|
|
2582
|
+
$r1: $r0 || false,
|
|
2583
|
+
$c1: $c0 || false
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
if (final && trim) {
|
|
2588
|
+
final.trim = trim;
|
|
2589
|
+
}
|
|
2590
|
+
return final;
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
// lib/parseR1C1Ref.ts
|
|
2594
|
+
function parseR1C1Ref(refString, options = {}) {
|
|
2595
|
+
const {
|
|
2596
|
+
allowNamed = true,
|
|
2597
|
+
allowTernary = false
|
|
2598
|
+
} = options;
|
|
2599
|
+
const d = parseRefCtx(refString, { allowNamed, allowTernary, r1c1: true });
|
|
2600
|
+
if (d) {
|
|
2601
|
+
if (d.name) {
|
|
2602
|
+
return { context: d.context, name: d.name };
|
|
2603
|
+
} else if (d.r0) {
|
|
2604
|
+
const range = d.r1 ? parseR1C1Range(d.r0 + d.operator + d.r1) : parseR1C1Range(d.r0);
|
|
2605
|
+
if (range) {
|
|
2606
|
+
return { context: d.context, range };
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
function parseR1C1RefXlsx(refString, options = {}) {
|
|
2612
|
+
const {
|
|
2613
|
+
allowNamed = true,
|
|
2614
|
+
allowTernary = false
|
|
2615
|
+
} = options;
|
|
2616
|
+
const d = parseRefXlsx(refString, { allowNamed, allowTernary, r1c1: true });
|
|
2617
|
+
if (d) {
|
|
2618
|
+
if (d.name && allowNamed) {
|
|
2619
|
+
return { workbookName: d.workbookName, sheetName: d.sheetName, name: d.name };
|
|
2620
|
+
} else if (d.r0) {
|
|
2621
|
+
const range = d.r1 ? parseR1C1Range(d.r0 + d.operator + d.r1) : parseR1C1Range(d.r0);
|
|
2622
|
+
if (range) {
|
|
2623
|
+
return { workbookName: d.workbookName, sheetName: d.sheetName, range };
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
// lib/translateToA1.ts
|
|
2630
|
+
var REF_OPTS = { allowTernary: true };
|
|
2631
|
+
function toFixed(val, abs, base, max, wrapEdges = true) {
|
|
2632
|
+
let v = val;
|
|
2633
|
+
if (v != null && !abs) {
|
|
2634
|
+
v = base + val;
|
|
2635
|
+
if (v < 0) {
|
|
2636
|
+
if (!wrapEdges) {
|
|
2637
|
+
return NaN;
|
|
2638
|
+
}
|
|
2639
|
+
v = max + v + 1;
|
|
2640
|
+
}
|
|
2641
|
+
if (v > max) {
|
|
2642
|
+
if (!wrapEdges) {
|
|
2643
|
+
return NaN;
|
|
2644
|
+
}
|
|
2645
|
+
v -= max + 1;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
return v;
|
|
2649
|
+
}
|
|
2650
|
+
function translateTokensToA1(tokens2, anchorCell, options = {}) {
|
|
2651
|
+
const anchorRange = parseA1Range(anchorCell);
|
|
2652
|
+
if (!anchorRange) {
|
|
2653
|
+
throw new Error("translateToR1C1 got an invalid anchorCell: " + anchorCell);
|
|
2654
|
+
}
|
|
2655
|
+
const { top, left } = anchorRange;
|
|
2656
|
+
const { wrapEdges = true } = options;
|
|
2657
|
+
let offsetSkew = 0;
|
|
2658
|
+
const outTokens = [];
|
|
2659
|
+
for (let token of tokens2) {
|
|
2660
|
+
if (isRange(token)) {
|
|
2661
|
+
token = cloneToken(token);
|
|
2662
|
+
const tokenValue = token.value;
|
|
2663
|
+
const ref = parseR1C1RefXlsx(tokenValue, REF_OPTS);
|
|
2664
|
+
const d = ref.range;
|
|
2665
|
+
const range = { top: 0, left: 0 };
|
|
2666
|
+
const r0 = toFixed(d.r0, d.$r0, top, MAX_ROWS, wrapEdges);
|
|
2667
|
+
const r1 = toFixed(d.r1, d.$r1, top, MAX_ROWS, wrapEdges);
|
|
2668
|
+
if (r0 > r1) {
|
|
2669
|
+
range.top = r1;
|
|
2670
|
+
range.$top = d.$r1;
|
|
2671
|
+
range.bottom = r0;
|
|
2672
|
+
range.$bottom = d.$r0;
|
|
2673
|
+
} else {
|
|
2674
|
+
range.top = r0;
|
|
2675
|
+
range.$top = d.$r0;
|
|
2676
|
+
range.bottom = r1;
|
|
2677
|
+
range.$bottom = d.$r1;
|
|
2678
|
+
}
|
|
2679
|
+
const c0 = toFixed(d.c0, d.$c0, left, MAX_COLS, wrapEdges);
|
|
2680
|
+
const c1 = toFixed(d.c1, d.$c1, left, MAX_COLS, wrapEdges);
|
|
2681
|
+
if (c0 > c1) {
|
|
2682
|
+
range.left = c1;
|
|
2683
|
+
range.$left = d.$c1;
|
|
2684
|
+
range.right = c0;
|
|
2685
|
+
range.$right = d.$c0;
|
|
2686
|
+
} else {
|
|
2687
|
+
range.left = c0;
|
|
2688
|
+
range.$left = d.$c0;
|
|
2689
|
+
range.right = c1;
|
|
2690
|
+
range.$right = d.$c1;
|
|
2691
|
+
}
|
|
2692
|
+
if (d.trim) {
|
|
2693
|
+
range.trim = d.trim;
|
|
2694
|
+
}
|
|
2695
|
+
if (isNaN(r0) || isNaN(r1) || isNaN(c0) || isNaN(c1)) {
|
|
2696
|
+
token.type = ERROR;
|
|
2697
|
+
token.value = "#REF!";
|
|
2698
|
+
delete token.groupId;
|
|
2699
|
+
} else {
|
|
2700
|
+
ref.range = range;
|
|
2701
|
+
token.value = stringifyA1RefXlsx(ref);
|
|
2702
|
+
}
|
|
2703
|
+
if (token.loc) {
|
|
2704
|
+
token.loc[0] += offsetSkew;
|
|
2705
|
+
offsetSkew += token.value.length - tokenValue.length;
|
|
2706
|
+
token.loc[1] += offsetSkew;
|
|
2707
|
+
}
|
|
2708
|
+
} else if (offsetSkew && token.loc) {
|
|
2709
|
+
token = cloneToken(token);
|
|
2710
|
+
token.loc[0] += offsetSkew;
|
|
2711
|
+
token.loc[1] += offsetSkew;
|
|
2712
|
+
}
|
|
2713
|
+
outTokens[outTokens.length] = token;
|
|
2714
|
+
}
|
|
2715
|
+
return outTokens;
|
|
2716
|
+
}
|
|
2717
|
+
function translateFormulaToA1(formula, anchorCell, options = {}) {
|
|
2718
|
+
if (typeof formula === "string") {
|
|
2719
|
+
return stringifyTokens(translateTokensToA1(tokenizeXlsx(formula, {
|
|
2720
|
+
allowTernary: options.allowTernary ?? true,
|
|
2721
|
+
mergeRefs: options.mergeRefs,
|
|
2722
|
+
r1c1: true
|
|
2723
|
+
}), anchorCell, options));
|
|
2724
|
+
}
|
|
2725
|
+
throw new Error("translateFormulaToA1 expects a formula string");
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
// lib/parseA1Ref.ts
|
|
2729
|
+
function parseA1Ref(refString, { allowNamed = true, allowTernary = false } = {}) {
|
|
2730
|
+
const d = parseRefCtx(refString, { allowNamed, allowTernary, r1c1: false });
|
|
2731
|
+
if (d) {
|
|
2732
|
+
if (d.name) {
|
|
2733
|
+
return { context: d.context, name: d.name };
|
|
2734
|
+
} else if (d.r0) {
|
|
2735
|
+
const range = parseA1Range(d.r1 ? d.r0 + d.operator + d.r1 : d.r0);
|
|
2736
|
+
if (range) {
|
|
2737
|
+
return { context: d.context, range };
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
// lib/addA1RangeBounds.ts
|
|
2744
|
+
function addA1RangeBounds(range) {
|
|
2745
|
+
if (range.top == null) {
|
|
2746
|
+
range.top = 0;
|
|
2747
|
+
range.$top = false;
|
|
2748
|
+
}
|
|
2749
|
+
if (range.bottom == null) {
|
|
2750
|
+
range.bottom = MAX_ROWS;
|
|
2751
|
+
range.$bottom = false;
|
|
2752
|
+
}
|
|
2753
|
+
if (range.left == null) {
|
|
2754
|
+
range.left = 0;
|
|
2755
|
+
range.$left = false;
|
|
2756
|
+
}
|
|
2757
|
+
if (range.right == null) {
|
|
2758
|
+
range.right = MAX_COLS;
|
|
2759
|
+
range.$right = false;
|
|
2760
|
+
}
|
|
2761
|
+
return range;
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// lib/parseStructRef.ts
|
|
2765
|
+
function parseStructRef(ref) {
|
|
2766
|
+
const r = parseRefCtx(ref);
|
|
2767
|
+
if (r && r.struct) {
|
|
2768
|
+
const structData = parseSRange(r.struct);
|
|
2769
|
+
if (structData && structData.length === r.struct.length) {
|
|
2770
|
+
return {
|
|
2771
|
+
context: r.context,
|
|
2772
|
+
table: r.name,
|
|
2773
|
+
columns: structData.columns,
|
|
2774
|
+
sections: structData.sections
|
|
2775
|
+
};
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
// lib/stringifyStructRef.ts
|
|
2781
|
+
function quoteColname(str) {
|
|
2782
|
+
return str.replace(/([[\]#'@])/g, "'$1");
|
|
2783
|
+
}
|
|
2784
|
+
function needsBraces(str) {
|
|
2785
|
+
return /[^a-zA-Z0-9\u00a1-\uffff]/.test(str);
|
|
2786
|
+
}
|
|
2787
|
+
function toSentenceCase(str) {
|
|
2788
|
+
return str[0].toUpperCase() + str.slice(1).toLowerCase();
|
|
2789
|
+
}
|
|
2790
|
+
function stringifySRef(refObject, thisRow = false) {
|
|
2791
|
+
let s = "";
|
|
2792
|
+
if (refObject.table) {
|
|
2793
|
+
s += refObject.table;
|
|
2794
|
+
}
|
|
2795
|
+
const numColumns = refObject.columns?.length ?? 0;
|
|
2796
|
+
const numSections = refObject.sections?.length ?? 0;
|
|
2797
|
+
if (numSections === 1 && !numColumns) {
|
|
2798
|
+
s += `[#${toSentenceCase(refObject.sections[0])}]`;
|
|
2799
|
+
} else if (!numSections && numColumns === 1) {
|
|
2800
|
+
s += `[${quoteColname(refObject.columns[0])}]`;
|
|
2801
|
+
} else {
|
|
2802
|
+
s += "[";
|
|
2803
|
+
const singleAt = !thisRow && numSections === 1 && refObject.sections[0].toLowerCase() === "this row";
|
|
2804
|
+
if (singleAt) {
|
|
2805
|
+
s += "@";
|
|
2806
|
+
} else if (numSections) {
|
|
2807
|
+
s += refObject.sections.map((d) => `[#${toSentenceCase(d)}]`).join(",");
|
|
2808
|
+
if (numColumns) {
|
|
2809
|
+
s += ",";
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
if (singleAt && refObject.columns.length === 1 && !needsBraces(refObject.columns[0])) {
|
|
2813
|
+
s += quoteColname(refObject.columns[0]);
|
|
2814
|
+
} else if (numColumns) {
|
|
2815
|
+
s += refObject.columns.slice(0, 2).map((d) => `[${quoteColname(d)}]`).join(":");
|
|
2816
|
+
}
|
|
2817
|
+
s += "]";
|
|
2818
|
+
}
|
|
2819
|
+
return s;
|
|
2820
|
+
}
|
|
2821
|
+
function stringifyStructRef(refObject, options = {}) {
|
|
2822
|
+
return stringifyPrefix(refObject) + stringifySRef(refObject, !!options.thisRow);
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
// lib/fixRanges.ts
|
|
2826
|
+
function fixTokenRanges(tokens2, options = {}) {
|
|
2827
|
+
if (!Array.isArray(tokens2)) {
|
|
2828
|
+
throw new Error("fixRanges expects an array of tokens");
|
|
2829
|
+
}
|
|
2830
|
+
const { addBounds, thisRow } = options;
|
|
2831
|
+
let offsetSkew = 0;
|
|
2832
|
+
const output = [];
|
|
2833
|
+
for (const t of tokens2) {
|
|
2834
|
+
const token = cloneToken(t);
|
|
2835
|
+
let offsetDelta = 0;
|
|
2836
|
+
if (token.type === REF_STRUCT) {
|
|
2837
|
+
const sref = parseStructRef(token.value);
|
|
2838
|
+
const newValue = stringifyStructRef(sref, { thisRow });
|
|
2839
|
+
offsetDelta = newValue.length - token.value.length;
|
|
2840
|
+
token.value = newValue;
|
|
2841
|
+
} else if (isRange(token)) {
|
|
2842
|
+
const ref = parseA1Ref(token.value, { allowTernary: true });
|
|
2843
|
+
const range = ref.range;
|
|
2844
|
+
if (addBounds) {
|
|
2845
|
+
addA1RangeBounds(range);
|
|
2846
|
+
}
|
|
2847
|
+
const newValue = stringifyA1Ref(ref);
|
|
2848
|
+
offsetDelta = newValue.length - token.value.length;
|
|
2849
|
+
token.value = newValue;
|
|
2850
|
+
}
|
|
2851
|
+
if (offsetSkew || offsetDelta) {
|
|
2852
|
+
if (token.loc) {
|
|
2853
|
+
token.loc[0] += offsetSkew;
|
|
2854
|
+
}
|
|
2855
|
+
offsetSkew += offsetDelta;
|
|
2856
|
+
if (token.loc) {
|
|
2857
|
+
token.loc[1] += offsetSkew;
|
|
2858
|
+
}
|
|
2859
|
+
} else {
|
|
2860
|
+
offsetSkew += offsetDelta;
|
|
2861
|
+
}
|
|
2862
|
+
output.push(token);
|
|
2863
|
+
}
|
|
2864
|
+
return output;
|
|
2865
|
+
}
|
|
2866
|
+
function fixFormulaRanges(formula, options = {}) {
|
|
2867
|
+
if (typeof formula !== "string") {
|
|
2868
|
+
throw new Error("fixFormulaRanges expects a string formula");
|
|
2869
|
+
}
|
|
2870
|
+
return stringifyTokens(
|
|
2871
|
+
fixTokenRanges(
|
|
2872
|
+
tokenize(formula, options),
|
|
2873
|
+
options
|
|
2874
|
+
)
|
|
2875
|
+
);
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
// lib/isNodeType.ts
|
|
2879
|
+
function isIdentifierNode(node) {
|
|
2880
|
+
return node?.type === IDENTIFIER;
|
|
2881
|
+
}
|
|
2882
|
+
function isReferenceNode2(node) {
|
|
2883
|
+
return node?.type === REFERENCE;
|
|
2884
|
+
}
|
|
2885
|
+
function isLiteralNode(node) {
|
|
2886
|
+
return node?.type === LITERAL;
|
|
2887
|
+
}
|
|
2888
|
+
function isErrorNode(node) {
|
|
2889
|
+
return node?.type === ERROR_LITERAL;
|
|
2890
|
+
}
|
|
2891
|
+
function isUnaryNode(node) {
|
|
2892
|
+
return node?.type === UNARY;
|
|
2893
|
+
}
|
|
2894
|
+
function isBinaryNode(node) {
|
|
2895
|
+
return node?.type === BINARY;
|
|
2896
|
+
}
|
|
2897
|
+
function isCallNode(node) {
|
|
2898
|
+
return node?.type === CALL;
|
|
2899
|
+
}
|
|
2900
|
+
function isArrayNode(node) {
|
|
2901
|
+
return node?.type === ARRAY;
|
|
2902
|
+
}
|
|
2903
|
+
function isLambdaNode(node) {
|
|
2904
|
+
return node?.type === ARRAY;
|
|
2905
|
+
}
|
|
2906
|
+
function isLetNode(node) {
|
|
2907
|
+
return node?.type === LET;
|
|
2908
|
+
}
|
|
2909
|
+
function isLetDeclaratorNode(node) {
|
|
2910
|
+
return node?.type === LET_DECL;
|
|
2911
|
+
}
|
|
2912
|
+
function isExpressionNode(node) {
|
|
2913
|
+
const type = node?.type;
|
|
2914
|
+
if (type) {
|
|
2915
|
+
return type === REFERENCE || type === LITERAL || type === ERROR || type === UNARY || type === BINARY || type === CALL || type === ARRAY || type === LAMBDA || type === LET;
|
|
2916
|
+
}
|
|
2917
|
+
return false;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
// lib/fromCol.ts
|
|
2921
|
+
function fromCol(columnString) {
|
|
2922
|
+
const x = columnString || "";
|
|
2923
|
+
const l = x.length;
|
|
2924
|
+
let n = 0;
|
|
2925
|
+
if (l > 2) {
|
|
2926
|
+
const c = x.charCodeAt(l - 3);
|
|
2927
|
+
const a = c > 95 ? 32 : 0;
|
|
2928
|
+
n += (1 + c - a - 65) * 676;
|
|
2929
|
+
}
|
|
2930
|
+
if (l > 1) {
|
|
2931
|
+
const c = x.charCodeAt(l - 2);
|
|
2932
|
+
const a = c > 95 ? 32 : 0;
|
|
2933
|
+
n += (1 + c - a - 65) * 26;
|
|
2934
|
+
}
|
|
2935
|
+
if (l) {
|
|
2936
|
+
const c = x.charCodeAt(l - 1);
|
|
2937
|
+
const a = c > 95 ? 32 : 0;
|
|
2938
|
+
n += c - a - 65;
|
|
2939
|
+
}
|
|
2940
|
+
return n;
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
// lib/tokenTypes.ts
|
|
2944
|
+
var tokenTypes = Object.freeze({
|
|
2945
|
+
/** Unary or binary operator (`+`, `%`) */
|
|
2946
|
+
OPERATOR,
|
|
2947
|
+
/** Boolean literal (`TRUE`) */
|
|
2948
|
+
BOOLEAN,
|
|
2949
|
+
/** Error literal (`#VALUE!`) */
|
|
2950
|
+
ERROR,
|
|
2951
|
+
/** Number literal (`123.4`, `-1.5e+2`) */
|
|
2952
|
+
NUMBER,
|
|
2953
|
+
/** Function name (`SUM`) */
|
|
2954
|
+
FUNCTION,
|
|
2955
|
+
/** Newline character (`\n`) */
|
|
2956
|
+
NEWLINE,
|
|
2957
|
+
/** Whitespace character sequence (` `) */
|
|
2958
|
+
WHITESPACE,
|
|
2959
|
+
/** String literal (`"Lorem ipsum"`) */
|
|
2960
|
+
STRING,
|
|
2961
|
+
/** Reference context ([Workbook.xlsx]Sheet1) */
|
|
2962
|
+
CONTEXT,
|
|
2963
|
+
/** Quoted reference context (`'[My workbook.xlsx]Sheet1'`) */
|
|
2964
|
+
CONTEXT_QUOTE,
|
|
2965
|
+
/** A range identifier (`A1`) */
|
|
2966
|
+
REF_RANGE,
|
|
2967
|
+
/** A range "beam" identifier (`A:A` or `1:1`) */
|
|
2968
|
+
REF_BEAM,
|
|
2969
|
+
/** A ternary range identifier (`B2:B`) */
|
|
2970
|
+
REF_TERNARY,
|
|
2971
|
+
/** A name / named range identifier (`income`) */
|
|
2972
|
+
REF_NAMED,
|
|
2973
|
+
/** A structured reference identifier (`table[[Column1]:[Column2]]`) */
|
|
2974
|
+
REF_STRUCT,
|
|
2975
|
+
/** A leading equals sign at the start of a formula (`=`) */
|
|
2976
|
+
FX_PREFIX,
|
|
2977
|
+
/** Any unidentifiable range of characters. */
|
|
2978
|
+
UNKNOWN
|
|
2979
|
+
});
|
|
2980
|
+
|
|
2981
|
+
// lib/nodeTypes.ts
|
|
2982
|
+
var nodeTypes = Object.freeze({
|
|
2983
|
+
/** A unary operation (`10%`) */
|
|
2984
|
+
UNARY,
|
|
2985
|
+
/** A binary operation (`10+10`) */
|
|
2986
|
+
BINARY,
|
|
2987
|
+
/** A range identifier (`A1`) */
|
|
2988
|
+
REFERENCE,
|
|
2989
|
+
/** A literal (number, string, or boolean) (`123`, `"foo"`, `false`) */
|
|
2990
|
+
LITERAL,
|
|
2991
|
+
/** An error literal (`#VALUE!`) */
|
|
2992
|
+
ERROR: ERROR_LITERAL,
|
|
2993
|
+
/** A function call expression (`SUM(1,2)`) */
|
|
2994
|
+
CALL,
|
|
2995
|
+
/** An array expression (`{1,2;3,4}`) */
|
|
2996
|
+
ARRAY,
|
|
2997
|
+
/** A function name identifier (`SUM`) */
|
|
2998
|
+
IDENTIFIER,
|
|
2999
|
+
/** A LAMBDA expression (`LAMBDA(x,y,x*y)``) */
|
|
3000
|
+
LAMBDA,
|
|
3001
|
+
/** A LET expression (`LET(a,A1*10,b,SUM(F:F),a*b)`) */
|
|
3002
|
+
LET,
|
|
3003
|
+
/** A LET declaration (LET(`a,A1*10`...)*/
|
|
3004
|
+
LET_DECL
|
|
3005
|
+
});
|
|
3006
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3007
|
+
0 && (module.exports = {
|
|
3008
|
+
MAX_COLS,
|
|
3009
|
+
MAX_ROWS,
|
|
3010
|
+
addA1RangeBounds,
|
|
3011
|
+
fixFormulaRanges,
|
|
3012
|
+
fixTokenRanges,
|
|
3013
|
+
fromCol,
|
|
3014
|
+
isArrayNode,
|
|
3015
|
+
isBinaryNode,
|
|
3016
|
+
isCallNode,
|
|
3017
|
+
isError,
|
|
3018
|
+
isErrorNode,
|
|
3019
|
+
isExpressionNode,
|
|
3020
|
+
isFunction,
|
|
3021
|
+
isFxPrefix,
|
|
3022
|
+
isIdentifierNode,
|
|
3023
|
+
isLambdaNode,
|
|
3024
|
+
isLetDeclaratorNode,
|
|
3025
|
+
isLetNode,
|
|
3026
|
+
isLiteral,
|
|
3027
|
+
isLiteralNode,
|
|
3028
|
+
isOperator,
|
|
3029
|
+
isRange,
|
|
3030
|
+
isReference,
|
|
3031
|
+
isReferenceNode,
|
|
3032
|
+
isUnaryNode,
|
|
3033
|
+
isWhitespace,
|
|
3034
|
+
mergeRefTokens,
|
|
3035
|
+
nodeTypes,
|
|
3036
|
+
parse,
|
|
3037
|
+
parseA1Range,
|
|
3038
|
+
parseA1Ref,
|
|
3039
|
+
parseR1C1Range,
|
|
3040
|
+
parseR1C1Ref,
|
|
3041
|
+
parseStructRef,
|
|
3042
|
+
stringifyA1Ref,
|
|
3043
|
+
stringifyR1C1Ref,
|
|
3044
|
+
stringifyStructRef,
|
|
3045
|
+
stringifyTokens,
|
|
3046
|
+
toCol,
|
|
3047
|
+
tokenTypes,
|
|
3048
|
+
tokenize,
|
|
3049
|
+
translateFormulaToA1,
|
|
3050
|
+
translateFormulaToR1C1,
|
|
3051
|
+
translateTokensToA1,
|
|
3052
|
+
translateTokensToR1C1
|
|
3053
|
+
});
|
|
3054
|
+
//# sourceMappingURL=index.cjs.map
|