@rowsncolumns/toolkit 24.5.18 → 24.5.20
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/cjs/excel-parser/defined-names.d.ts +18 -0
- package/dist/cjs/excel-parser/defined-names.d.ts.map +1 -0
- package/dist/cjs/excel-parser/defined-names.js +59 -0
- package/dist/cjs/excel-parser/interface.d.ts +7 -1
- package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsb/function-table.d.ts +17 -0
- package/dist/cjs/excel-parser/plugins/xlsb/function-table.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/function-table.js +988 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts +45 -3
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsb/index.js +406 -374
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts +43 -9
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.js +422 -478
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/index.js +147 -191
- package/dist/cjs/excel-parser/types.d.ts +17 -0
- package/dist/cjs/excel-parser/types.d.ts.map +1 -1
- package/dist/cjs/excel-parser/workbook.d.ts +1 -0
- package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
- package/dist/cjs/excel-parser/workbook.js +4 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/xlsx-export.js +46 -23
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/excel-parser/defined-names.d.ts +18 -0
- package/dist/esm/excel-parser/defined-names.d.ts.map +1 -0
- package/dist/esm/excel-parser/defined-names.js +67 -0
- package/dist/esm/excel-parser/interface.d.ts +7 -1
- package/dist/esm/excel-parser/interface.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsb/function-table.d.ts +17 -0
- package/dist/esm/excel-parser/plugins/xlsb/function-table.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/function-table.js +988 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts +45 -3
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsb/index.js +266 -205
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts +43 -9
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.js +405 -472
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/index.js +9 -58
- package/dist/esm/excel-parser/types.d.ts +17 -0
- package/dist/esm/excel-parser/types.d.ts.map +1 -1
- package/dist/esm/excel-parser/workbook.d.ts +1 -0
- package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
- package/dist/esm/excel-parser/workbook.js +3 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/xlsx-export.js +26 -5
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,527 +1,471 @@
|
|
|
1
|
+
import { __extends, __read } from "tslib";
|
|
1
2
|
import { number2Alpha } from "@rowsncolumns/utils";
|
|
3
|
+
import { FTAB, FTAB_FIXED_ARGC } from "./function-table";
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* Decoder for a BIFF12 formula's token stream (`rgce`, [MS-XLSB] 2.2.2 / 2.5.97.88):
|
|
6
|
+
* reverse-Polish tokens rebuilt into the formula's text.
|
|
7
|
+
*
|
|
8
|
+
* Strict by design: a formula decodes completely or not at all. A token it
|
|
9
|
+
* does not know, a function outside the table, a read past the end of the
|
|
10
|
+
* stream or a stack that does not end with exactly one expression throws
|
|
11
|
+
* {@link RgceUnsupportedError}, and the caller keeps the cell's cached value
|
|
12
|
+
* instead of writing a formula that computes something else.
|
|
4
13
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
14
|
+
/** The formula cannot be decoded exactly; keep the cell's cached value. */
|
|
15
|
+
var RgceUnsupportedError = /** @class */ (function (_super) {
|
|
16
|
+
__extends(RgceUnsupportedError, _super);
|
|
17
|
+
function RgceUnsupportedError(message) {
|
|
18
|
+
var _this = _super.call(this, message) || this;
|
|
19
|
+
_this.name = "RgceUnsupportedError";
|
|
20
|
+
return _this;
|
|
21
|
+
}
|
|
22
|
+
return RgceUnsupportedError;
|
|
23
|
+
}(Error));
|
|
24
|
+
export { RgceUnsupportedError };
|
|
25
|
+
var MAX_ROW_INDEX = 0xfffff; // 1,048,575: row 1,048,576
|
|
26
|
+
var MAX_COL_INDEX = 0x3fff; // 16,383: column XFD
|
|
27
|
+
var ERROR_CODES = {
|
|
28
|
+
0x00: "#NULL!",
|
|
29
|
+
0x07: "#DIV/0!",
|
|
30
|
+
0x0f: "#VALUE!",
|
|
31
|
+
0x17: "#REF!",
|
|
32
|
+
0x1d: "#NAME?",
|
|
33
|
+
0x24: "#NUM!",
|
|
34
|
+
0x2a: "#N/A",
|
|
35
|
+
0x2b: "#GETTING_DATA",
|
|
36
|
+
};
|
|
37
|
+
var BINARY_OPERATORS = {
|
|
38
|
+
0x03: "+",
|
|
39
|
+
0x04: "-",
|
|
40
|
+
0x05: "*",
|
|
41
|
+
0x06: "/",
|
|
42
|
+
0x07: "^",
|
|
43
|
+
0x08: "&",
|
|
44
|
+
0x09: "<",
|
|
45
|
+
0x0a: "<=",
|
|
46
|
+
0x0b: "=",
|
|
47
|
+
0x0c: ">=",
|
|
48
|
+
0x0d: ">",
|
|
49
|
+
0x0e: "<>",
|
|
50
|
+
0x0f: " ",
|
|
51
|
+
0x10: ",",
|
|
52
|
+
0x11: ":",
|
|
53
|
+
};
|
|
54
|
+
/** `PtgAttr` kinds that only steer evaluation or carry whitespace: no stack effect. */
|
|
55
|
+
var ATTR_NO_EFFECT = new Set([0x01, 0x02, 0x08, 0x20, 0x21, 0x40, 0x41]);
|
|
56
|
+
var ATTR_CHOOSE = 0x04;
|
|
57
|
+
var PTG_UNION = 0x10;
|
|
58
|
+
var ATTR_SUM = 0x10;
|
|
59
|
+
var Reader = /** @class */ (function () {
|
|
60
|
+
function Reader(bytes) {
|
|
8
61
|
this.bytes = bytes;
|
|
62
|
+
this.offset = 0;
|
|
9
63
|
this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
10
64
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
65
|
+
Object.defineProperty(Reader.prototype, "done", {
|
|
66
|
+
get: function () {
|
|
67
|
+
return this.offset >= this.bytes.length;
|
|
68
|
+
},
|
|
69
|
+
enumerable: false,
|
|
70
|
+
configurable: true
|
|
71
|
+
});
|
|
72
|
+
Reader.prototype.take = function (count) {
|
|
73
|
+
if (this.offset + count > this.bytes.length) {
|
|
74
|
+
throw new RgceUnsupportedError("token runs past the end of the formula");
|
|
75
|
+
}
|
|
76
|
+
var at = this.offset;
|
|
77
|
+
this.offset += count;
|
|
78
|
+
return at;
|
|
15
79
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.offset += 2;
|
|
19
|
-
return value;
|
|
80
|
+
Reader.prototype.u8 = function () {
|
|
81
|
+
return this.view.getUint8(this.take(1));
|
|
20
82
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.offset += 4;
|
|
24
|
-
return value;
|
|
83
|
+
Reader.prototype.u16 = function () {
|
|
84
|
+
return this.view.getUint16(this.take(2), true);
|
|
25
85
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.offset += 4;
|
|
29
|
-
return value;
|
|
86
|
+
Reader.prototype.i16 = function () {
|
|
87
|
+
return this.view.getInt16(this.take(2), true);
|
|
30
88
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.offset += 2;
|
|
34
|
-
return value;
|
|
89
|
+
Reader.prototype.u32 = function () {
|
|
90
|
+
return this.view.getUint32(this.take(4), true);
|
|
35
91
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.offset += 8;
|
|
39
|
-
return value;
|
|
92
|
+
Reader.prototype.i32 = function () {
|
|
93
|
+
return this.view.getInt32(this.take(4), true);
|
|
40
94
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.offset += byteCount;
|
|
47
|
-
return new TextDecoder("utf-16le").decode(slice);
|
|
95
|
+
Reader.prototype.f64 = function () {
|
|
96
|
+
return this.view.getFloat64(this.take(8), true);
|
|
97
|
+
};
|
|
98
|
+
Reader.prototype.skip = function (count) {
|
|
99
|
+
this.take(count);
|
|
48
100
|
};
|
|
49
|
-
|
|
50
|
-
var
|
|
51
|
-
return
|
|
101
|
+
Reader.prototype.utf16 = function (chars) {
|
|
102
|
+
var at = this.take(chars * 2);
|
|
103
|
+
return new TextDecoder("utf-16le").decode(this.bytes.subarray(at, at + chars * 2));
|
|
52
104
|
};
|
|
53
|
-
return
|
|
105
|
+
return Reader;
|
|
54
106
|
}());
|
|
55
|
-
// Common Excel function names by ID (ftab index)
|
|
56
|
-
var FUNCTION_NAMES = {
|
|
57
|
-
0: "COUNT", 1: "IF", 2: "ISNA", 3: "ISERROR", 4: "SUM", 5: "AVERAGE",
|
|
58
|
-
6: "MIN", 7: "MAX", 8: "ROW", 9: "COLUMN", 10: "NA", 11: "NPV",
|
|
59
|
-
12: "STDEV", 13: "DOLLAR", 14: "FIXED", 15: "SIN", 16: "COS",
|
|
60
|
-
17: "TAN", 18: "ATAN", 19: "PI", 20: "SQRT", 21: "EXP", 22: "LN",
|
|
61
|
-
23: "LOG10", 24: "ABS", 25: "INT", 26: "SIGN", 27: "ROUND",
|
|
62
|
-
28: "LOOKUP", 29: "INDEX", 30: "REPT", 31: "MID", 32: "LEN",
|
|
63
|
-
33: "VALUE", 34: "TRUE", 35: "FALSE", 36: "AND", 37: "OR",
|
|
64
|
-
38: "NOT", 39: "MOD", 40: "DCOUNT", 41: "DSUM", 42: "DAVERAGE",
|
|
65
|
-
43: "DMIN", 44: "DMAX", 45: "DSTDEV", 46: "VAR", 47: "DVAR",
|
|
66
|
-
48: "TEXT", 49: "LINEST", 50: "TREND", 51: "LOGEST", 52: "GROWTH",
|
|
67
|
-
61: "MIRR", 62: "IRR", 63: "RAND", 64: "MATCH", 65: "DATE",
|
|
68
|
-
66: "TIME", 67: "DAY", 68: "MONTH", 69: "YEAR", 70: "WEEKDAY",
|
|
69
|
-
71: "HOUR", 72: "MINUTE", 73: "SECOND", 74: "NOW", 75: "AREAS",
|
|
70
|
-
76: "ROWS", 77: "COLUMNS", 78: "OFFSET", 82: "SEARCH", 83: "TRANSPOSE",
|
|
71
|
-
86: "TYPE", 97: "ATAN2", 98: "ASIN", 99: "ACOS", 100: "CHOOSE",
|
|
72
|
-
101: "HLOOKUP", 102: "VLOOKUP", 103: "ISREF", 104: "LOG",
|
|
73
|
-
105: "CHAR", 106: "LOWER", 107: "UPPER", 108: "PROPER", 109: "LEFT",
|
|
74
|
-
110: "RIGHT", 111: "EXACT", 112: "TRIM", 113: "REPLACE", 114: "SUBSTITUTE",
|
|
75
|
-
115: "CODE", 116: "NAMES", 117: "DIRECTORY", 118: "FIND", 119: "CELL",
|
|
76
|
-
120: "ISERR", 121: "ISTEXT", 122: "ISNUMBER", 123: "ISBLANK",
|
|
77
|
-
124: "T", 125: "N", 127: "ISNONTEXT", 128: "ISODD", 129: "ISEVEN",
|
|
78
|
-
162: "CLEAN", 163: "MDETERM", 164: "MINVERSE", 165: "MMULT",
|
|
79
|
-
167: "IPMT", 168: "PPMT", 169: "COUNTA", 183: "PRODUCT",
|
|
80
|
-
184: "FACT", 189: "DPRODUCT", 190: "ISNONTEXT",
|
|
81
|
-
193: "STDEVP", 194: "VARP", 195: "DSTDEVP", 196: "DVARP",
|
|
82
|
-
197: "TRUNC", 198: "ISLOGICAL", 199: "DCOUNTA", 200: "DELETEBAR",
|
|
83
|
-
216: "RANK", 219: "ADDRESS", 220: "DAYS360", 221: "TODAY",
|
|
84
|
-
222: "VDB", 227: "MEDIAN", 228: "SUMPRODUCT", 229: "SINH",
|
|
85
|
-
230: "COSH", 231: "TANH", 232: "ASINH", 233: "ACOSH", 234: "ATANH",
|
|
86
|
-
235: "DGET", 244: "INFO", 247: "DB", 252: "FREQUENCY",
|
|
87
|
-
261: "ERROR.TYPE", 269: "AVEDEV", 270: "BETADIST", 271: "GAMMALN",
|
|
88
|
-
272: "BETAINV", 273: "BINOMDIST", 274: "CHIDIST", 275: "CHIINV",
|
|
89
|
-
276: "COMBIN", 277: "CONFIDENCE", 278: "CRITBINOM", 279: "EVEN",
|
|
90
|
-
280: "EXPONDIST", 281: "FDIST", 282: "FINV", 283: "FISHER",
|
|
91
|
-
284: "FISHERINV", 285: "FLOOR", 286: "GAMMADIST", 287: "GAMMAINV",
|
|
92
|
-
288: "CEILING", 289: "HYPGEOMDIST", 290: "LOGNORMDIST", 291: "LOGINV",
|
|
93
|
-
292: "NEGBINOMDIST", 293: "NORMDIST", 294: "NORMSDIST", 295: "NORMINV",
|
|
94
|
-
296: "NORMSINV", 297: "STANDARDIZE", 298: "ODD", 299: "PERMUT",
|
|
95
|
-
300: "POISSON", 301: "TDIST", 302: "WEIBULL", 303: "SUMXMY2",
|
|
96
|
-
304: "SUMX2MY2", 305: "SUMX2PY2", 306: "CHITEST", 307: "CORREL",
|
|
97
|
-
308: "COVAR", 309: "FORECAST", 310: "FTEST", 311: "INTERCEPT",
|
|
98
|
-
312: "PEARSON", 313: "RSQ", 314: "STEYX", 315: "SLOPE", 316: "TTEST",
|
|
99
|
-
317: "PROB", 318: "DEVSQ", 319: "GEOMEAN", 320: "HARMEAN",
|
|
100
|
-
321: "SUMSQ", 322: "KURT", 323: "SKEW", 324: "ZTEST", 325: "LARGE",
|
|
101
|
-
326: "SMALL", 327: "QUARTILE", 328: "PERCENTILE", 329: "PERCENTRANK",
|
|
102
|
-
330: "MODE", 331: "TRIMMEAN", 332: "TINV", 334: "CONCATENATE",
|
|
103
|
-
335: "POWER", 336: "RADIANS", 337: "DEGREES", 338: "SUBTOTAL",
|
|
104
|
-
339: "SUMIF", 340: "COUNTIF", 341: "COUNTBLANK", 342: "HYPERLINK",
|
|
105
|
-
343: "PHONETIC", 344: "AVERAGEA", 345: "MAXA", 346: "MINA",
|
|
106
|
-
347: "STDEVPA", 348: "VARPA", 349: "STDEVA", 350: "VARA",
|
|
107
|
-
};
|
|
108
107
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
* @param rgceBytes - The binary formula data
|
|
113
|
-
* @returns The formula string (without leading "=")
|
|
108
|
+
* A sheet name as a reference prefix: quoted unless it is a plain ASCII
|
|
109
|
+
* identifier no reader could take for a cell (`A1`, `R1C1`, `R`) or a
|
|
110
|
+
* boolean. Quoting is always valid, so anything else is quoted.
|
|
114
111
|
*/
|
|
112
|
+
export var quoteSheetName = function (name) {
|
|
113
|
+
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name) &&
|
|
114
|
+
!/^[A-Za-z]{1,3}\d+$/.test(name) &&
|
|
115
|
+
!/^(?:[Rr]\d*)?(?:[Cc]\d*)?$/.test(name) &&
|
|
116
|
+
!/^(?:TRUE|FALSE)$/i.test(name)
|
|
117
|
+
? name
|
|
118
|
+
: "'".concat(name.replace(/'/g, "''"), "'");
|
|
119
|
+
};
|
|
120
|
+
var formatNumber = function (value) {
|
|
121
|
+
if (!Number.isFinite(value)) {
|
|
122
|
+
throw new RgceUnsupportedError("non-finite number constant");
|
|
123
|
+
}
|
|
124
|
+
return String(value).replace("e", "E");
|
|
125
|
+
};
|
|
126
|
+
var cellRef = function (row, col, rowRelative, colRelative) {
|
|
127
|
+
return "".concat(colRelative ? "" : "$").concat(number2Alpha(col)).concat(rowRelative ? "" : "$").concat(row + 1);
|
|
128
|
+
};
|
|
129
|
+
/** An area, written the way Excel writes whole columns (`A:B`) and whole rows (`1:2`). */
|
|
130
|
+
var areaRef = function (first, last) {
|
|
131
|
+
if (first.row === 0 && last.row === MAX_ROW_INDEX) {
|
|
132
|
+
return "".concat(first.colRelative ? "" : "$").concat(number2Alpha(first.col), ":").concat(last.colRelative ? "" : "$").concat(number2Alpha(last.col));
|
|
133
|
+
}
|
|
134
|
+
if (first.col === 0 && last.col === MAX_COL_INDEX) {
|
|
135
|
+
return "".concat(first.rowRelative ? "" : "$").concat(first.row + 1, ":").concat(last.rowRelative ? "" : "$").concat(last.row + 1);
|
|
136
|
+
}
|
|
137
|
+
return "".concat(cellRef(first.row, first.col, first.rowRelative, first.colRelative), ":").concat(cellRef(last.row, last.col, last.rowRelative, last.colRelative));
|
|
138
|
+
};
|
|
139
|
+
/** `RgceLoc` / `RgceArea` corner: a 20-bit row (u32) and a 14-bit column with its relative flags (u16). */
|
|
140
|
+
var corner = function (row, colField) { return ({
|
|
141
|
+
row: row & MAX_ROW_INDEX,
|
|
142
|
+
col: colField & MAX_COL_INDEX,
|
|
143
|
+
rowRelative: (colField & 0x8000) !== 0,
|
|
144
|
+
colRelative: (colField & 0x4000) !== 0,
|
|
145
|
+
}); };
|
|
146
|
+
/** A `RgceLocRel` corner of a shared formula or name: relative parts are offsets from the base cell. */
|
|
147
|
+
var relativeCorner = function (rowField, colField, base) {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
var rowRelative = (colField & 0x8000) !== 0;
|
|
150
|
+
var colRelative = (colField & 0x4000) !== 0;
|
|
151
|
+
if ((rowRelative || colRelative) && !base) {
|
|
152
|
+
throw new RgceUnsupportedError("relative reference without a base cell");
|
|
153
|
+
}
|
|
154
|
+
var baseRow = ((_a = base === null || base === void 0 ? void 0 : base.row) !== null && _a !== void 0 ? _a : 1) - 1;
|
|
155
|
+
var baseCol = ((_b = base === null || base === void 0 ? void 0 : base.col) !== null && _b !== void 0 ? _b : 1) - 1;
|
|
156
|
+
// A relative column is a signed 14-bit offset; a relative row a signed 32-bit one.
|
|
157
|
+
var colOffset = ((colField & MAX_COL_INDEX) << 18) >> 18;
|
|
158
|
+
var row = rowRelative ? baseRow + rowField : rowField;
|
|
159
|
+
var col = colRelative ? baseCol + colOffset : colField & MAX_COL_INDEX;
|
|
160
|
+
// Offsets wrap around the sheet, as Excel's do.
|
|
161
|
+
return {
|
|
162
|
+
row: ((row % (MAX_ROW_INDEX + 1)) + MAX_ROW_INDEX + 1) % (MAX_ROW_INDEX + 1),
|
|
163
|
+
col: ((col % (MAX_COL_INDEX + 1)) + MAX_COL_INDEX + 1) % (MAX_COL_INDEX + 1),
|
|
164
|
+
rowRelative: rowRelative,
|
|
165
|
+
colRelative: colRelative,
|
|
166
|
+
};
|
|
167
|
+
};
|
|
115
168
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* @
|
|
119
|
-
*
|
|
169
|
+
* Decode a formula's tokens into its text, without the leading `=`.
|
|
170
|
+
*
|
|
171
|
+
* Throws {@link RgceUnsupportedError} when any part of the formula cannot be
|
|
172
|
+
* decoded exactly.
|
|
120
173
|
*/
|
|
121
|
-
export function
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
var stack = [];
|
|
127
|
-
if (debug) {
|
|
128
|
-
console.log("[Rgce] Parsing", rgceBytes.length, "bytes:", Array.from(rgceBytes.slice(0, Math.min(30, rgceBytes.length)))
|
|
129
|
-
.map(function (b) { return "0x".concat(b.toString(16).padStart(2, '0')); })
|
|
130
|
-
.join(' '));
|
|
174
|
+
export function decodeRgce(rgce, context) {
|
|
175
|
+
var _a, _b;
|
|
176
|
+
if (context === void 0) { context = {}; }
|
|
177
|
+
if (rgce.length === 0) {
|
|
178
|
+
throw new RgceUnsupportedError("empty formula");
|
|
131
179
|
}
|
|
132
|
-
var
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
25: 1, // INT
|
|
142
|
-
27: 2, // ROUND
|
|
143
|
-
31: 3, // MID
|
|
144
|
-
32: 1, // LEN
|
|
145
|
-
34: 0, // TRUE
|
|
146
|
-
35: 0, // FALSE
|
|
147
|
-
39: 2, // MOD
|
|
148
|
-
65: 3, // DATE
|
|
149
|
-
66: 3, // TIME
|
|
150
|
-
67: 1, // DAY
|
|
151
|
-
68: 1, // MONTH
|
|
152
|
-
69: 1, // YEAR
|
|
153
|
-
71: 1, // HOUR
|
|
154
|
-
72: 1, // MINUTE
|
|
155
|
-
73: 1, // SECOND
|
|
156
|
-
74: 0, // NOW
|
|
157
|
-
105: 1, // CHAR
|
|
158
|
-
106: 1, // LOWER
|
|
159
|
-
107: 1, // UPPER
|
|
160
|
-
109: 2, // LEFT
|
|
161
|
-
110: 2, // RIGHT
|
|
162
|
-
111: 2, // EXACT
|
|
163
|
-
112: 1, // TRIM
|
|
164
|
-
115: 1, // CODE
|
|
165
|
-
183: 1, // PRODUCT
|
|
166
|
-
197: 2, // TRUNC
|
|
167
|
-
221: 0, // TODAY
|
|
168
|
-
335: 2, // POWER
|
|
169
|
-
336: 1, // RADIANS
|
|
170
|
-
337: 1, // DEGREES
|
|
171
|
-
};
|
|
172
|
-
var canRead = function (n) { return reader.offset + n <= rgceBytes.length; };
|
|
173
|
-
var quoteSheetName = function (name) {
|
|
174
|
-
return /[\s!'[\]]/.test(name) ? "'".concat(name.replace(/'/g, "''"), "'") : name;
|
|
175
|
-
};
|
|
176
|
-
var resolveSheetName = function (ixti) {
|
|
177
|
-
if (typeof sheetRefResolver === "function") {
|
|
178
|
-
return sheetRefResolver(ixti);
|
|
180
|
+
var reader = new Reader(rgce);
|
|
181
|
+
var stack = [];
|
|
182
|
+
// Stack slots holding a union without its parentheses: fine as a whole
|
|
183
|
+
// formula (`A1,C3`), but an argument must say it is one (`SUM((A1,C3))`).
|
|
184
|
+
var bareUnions = new Set();
|
|
185
|
+
var pop = function () {
|
|
186
|
+
var value = stack.pop();
|
|
187
|
+
if (value === undefined) {
|
|
188
|
+
throw new RgceUnsupportedError("operator without an operand");
|
|
179
189
|
}
|
|
180
|
-
|
|
190
|
+
bareUnions.delete(stack.length);
|
|
191
|
+
return value;
|
|
181
192
|
};
|
|
182
193
|
var popArgs = function (count) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
194
|
+
if (count > stack.length) {
|
|
195
|
+
throw new RgceUnsupportedError("function without all its arguments");
|
|
196
|
+
}
|
|
197
|
+
var first = stack.length - count;
|
|
198
|
+
return stack.splice(first, count).map(function (arg, at) {
|
|
199
|
+
var isBareUnion = bareUnions.delete(first + at);
|
|
200
|
+
return isBareUnion ? "(".concat(arg, ")") : arg;
|
|
201
|
+
});
|
|
187
202
|
};
|
|
188
|
-
var
|
|
203
|
+
var sheet = function (ixti) {
|
|
189
204
|
var _a;
|
|
190
|
-
var
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
var funcName = FUNCTION_NAMES[ftabIndex] || "FUNC".concat(ftabIndex);
|
|
196
|
-
stack.push("".concat(funcName, "(").concat(popArgs(cargs).join(","), ")"));
|
|
197
|
-
};
|
|
198
|
-
var formatRef = function (rowZero, colZero, rowRel, colRel) {
|
|
199
|
-
var row = Math.max(0, rowZero);
|
|
200
|
-
var col = Math.max(0, colZero);
|
|
201
|
-
return "".concat(colRel ? "" : "$").concat(number2Alpha(col)).concat(rowRel ? "" : "$").concat(row + 1);
|
|
202
|
-
};
|
|
203
|
-
var readShortRef = function () {
|
|
204
|
-
var row = reader.readUInt32LE();
|
|
205
|
-
var col = reader.readUInt16LE();
|
|
206
|
-
var rowRel = (col & 0x8000) !== 0;
|
|
207
|
-
var colRel = (col & 0x4000) !== 0;
|
|
208
|
-
return formatRef(row & 0x000fffff, col & 0x3fff, rowRel, colRel);
|
|
209
|
-
};
|
|
210
|
-
var readShortArea = function () {
|
|
211
|
-
var rowFirst = reader.readUInt32LE();
|
|
212
|
-
var rowLast = reader.readUInt32LE();
|
|
213
|
-
var colFirst = reader.readUInt16LE();
|
|
214
|
-
var colLast = reader.readUInt16LE();
|
|
215
|
-
var refFirst = formatRef(rowFirst & 0x000fffff, colFirst & 0x3fff, (colFirst & 0x8000) !== 0, (colFirst & 0x4000) !== 0);
|
|
216
|
-
var refLast = formatRef(rowLast & 0x000fffff, colLast & 0x3fff, (colLast & 0x8000) !== 0, (colLast & 0x4000) !== 0);
|
|
217
|
-
return "".concat(refFirst, ":").concat(refLast);
|
|
218
|
-
};
|
|
219
|
-
var readRelShortRef = function () {
|
|
220
|
-
var _a, _b;
|
|
221
|
-
var rowOffset = reader.readInt32LE();
|
|
222
|
-
var colRaw = reader.readInt16LE();
|
|
223
|
-
var colOffset14 = colRaw & 0x3fff;
|
|
224
|
-
var colOffset = (colOffset14 << 18) >> 18;
|
|
225
|
-
var baseRowZero = Math.max(0, ((_a = baseCell === null || baseCell === void 0 ? void 0 : baseCell.row) !== null && _a !== void 0 ? _a : 1) - 1);
|
|
226
|
-
var baseColZero = Math.max(0, ((_b = baseCell === null || baseCell === void 0 ? void 0 : baseCell.col) !== null && _b !== void 0 ? _b : 1) - 1);
|
|
227
|
-
return formatRef(baseRowZero + rowOffset, baseColZero + colOffset, true, true);
|
|
205
|
+
var name = (_a = context.sheetName) === null || _a === void 0 ? void 0 : _a.call(context, ixti);
|
|
206
|
+
if (name === undefined) {
|
|
207
|
+
throw new RgceUnsupportedError("unknown sheet reference ".concat(ixti));
|
|
208
|
+
}
|
|
209
|
+
return quoteSheetName(name);
|
|
228
210
|
};
|
|
229
|
-
var
|
|
230
|
-
var
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
var colFirstOffset = ((colFirstRaw & 0x3fff) << 18) >> 18;
|
|
236
|
-
var colLastOffset = ((colLastRaw & 0x3fff) << 18) >> 18;
|
|
237
|
-
var baseRowZero = Math.max(0, ((_a = baseCell === null || baseCell === void 0 ? void 0 : baseCell.row) !== null && _a !== void 0 ? _a : 1) - 1);
|
|
238
|
-
var baseColZero = Math.max(0, ((_b = baseCell === null || baseCell === void 0 ? void 0 : baseCell.col) !== null && _b !== void 0 ? _b : 1) - 1);
|
|
239
|
-
var refFirst = formatRef(baseRowZero + rowFirstOffset, baseColZero + colFirstOffset, true, true);
|
|
240
|
-
var refLast = formatRef(baseRowZero + rowLastOffset, baseColZero + colLastOffset, true, true);
|
|
241
|
-
return "".concat(refFirst, ":").concat(refLast);
|
|
211
|
+
var callFunction = function (iftab, args) {
|
|
212
|
+
var name = FTAB[iftab];
|
|
213
|
+
if (!name) {
|
|
214
|
+
throw new RgceUnsupportedError("unknown function ".concat(iftab));
|
|
215
|
+
}
|
|
216
|
+
return "".concat(name, "(").concat(args.join(","), ")");
|
|
242
217
|
};
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
var left = stack.pop() || "0";
|
|
269
|
-
stack.push("".concat(left, "*").concat(right));
|
|
270
|
-
}
|
|
271
|
-
else if (ptg === 0x06) {
|
|
272
|
-
// PtgDiv
|
|
273
|
-
var right = stack.pop() || "0";
|
|
274
|
-
var left = stack.pop() || "0";
|
|
275
|
-
stack.push("".concat(left, "/").concat(right));
|
|
276
|
-
}
|
|
277
|
-
else if (ptg === 0x07) {
|
|
278
|
-
// PtgPower
|
|
279
|
-
var right = stack.pop() || "0";
|
|
280
|
-
var left = stack.pop() || "0";
|
|
281
|
-
stack.push("".concat(left, "^").concat(right));
|
|
282
|
-
}
|
|
283
|
-
else if (ptg === 0x08) {
|
|
284
|
-
// PtgConcat
|
|
285
|
-
var right = stack.pop() || '""';
|
|
286
|
-
var left = stack.pop() || '""';
|
|
287
|
-
stack.push("".concat(left, "&").concat(right));
|
|
288
|
-
}
|
|
289
|
-
else if (ptg === 0x09) {
|
|
290
|
-
// PtgLT
|
|
291
|
-
var right = stack.pop() || "0";
|
|
292
|
-
var left = stack.pop() || "0";
|
|
293
|
-
stack.push("".concat(left, "<").concat(right));
|
|
294
|
-
}
|
|
295
|
-
else if (ptg === 0x0a) {
|
|
296
|
-
// PtgLE
|
|
297
|
-
var right = stack.pop() || "0";
|
|
298
|
-
var left = stack.pop() || "0";
|
|
299
|
-
stack.push("".concat(left, "<=").concat(right));
|
|
300
|
-
}
|
|
301
|
-
else if (ptg === 0x0b) {
|
|
302
|
-
// PtgEQ
|
|
303
|
-
var right = stack.pop() || "0";
|
|
304
|
-
var left = stack.pop() || "0";
|
|
305
|
-
stack.push("".concat(left, "=").concat(right));
|
|
306
|
-
}
|
|
307
|
-
else if (ptg === 0x0c) {
|
|
308
|
-
// PtgGE
|
|
309
|
-
var right = stack.pop() || "0";
|
|
310
|
-
var left = stack.pop() || "0";
|
|
311
|
-
stack.push("".concat(left, ">=").concat(right));
|
|
312
|
-
}
|
|
313
|
-
else if (ptg === 0x0d) {
|
|
314
|
-
// PtgGT
|
|
315
|
-
var right = stack.pop() || "0";
|
|
316
|
-
var left = stack.pop() || "0";
|
|
317
|
-
stack.push("".concat(left, ">").concat(right));
|
|
318
|
-
}
|
|
319
|
-
else if (ptg === 0x0e) {
|
|
320
|
-
// PtgNE
|
|
321
|
-
var right = stack.pop() || "0";
|
|
322
|
-
var left = stack.pop() || "0";
|
|
323
|
-
stack.push("".concat(left, "<>").concat(right));
|
|
324
|
-
}
|
|
325
|
-
else if (ptg === 0x12) {
|
|
326
|
-
// PtgUPlus
|
|
327
|
-
var operand = stack.pop() || "0";
|
|
328
|
-
stack.push("+".concat(operand));
|
|
329
|
-
}
|
|
330
|
-
else if (ptg === 0x13) {
|
|
331
|
-
// PtgUMinus
|
|
332
|
-
var operand = stack.pop() || "0";
|
|
333
|
-
stack.push("-".concat(operand));
|
|
334
|
-
}
|
|
335
|
-
else if (ptg === 0x14) {
|
|
336
|
-
// PtgPercent
|
|
337
|
-
var operand = stack.pop() || "0";
|
|
338
|
-
stack.push("".concat(operand, "%"));
|
|
339
|
-
}
|
|
340
|
-
else if (ptg === 0x15) {
|
|
341
|
-
// PtgParen
|
|
342
|
-
var operand = stack.pop() || "";
|
|
343
|
-
stack.push("(".concat(operand, ")"));
|
|
344
|
-
}
|
|
345
|
-
else if (ptg === 0x16) {
|
|
346
|
-
// PtgMissArg - missing argument (empty between commas)
|
|
218
|
+
while (!reader.done) {
|
|
219
|
+
var ptg = reader.u8();
|
|
220
|
+
var binary = BINARY_OPERATORS[ptg];
|
|
221
|
+
if (binary !== undefined) {
|
|
222
|
+
var right = pop();
|
|
223
|
+
var left = pop();
|
|
224
|
+
if (ptg === PTG_UNION)
|
|
225
|
+
bareUnions.add(stack.length);
|
|
226
|
+
stack.push("".concat(left).concat(binary).concat(right));
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
switch (ptg) {
|
|
230
|
+
case 0x12: // PtgUplus
|
|
231
|
+
stack.push("+".concat(pop()));
|
|
232
|
+
continue;
|
|
233
|
+
case 0x13: // PtgUminus
|
|
234
|
+
stack.push("-".concat(pop()));
|
|
235
|
+
continue;
|
|
236
|
+
case 0x14: // PtgPercent
|
|
237
|
+
stack.push("".concat(pop(), "%"));
|
|
238
|
+
continue;
|
|
239
|
+
case 0x15: // PtgParen
|
|
240
|
+
stack.push("(".concat(pop(), ")"));
|
|
241
|
+
continue;
|
|
242
|
+
case 0x16: // PtgMissArg
|
|
347
243
|
stack.push("");
|
|
244
|
+
continue;
|
|
245
|
+
case 0x17: {
|
|
246
|
+
// PtgStr: a 16-bit character count, then UTF-16LE.
|
|
247
|
+
var text = reader.utf16(reader.u16());
|
|
248
|
+
stack.push("\"".concat(text.replace(/"/g, '""'), "\""));
|
|
249
|
+
continue;
|
|
348
250
|
}
|
|
349
|
-
|
|
350
|
-
//
|
|
351
|
-
var
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// PtgBool - boolean constant
|
|
356
|
-
var value = reader.readUInt8();
|
|
357
|
-
stack.push(value ? "TRUE" : "FALSE");
|
|
358
|
-
}
|
|
359
|
-
else if (ptg === 0x1e) {
|
|
360
|
-
// PtgInt - integer constant
|
|
361
|
-
var value = reader.readUInt16LE();
|
|
362
|
-
stack.push(String(value));
|
|
363
|
-
}
|
|
364
|
-
else if (ptg === 0x1f) {
|
|
365
|
-
// PtgNum - float constant
|
|
366
|
-
var value = reader.readFloat64LE();
|
|
367
|
-
stack.push(String(value));
|
|
368
|
-
}
|
|
369
|
-
else if (ptg === 0x18) {
|
|
370
|
-
// PtgErr - error constant
|
|
371
|
-
if (!canRead(1))
|
|
372
|
-
break;
|
|
373
|
-
var code = reader.readUInt8();
|
|
374
|
-
var errorValues = {
|
|
375
|
-
0x00: "#NULL!",
|
|
376
|
-
0x07: "#DIV/0!",
|
|
377
|
-
0x0f: "#VALUE!",
|
|
378
|
-
0x17: "#REF!",
|
|
379
|
-
0x1d: "#NAME?",
|
|
380
|
-
0x24: "#NUM!",
|
|
381
|
-
0x2a: "#N/A",
|
|
382
|
-
0x2b: "#GETTING_DATA",
|
|
383
|
-
};
|
|
384
|
-
stack.push(errorValues[code] || "#VALUE!");
|
|
385
|
-
}
|
|
386
|
-
else if (ptg === 0x19) {
|
|
387
|
-
// PtgAttr: 1 byte flags + 2 bytes data
|
|
388
|
-
if (!canRead(3))
|
|
389
|
-
break;
|
|
390
|
-
var flags = reader.readUInt8();
|
|
391
|
-
var data = reader.readUInt16LE();
|
|
392
|
-
// Handle various PtgAttr flags
|
|
393
|
-
if ((flags & 0x10) !== 0) {
|
|
394
|
-
// fSum: treat previous operand as SUM(operand)
|
|
395
|
-
var operand = stack.pop() || "";
|
|
396
|
-
stack.push("SUM(".concat(operand, ")"));
|
|
397
|
-
}
|
|
398
|
-
// Note: Other flags (fIf=0x02, fChoose=0x04, fSkip=0x08, fGoto=0x01)
|
|
399
|
-
// are for control flow and typically don't affect the formula string
|
|
400
|
-
// They just affect how bytes are skipped during parsing
|
|
401
|
-
}
|
|
402
|
-
else if (ptg === 0x01) {
|
|
403
|
-
// Ambiguous in some XLSB streams:
|
|
404
|
-
// - PtgExp (4-byte payload)
|
|
405
|
-
// - PtgFunc ref-class variant (2-byte payload)
|
|
406
|
-
if (canRead(4)) {
|
|
407
|
-
var srcRow = reader.readUInt16LE() + 1;
|
|
408
|
-
var srcCol = reader.readUInt16LE() + 1;
|
|
409
|
-
stack.push("__PTGEXP__:".concat(srcRow, ":").concat(srcCol));
|
|
251
|
+
case 0x19: {
|
|
252
|
+
// PtgAttr: a kind byte and 16 bits of data.
|
|
253
|
+
var kind = reader.u8();
|
|
254
|
+
var data = reader.u16();
|
|
255
|
+
if (kind === ATTR_SUM) {
|
|
256
|
+
stack.push("SUM(".concat(popArgs(1)[0], ")"));
|
|
410
257
|
}
|
|
411
|
-
else if (
|
|
412
|
-
|
|
258
|
+
else if (kind === ATTR_CHOOSE) {
|
|
259
|
+
reader.skip((data + 1) * 2); // CHOOSE's jump table
|
|
413
260
|
}
|
|
414
|
-
else {
|
|
415
|
-
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
else if (ptg === 0x02) {
|
|
419
|
-
// PtgFuncVar reference-class variant (0x02)
|
|
420
|
-
// In practice, 0x02 is PtgFuncVar, not PtgTbl
|
|
421
|
-
if (canRead(3)) {
|
|
422
|
-
var cargs = reader.readUInt8();
|
|
423
|
-
pushVariableFunction(cargs, reader.readUInt16LE());
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
break;
|
|
261
|
+
else if (!ATTR_NO_EFFECT.has(kind)) {
|
|
262
|
+
throw new RgceUnsupportedError("attribute 0x".concat(kind.toString(16)));
|
|
427
263
|
}
|
|
264
|
+
continue;
|
|
428
265
|
}
|
|
429
|
-
|
|
430
|
-
//
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
var cellRef = readShortRef();
|
|
435
|
-
// Get sheet name if available
|
|
436
|
-
var sheetName = resolveSheetName(ixti);
|
|
437
|
-
if (sheetName) {
|
|
438
|
-
var quotedName = quoteSheetName(sheetName);
|
|
439
|
-
stack.push("".concat(quotedName, "!").concat(cellRef));
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
stack.push(cellRef);
|
|
266
|
+
case 0x1c: {
|
|
267
|
+
// PtgErr
|
|
268
|
+
var text = ERROR_CODES[reader.u8()];
|
|
269
|
+
if (text === undefined) {
|
|
270
|
+
throw new RgceUnsupportedError("unknown error constant");
|
|
443
271
|
}
|
|
272
|
+
stack.push(text);
|
|
273
|
+
continue;
|
|
444
274
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
275
|
+
case 0x1d: // PtgBool
|
|
276
|
+
stack.push(reader.u8() !== 0 ? "TRUE" : "FALSE");
|
|
277
|
+
continue;
|
|
278
|
+
case 0x1e: // PtgInt
|
|
279
|
+
stack.push(String(reader.u16()));
|
|
280
|
+
continue;
|
|
281
|
+
case 0x1f: // PtgNum
|
|
282
|
+
stack.push(formatNumber(reader.f64()));
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
// Operand and function tokens carry a value class in bits 5-6.
|
|
286
|
+
switch (ptg) {
|
|
287
|
+
case 0x21:
|
|
288
|
+
case 0x41:
|
|
289
|
+
case 0x61: {
|
|
290
|
+
// PtgFunc: a fixed-arity function.
|
|
291
|
+
var iftab = reader.u16();
|
|
292
|
+
var argc = FTAB_FIXED_ARGC[iftab];
|
|
293
|
+
if (argc === undefined || argc < 0) {
|
|
294
|
+
throw new RgceUnsupportedError("function ".concat(iftab, " is not fixed-arity"));
|
|
459
295
|
}
|
|
296
|
+
stack.push(callFunction(iftab, popArgs(argc)));
|
|
297
|
+
continue;
|
|
460
298
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
else if (basePtg === 0x02) {
|
|
471
|
-
// PtgFuncVar - function with variable args
|
|
472
|
-
if (!canRead(3))
|
|
473
|
-
break;
|
|
474
|
-
var cargs = reader.readUInt8();
|
|
475
|
-
pushVariableFunction(cargs, reader.readUInt16LE());
|
|
476
|
-
}
|
|
477
|
-
else if (basePtg === 0x04) {
|
|
478
|
-
// PtgRef - cell reference
|
|
479
|
-
if (!canRead(6))
|
|
480
|
-
break;
|
|
481
|
-
stack.push(readShortRef());
|
|
482
|
-
}
|
|
483
|
-
else if (basePtg === 0x05) {
|
|
484
|
-
// PtgArea - range reference
|
|
485
|
-
if (!canRead(12))
|
|
486
|
-
break;
|
|
487
|
-
stack.push(readShortArea());
|
|
299
|
+
case 0x22:
|
|
300
|
+
case 0x42:
|
|
301
|
+
case 0x62: {
|
|
302
|
+
// PtgFuncVar: the argument count (up to 255), then the function (bit 15: a command).
|
|
303
|
+
var argc = reader.u8();
|
|
304
|
+
var field = reader.u16();
|
|
305
|
+
if (field & 0x8000) {
|
|
306
|
+
throw new RgceUnsupportedError("command-equivalent function");
|
|
488
307
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
break;
|
|
499
|
-
stack.push(readRelShortArea());
|
|
308
|
+
var iftab = field & 0x7fff;
|
|
309
|
+
var args = popArgs(argc);
|
|
310
|
+
if (iftab === 0xff) {
|
|
311
|
+
// A user-defined or add-in function: its name is the first argument.
|
|
312
|
+
var _c = __read(args), name_1 = _c[0], rest = _c.slice(1);
|
|
313
|
+
if (!name_1) {
|
|
314
|
+
throw new RgceUnsupportedError("user-defined function without a name");
|
|
315
|
+
}
|
|
316
|
+
stack.push("".concat(name_1, "(").concat(rest.join(","), ")"));
|
|
500
317
|
}
|
|
501
318
|
else {
|
|
502
|
-
|
|
503
|
-
break;
|
|
319
|
+
stack.push(callFunction(iftab, args));
|
|
504
320
|
}
|
|
321
|
+
continue;
|
|
505
322
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
323
|
+
case 0x23:
|
|
324
|
+
case 0x43:
|
|
325
|
+
case 0x63: {
|
|
326
|
+
// PtgName: a 1-based index into the workbook's names.
|
|
327
|
+
var index = reader.u32();
|
|
328
|
+
var name_2 = (_a = context.definedName) === null || _a === void 0 ? void 0 : _a.call(context, index);
|
|
329
|
+
if (name_2 === undefined) {
|
|
330
|
+
throw new RgceUnsupportedError("unknown defined name ".concat(index));
|
|
510
331
|
}
|
|
511
|
-
|
|
332
|
+
stack.push(name_2);
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
case 0x24:
|
|
336
|
+
case 0x44:
|
|
337
|
+
case 0x64: {
|
|
338
|
+
// PtgRef
|
|
339
|
+
var row = reader.u32();
|
|
340
|
+
var c = corner(row, reader.u16());
|
|
341
|
+
stack.push(cellRef(c.row, c.col, c.rowRelative, c.colRelative));
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
case 0x25:
|
|
345
|
+
case 0x45:
|
|
346
|
+
case 0x65: {
|
|
347
|
+
// PtgArea
|
|
348
|
+
var rowFirst = reader.u32();
|
|
349
|
+
var rowLast = reader.u32();
|
|
350
|
+
var colFirst = reader.u16();
|
|
351
|
+
var colLast = reader.u16();
|
|
352
|
+
stack.push(areaRef(corner(rowFirst, colFirst), corner(rowLast, colLast)));
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
case 0x26:
|
|
356
|
+
case 0x46:
|
|
357
|
+
case 0x66: // PtgMemArea
|
|
358
|
+
case 0x27:
|
|
359
|
+
case 0x47:
|
|
360
|
+
case 0x67: // PtgMemErr
|
|
361
|
+
case 0x28:
|
|
362
|
+
case 0x48:
|
|
363
|
+
case 0x68: // PtgMemNoMem
|
|
364
|
+
// A precomputed reference: the tokens that follow compute it.
|
|
365
|
+
reader.skip(4);
|
|
366
|
+
reader.u16(); // cce
|
|
367
|
+
continue;
|
|
368
|
+
case 0x29:
|
|
369
|
+
case 0x49:
|
|
370
|
+
case 0x69: // PtgMemFunc
|
|
371
|
+
reader.u16(); // cce
|
|
372
|
+
continue;
|
|
373
|
+
case 0x2a:
|
|
374
|
+
case 0x4a:
|
|
375
|
+
case 0x6a: // PtgRefErr
|
|
376
|
+
reader.skip(6);
|
|
377
|
+
stack.push("#REF!");
|
|
378
|
+
continue;
|
|
379
|
+
case 0x2b:
|
|
380
|
+
case 0x4b:
|
|
381
|
+
case 0x6b: // PtgAreaErr
|
|
382
|
+
reader.skip(12);
|
|
383
|
+
stack.push("#REF!");
|
|
384
|
+
continue;
|
|
385
|
+
case 0x2c:
|
|
386
|
+
case 0x4c:
|
|
387
|
+
case 0x6c: {
|
|
388
|
+
// PtgRefN: relative to the base cell.
|
|
389
|
+
var row = reader.i32();
|
|
390
|
+
var c = relativeCorner(row, reader.u16(), context.baseCell);
|
|
391
|
+
stack.push(cellRef(c.row, c.col, c.rowRelative, c.colRelative));
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
case 0x2d:
|
|
395
|
+
case 0x4d:
|
|
396
|
+
case 0x6d: {
|
|
397
|
+
// PtgAreaN
|
|
398
|
+
var rowFirst = reader.i32();
|
|
399
|
+
var rowLast = reader.i32();
|
|
400
|
+
var colFirst = reader.u16();
|
|
401
|
+
var colLast = reader.u16();
|
|
402
|
+
stack.push(areaRef(relativeCorner(rowFirst, colFirst, context.baseCell), relativeCorner(rowLast, colLast, context.baseCell)));
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
case 0x3a:
|
|
406
|
+
case 0x5a:
|
|
407
|
+
case 0x7a: {
|
|
408
|
+
// PtgRef3d
|
|
409
|
+
var prefix = sheet(reader.u16());
|
|
410
|
+
var row = reader.u32();
|
|
411
|
+
var c = corner(row, reader.u16());
|
|
412
|
+
stack.push("".concat(prefix, "!").concat(cellRef(c.row, c.col, c.rowRelative, c.colRelative)));
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
case 0x3b:
|
|
416
|
+
case 0x5b:
|
|
417
|
+
case 0x7b: {
|
|
418
|
+
// PtgArea3d
|
|
419
|
+
var prefix = sheet(reader.u16());
|
|
420
|
+
var rowFirst = reader.u32();
|
|
421
|
+
var rowLast = reader.u32();
|
|
422
|
+
var colFirst = reader.u16();
|
|
423
|
+
var colLast = reader.u16();
|
|
424
|
+
stack.push("".concat(prefix, "!").concat(areaRef(corner(rowFirst, colFirst), corner(rowLast, colLast))));
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
case 0x3c:
|
|
428
|
+
case 0x5c:
|
|
429
|
+
case 0x7c: // PtgRefErr3d
|
|
430
|
+
case 0x3d:
|
|
431
|
+
case 0x5d:
|
|
432
|
+
case 0x7d: {
|
|
433
|
+
// PtgAreaErr3d. Excel keeps the sheet a deleted reference was on
|
|
434
|
+
// (`Sheet1!#REF!`); on a sheet it cannot name, the error alone.
|
|
435
|
+
var ixti = reader.u16();
|
|
436
|
+
var name_3 = (_b = context.sheetName) === null || _b === void 0 ? void 0 : _b.call(context, ixti);
|
|
437
|
+
reader.skip((ptg & 0x1f) === 0x1c ? 6 : 12);
|
|
438
|
+
stack.push(name_3 === undefined ? "#REF!" : "".concat(quoteSheetName(name_3), "!#REF!"));
|
|
439
|
+
continue;
|
|
512
440
|
}
|
|
513
441
|
}
|
|
442
|
+
// PtgExp / PtgTbl (shared, array or data-table formulas), PtgArray,
|
|
443
|
+
// PtgNameX, the extended tokens (structured references) and anything else.
|
|
444
|
+
throw new RgceUnsupportedError("token 0x".concat(ptg.toString(16)));
|
|
514
445
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
446
|
+
if (stack.length !== 1) {
|
|
447
|
+
throw new RgceUnsupportedError("formula leaves ".concat(stack.length, " expressions"));
|
|
448
|
+
}
|
|
449
|
+
return stack[0];
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* A formula's text, or `""` when it cannot be decoded exactly — never a part of
|
|
453
|
+
* one. Prefer {@link decodeRgce}, which says why.
|
|
454
|
+
*
|
|
455
|
+
* @deprecated the lenient form of {@link decodeRgce}.
|
|
456
|
+
*/
|
|
457
|
+
export function parseRgce(rgceBytes, sheetRefResolver, baseCell) {
|
|
458
|
+
if (!rgceBytes || rgceBytes.length === 0)
|
|
459
|
+
return "";
|
|
460
|
+
var sheetName = typeof sheetRefResolver === "function"
|
|
461
|
+
? sheetRefResolver
|
|
462
|
+
: function (ixti) { return sheetRefResolver === null || sheetRefResolver === void 0 ? void 0 : sheetRefResolver[ixti]; };
|
|
463
|
+
try {
|
|
464
|
+
return decodeRgce(rgceBytes, { sheetName: sheetName, baseCell: baseCell });
|
|
521
465
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
466
|
+
catch (error) {
|
|
467
|
+
if (error instanceof RgceUnsupportedError)
|
|
468
|
+
return "";
|
|
469
|
+
throw error;
|
|
525
470
|
}
|
|
526
|
-
return result;
|
|
527
471
|
}
|