@rowsncolumns/utils 9.2.35
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/LICENSE.md +100 -0
- package/dist/cjs/array.d.ts +3 -0
- package/dist/cjs/array.d.ts.map +1 -0
- package/dist/cjs/array.js +19 -0
- package/dist/cjs/cell-data-helpers.d.ts +19 -0
- package/dist/cjs/cell-data-helpers.d.ts.map +1 -0
- package/dist/cjs/cell-data-helpers.js +64 -0
- package/dist/cjs/color.d.ts +20 -0
- package/dist/cjs/color.d.ts.map +1 -0
- package/dist/cjs/color.js +168 -0
- package/dist/cjs/colors.d.ts +2 -0
- package/dist/cjs/colors.d.ts.map +1 -0
- package/dist/cjs/colors.js +78 -0
- package/dist/cjs/conditional-format.d.ts +49 -0
- package/dist/cjs/conditional-format.d.ts.map +1 -0
- package/dist/cjs/conditional-format.js +227 -0
- package/dist/cjs/content-hash.d.ts +16 -0
- package/dist/cjs/content-hash.d.ts.map +1 -0
- package/dist/cjs/content-hash.js +72 -0
- package/dist/cjs/data-validation.d.ts +54 -0
- package/dist/cjs/data-validation.d.ts.map +1 -0
- package/dist/cjs/data-validation.js +249 -0
- package/dist/cjs/date.d.ts +15 -0
- package/dist/cjs/date.d.ts.map +1 -0
- package/dist/cjs/date.js +56 -0
- package/dist/cjs/dom.d.ts +10 -0
- package/dist/cjs/dom.d.ts.map +1 -0
- package/dist/cjs/dom.js +97 -0
- package/dist/cjs/formatter.d.ts +22 -0
- package/dist/cjs/formatter.d.ts.map +1 -0
- package/dist/cjs/formatter.js +264 -0
- package/dist/cjs/formula-refs.d.ts +7 -0
- package/dist/cjs/formula-refs.d.ts.map +1 -0
- package/dist/cjs/formula-refs.js +54 -0
- package/dist/cjs/formula.d.ts +80 -0
- package/dist/cjs/formula.d.ts.map +1 -0
- package/dist/cjs/formula.js +401 -0
- package/dist/cjs/index.d.ts +24 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +26 -0
- package/dist/cjs/locale.d.ts +34 -0
- package/dist/cjs/locale.d.ts.map +1 -0
- package/dist/cjs/locale.js +260 -0
- package/dist/cjs/log.d.ts +4 -0
- package/dist/cjs/log.d.ts.map +1 -0
- package/dist/cjs/log.js +28 -0
- package/dist/cjs/memoize.d.ts +18 -0
- package/dist/cjs/memoize.d.ts.map +1 -0
- package/dist/cjs/memoize.js +128 -0
- package/dist/cjs/numbers.d.ts +19 -0
- package/dist/cjs/numbers.d.ts.map +1 -0
- package/dist/cjs/numbers.js +47 -0
- package/dist/cjs/selection.d.ts +88 -0
- package/dist/cjs/selection.d.ts.map +1 -0
- package/dist/cjs/selection.js +368 -0
- package/dist/cjs/shared-string-canonical.d.ts +18 -0
- package/dist/cjs/shared-string-canonical.d.ts.map +1 -0
- package/dist/cjs/shared-string-canonical.js +74 -0
- package/dist/cjs/sort.d.ts +15 -0
- package/dist/cjs/sort.d.ts.map +1 -0
- package/dist/cjs/sort.js +44 -0
- package/dist/cjs/string.d.ts +74 -0
- package/dist/cjs/string.d.ts.map +1 -0
- package/dist/cjs/string.js +237 -0
- package/dist/cjs/table-styles.d.ts +56 -0
- package/dist/cjs/table-styles.d.ts.map +1 -0
- package/dist/cjs/table-styles.js +362 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/cjs/typeguards.d.ts +4 -0
- package/dist/cjs/typeguards.d.ts.map +1 -0
- package/dist/cjs/typeguards.js +15 -0
- package/dist/cjs/uuid.d.ts +8 -0
- package/dist/cjs/uuid.d.ts.map +1 -0
- package/dist/cjs/uuid.js +30 -0
- package/dist/cjs/vitest.config.d.ts +3 -0
- package/dist/cjs/vitest.config.d.ts.map +1 -0
- package/dist/cjs/vitest.config.js +9 -0
- package/dist/esm/array.d.ts +3 -0
- package/dist/esm/array.d.ts.map +1 -0
- package/dist/esm/array.js +14 -0
- package/dist/esm/cell-data-helpers.d.ts +19 -0
- package/dist/esm/cell-data-helpers.d.ts.map +1 -0
- package/dist/esm/cell-data-helpers.js +39 -0
- package/dist/esm/color.d.ts +20 -0
- package/dist/esm/color.d.ts.map +1 -0
- package/dist/esm/color.js +152 -0
- package/dist/esm/colors.d.ts +2 -0
- package/dist/esm/colors.d.ts.map +1 -0
- package/dist/esm/colors.js +75 -0
- package/dist/esm/conditional-format.d.ts +49 -0
- package/dist/esm/conditional-format.d.ts.map +1 -0
- package/dist/esm/conditional-format.js +219 -0
- package/dist/esm/content-hash.d.ts +16 -0
- package/dist/esm/content-hash.d.ts.map +1 -0
- package/dist/esm/content-hash.js +68 -0
- package/dist/esm/data-validation.d.ts +54 -0
- package/dist/esm/data-validation.d.ts.map +1 -0
- package/dist/esm/data-validation.js +237 -0
- package/dist/esm/date.d.ts +15 -0
- package/dist/esm/date.d.ts.map +1 -0
- package/dist/esm/date.js +46 -0
- package/dist/esm/dom.d.ts +10 -0
- package/dist/esm/dom.d.ts.map +1 -0
- package/dist/esm/dom.js +90 -0
- package/dist/esm/formatter.d.ts +22 -0
- package/dist/esm/formatter.d.ts.map +1 -0
- package/dist/esm/formatter.js +253 -0
- package/dist/esm/formula-refs.d.ts +7 -0
- package/dist/esm/formula-refs.d.ts.map +1 -0
- package/dist/esm/formula-refs.js +49 -0
- package/dist/esm/formula.d.ts +80 -0
- package/dist/esm/formula.d.ts.map +1 -0
- package/dist/esm/formula.js +298 -0
- package/dist/esm/index.d.ts +24 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/locale.d.ts +34 -0
- package/dist/esm/locale.d.ts.map +1 -0
- package/dist/esm/locale.js +223 -0
- package/dist/esm/log.d.ts +4 -0
- package/dist/esm/log.d.ts.map +1 -0
- package/dist/esm/log.js +3 -0
- package/dist/esm/memoize.d.ts +18 -0
- package/dist/esm/memoize.d.ts.map +1 -0
- package/dist/esm/memoize.js +95 -0
- package/dist/esm/numbers.d.ts +19 -0
- package/dist/esm/numbers.d.ts.map +1 -0
- package/dist/esm/numbers.js +40 -0
- package/dist/esm/selection.d.ts +88 -0
- package/dist/esm/selection.d.ts.map +1 -0
- package/dist/esm/selection.js +311 -0
- package/dist/esm/shared-string-canonical.d.ts +18 -0
- package/dist/esm/shared-string-canonical.d.ts.map +1 -0
- package/dist/esm/shared-string-canonical.js +68 -0
- package/dist/esm/sort.d.ts +15 -0
- package/dist/esm/sort.d.ts.map +1 -0
- package/dist/esm/sort.js +39 -0
- package/dist/esm/string.d.ts +74 -0
- package/dist/esm/string.d.ts.map +1 -0
- package/dist/esm/string.js +213 -0
- package/dist/esm/table-styles.d.ts +56 -0
- package/dist/esm/table-styles.d.ts.map +1 -0
- package/dist/esm/table-styles.js +367 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/esm/typeguards.d.ts +4 -0
- package/dist/esm/typeguards.d.ts.map +1 -0
- package/dist/esm/typeguards.js +7 -0
- package/dist/esm/uuid.d.ts +8 -0
- package/dist/esm/uuid.d.ts.map +1 -0
- package/dist/esm/uuid.js +25 -0
- package/dist/esm/vitest.config.d.ts +3 -0
- package/dist/esm/vitest.config.d.ts.map +1 -0
- package/dist/esm/vitest.config.js +7 -0
- package/package.json +49 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { checkIfStringIsReference } from "./selection";
|
|
2
|
+
/* Close parenthesis mapping */
|
|
3
|
+
const inverseParenMap = {
|
|
4
|
+
"(": ")",
|
|
5
|
+
"[": "]",
|
|
6
|
+
};
|
|
7
|
+
/* Check if a str is function parenthesis */
|
|
8
|
+
const isParen = (char) => "()[]".indexOf(char) !== -1;
|
|
9
|
+
/* Check if a str is open parenthesis */
|
|
10
|
+
const isOpenParen = (char) => "(" === char || "[" === char;
|
|
11
|
+
/**
|
|
12
|
+
* Add/remove parenthesis in formulas
|
|
13
|
+
* @param str
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export const balanceParentheses = (str) => {
|
|
17
|
+
const chars = str.split("");
|
|
18
|
+
const stack = [];
|
|
19
|
+
for (let i = 0; i < chars.length; i++) {
|
|
20
|
+
const char = chars[i];
|
|
21
|
+
if (isParen(char)) {
|
|
22
|
+
if (isOpenParen(char)) {
|
|
23
|
+
stack.push(char);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (stack.length !== 0)
|
|
27
|
+
stack.pop();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return str + stack.map((item) => inverseParenMap[item]).join("");
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Add closing quotes in formulas when a string is unterminated.
|
|
35
|
+
* Handles escaped quotes ("") inside strings.
|
|
36
|
+
*/
|
|
37
|
+
export const balanceQuotes = (str) => {
|
|
38
|
+
let inString = false;
|
|
39
|
+
let openScopeCount = 0;
|
|
40
|
+
let stringStartScopeCount = 0;
|
|
41
|
+
for (let i = 0; i < str.length; i++) {
|
|
42
|
+
const char = str[i];
|
|
43
|
+
if (char === '"') {
|
|
44
|
+
if (inString && str[i + 1] === '"') {
|
|
45
|
+
i += 1;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
inString = !inString;
|
|
49
|
+
if (inString) {
|
|
50
|
+
stringStartScopeCount = openScopeCount;
|
|
51
|
+
}
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (!inString) {
|
|
55
|
+
if (isOpenParen(char)) {
|
|
56
|
+
openScopeCount++;
|
|
57
|
+
}
|
|
58
|
+
else if (char === ")" || char === "]") {
|
|
59
|
+
if (openScopeCount > 0)
|
|
60
|
+
openScopeCount--;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!inString) {
|
|
65
|
+
return str;
|
|
66
|
+
}
|
|
67
|
+
let insertIndex = str.length;
|
|
68
|
+
while (insertIndex > 0 && /\s/.test(str[insertIndex - 1])) {
|
|
69
|
+
insertIndex -= 1;
|
|
70
|
+
}
|
|
71
|
+
let closeStart = insertIndex;
|
|
72
|
+
while (closeStart > 0) {
|
|
73
|
+
const char = str[closeStart - 1];
|
|
74
|
+
if (char !== ")" && char !== "]")
|
|
75
|
+
break;
|
|
76
|
+
closeStart -= 1;
|
|
77
|
+
}
|
|
78
|
+
const trailingParensCount = insertIndex - closeStart;
|
|
79
|
+
const parensToKeepOutside = Math.min(stringStartScopeCount, trailingParensCount);
|
|
80
|
+
const insertionPos = insertIndex - parensToKeepOutside;
|
|
81
|
+
return `${str.slice(0, insertionPos)}"${str.slice(insertionPos)}`;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Add/remove parenthesis and add closing quotes in formulas.
|
|
85
|
+
*/
|
|
86
|
+
export const balanceFormula = (str) => {
|
|
87
|
+
return balanceParentheses(str);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Check if parenthesis is balanced
|
|
91
|
+
* @param str
|
|
92
|
+
* @returns
|
|
93
|
+
*/
|
|
94
|
+
export const isBalancedParenthesis = (str) => {
|
|
95
|
+
return balanceParentheses(str).length === str.length;
|
|
96
|
+
};
|
|
97
|
+
export const looksLikeMarkdown = (text) => {
|
|
98
|
+
const normalizedText = text.replace(/\\n/g, "\n").replace(/\\r/g, "\r");
|
|
99
|
+
const trimmedStart = normalizedText.trimStart();
|
|
100
|
+
if (!trimmedStart) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const firstLine = trimmedStart.split("\n", 1)[0];
|
|
104
|
+
// Text starting with `---` is considered markdown (horizontal rule or front matter)
|
|
105
|
+
if (firstLine.startsWith("--")) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
// Front matter: starts with --- and another --- appears within a few lines.
|
|
109
|
+
if (/^---\s*$/.test(firstLine)) {
|
|
110
|
+
const lines = trimmedStart.split("\n").slice(1, 20);
|
|
111
|
+
if (lines.some((line) => /^---\s*$/.test(line))) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
// Heuristic: if a front-matter-like start is followed by markdown markers,
|
|
115
|
+
// treat it as markdown even without a closing ---.
|
|
116
|
+
if (lines.some((line) => /^(#{1,6}\s|>\s|[-*]\s|\d+\.\s|\|)/.test(line.trimStart()))) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Common markdown markers.
|
|
121
|
+
if (/^(#{1,6}\s|>\s|[-*]\s|\d+\.\s|\|)/.test(trimmedStart)) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
// Horizontal rule only (line with ---/***/___).
|
|
125
|
+
return /^(?:---|\*\*\*|___)\s*$/.test(firstLine);
|
|
126
|
+
};
|
|
127
|
+
let defaultEnableAtFormula = false;
|
|
128
|
+
export const setDefaultEnableAtFormula = (enable) => {
|
|
129
|
+
defaultEnableAtFormula = enable ?? false;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Check if text is a formula
|
|
133
|
+
* @param text
|
|
134
|
+
* @returns
|
|
135
|
+
*/
|
|
136
|
+
export const isAFormula = (text) => {
|
|
137
|
+
const textStr = String(text);
|
|
138
|
+
if (looksLikeMarkdown(textStr)) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
// A formula's expression can never legitimately begin with a second "="
|
|
142
|
+
// right after the leading one — neither Excel nor Google Sheets has a token
|
|
143
|
+
// that starts an expression with "=". So "==", "===", "=== heading ===" and
|
|
144
|
+
// similar are decorative/label text, not a (broken) formula. Treat them as
|
|
145
|
+
// plain text instead of routing them through the calculator.
|
|
146
|
+
if (textStr.startsWith("==")) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
return !!textStr.startsWith("=") || isAlternateFormula(textStr);
|
|
150
|
+
};
|
|
151
|
+
/* Quoted string literal, e.g. `"North Region"` (with `""` escapes). */
|
|
152
|
+
const STRING_LITERAL_ONLY = /^"(?:[^"]|"")*"$/;
|
|
153
|
+
/* Numeric literal, e.g. `42`, `-1.5`, `.5`, `1e3`, `12%`. */
|
|
154
|
+
const NUMERIC_LITERAL_ONLY = /^[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?%?$/;
|
|
155
|
+
/* Boolean literal. */
|
|
156
|
+
const BOOLEAN_LITERAL_ONLY = /^(?:TRUE|FALSE)$/i;
|
|
157
|
+
/* Formula operators that can only appear in an expression that needs
|
|
158
|
+
* the calculator (scanned outside quoted segments). */
|
|
159
|
+
const FORMULA_OPERATOR = /[+\-*/^&<>=]/;
|
|
160
|
+
/**
|
|
161
|
+
* Check if text is a formula-shaped expression stored WITHOUT the
|
|
162
|
+
* leading "=". OOXML defined names (`<definedName>` in workbook.xml)
|
|
163
|
+
* store their expressions bare — `OFFSET(Sheet1!$A$1,0,0,10)` rather
|
|
164
|
+
* than `=OFFSET(...)` — so `isAFormula` can't classify them.
|
|
165
|
+
*
|
|
166
|
+
* Returns false for anything that already resolves as a static value
|
|
167
|
+
* or plain reference today: quoted string / numeric / boolean
|
|
168
|
+
* literals, single-area range references (including external-workbook
|
|
169
|
+
* references like `'[1]Revenue'!$A$17`), and broken `#REF!`
|
|
170
|
+
* expressions. Returns true only for expressions that need the
|
|
171
|
+
* calculator: function calls and operator expressions.
|
|
172
|
+
* @param text
|
|
173
|
+
* @returns
|
|
174
|
+
*/
|
|
175
|
+
export const isBareFormulaExpression = (text) => {
|
|
176
|
+
if (typeof text !== "string") {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
const trimmed = text.trim();
|
|
180
|
+
if (!trimmed || trimmed.startsWith("=")) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
if (trimmed.includes("#REF!")) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
if (STRING_LITERAL_ONLY.test(trimmed) ||
|
|
187
|
+
NUMERIC_LITERAL_ONLY.test(trimmed) ||
|
|
188
|
+
BOOLEAN_LITERAL_ONLY.test(trimmed)) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
if (checkIfStringIsReference(trimmed)) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
// Function call or parenthesized sub-expression.
|
|
195
|
+
if (trimmed.includes("(")) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
// Operator expression like `Sheet1!$A$1*2`. Strip string literals
|
|
199
|
+
// and quoted sheet names first so `'My-Sheet'!$A$1` isn't misread
|
|
200
|
+
// as subtraction.
|
|
201
|
+
const scannable = trimmed
|
|
202
|
+
.replace(/"(?:[^"]|"")*"/g, "")
|
|
203
|
+
.replace(/'[^']*'/g, "");
|
|
204
|
+
return FORMULA_OPERATOR.test(scannable);
|
|
205
|
+
};
|
|
206
|
+
// Pre-compiled `\p{Sc}` (Unicode currency-symbol category) check. Used to
|
|
207
|
+
// distinguish currency input like `-$100` / `+€50` from formula-prefixed
|
|
208
|
+
// input like `-A1` / `+SUM(A1:B2)`. Wrapped in try/catch because some
|
|
209
|
+
// older JS engines don't support Unicode property escapes.
|
|
210
|
+
const CURRENCY_SYMBOL_START = (() => {
|
|
211
|
+
try {
|
|
212
|
+
return new RegExp("^\\p{Sc}", "u");
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return /^[£$€¥₹₽₩₪₫₴₸₺₼₾₿]/;
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
218
|
+
// Check if its alternate formula
|
|
219
|
+
// ie the text starts with +
|
|
220
|
+
export const isAlternateFormula = (text) => {
|
|
221
|
+
// @ can be treated as formula in Excel (even if invalid), but is disabled by default here
|
|
222
|
+
if (text.startsWith("@"))
|
|
223
|
+
return defaultEnableAtFormula;
|
|
224
|
+
if (!text.startsWith("+") && !text.startsWith("-"))
|
|
225
|
+
return false;
|
|
226
|
+
// Remove the leading + and check if what remains is just a number
|
|
227
|
+
const afterSign = text.slice(1).trim();
|
|
228
|
+
// If it's empty or just a number literal, it's not a formula
|
|
229
|
+
// Also check with common thousands separators removed (comma and period)
|
|
230
|
+
// to handle locale-formatted numbers like "1,234" or "1.234"
|
|
231
|
+
if (!afterSign || !isNaN(Number(afterSign))) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
// Excel parity: a leading sign followed by a currency symbol is the start
|
|
235
|
+
// of a (possibly in-progress) currency negative / positive — `-$100`,
|
|
236
|
+
// `+€50`, `-£1,234.56`. Excel treats these as currency, not formulas,
|
|
237
|
+
// even mid-type (the bare `-$` shows as text until digits are added).
|
|
238
|
+
if (CURRENCY_SYMBOL_START.test(afterSign)) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
// Check for numbers with thousands separators (e.g., "1,234" or "1.234,56")
|
|
242
|
+
// Strip commas and periods that look like thousands separators
|
|
243
|
+
const withoutThousandsSeparators = afterSign.replace(/[,.]/g, "");
|
|
244
|
+
if (/^\d+$/.test(withoutThousandsSeparators)) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
// If there is whitespace with no letters, treat it as text unless it uses
|
|
248
|
+
// non-hyphen operators (phone numbers like "+1 224-535-1764").
|
|
249
|
+
const hasLetters = /[A-Za-z]/.test(afterSign);
|
|
250
|
+
if (/\s/.test(afterSign) && !hasLetters) {
|
|
251
|
+
return /[+*/^=<>]/.test(afterSign);
|
|
252
|
+
}
|
|
253
|
+
// Otherwise, it's a formula like +A1, +SUM(A1:B2), +1-2, etc.
|
|
254
|
+
return true;
|
|
255
|
+
};
|
|
256
|
+
// Check if its a valid formula
|
|
257
|
+
export const isValidFormula = (text) => {
|
|
258
|
+
const str = String(text);
|
|
259
|
+
return str[0] === "=" && str.length > 1;
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Check if a key is an Arrow key
|
|
263
|
+
* @param code
|
|
264
|
+
* @returns
|
|
265
|
+
*/
|
|
266
|
+
export const isAnArrowKey = (code) => code.startsWith("Arrow");
|
|
267
|
+
/**
|
|
268
|
+
* Iterate over all cells in a bound
|
|
269
|
+
* @param bounds
|
|
270
|
+
* @param callback
|
|
271
|
+
*/
|
|
272
|
+
export const iterateCells = function* (top, right, bottom, left) {
|
|
273
|
+
for (let rowIndex = top; rowIndex <= bottom; rowIndex++) {
|
|
274
|
+
const rightBound = typeof right === "function" ? right(rowIndex) : right;
|
|
275
|
+
for (let columnIndex = left; columnIndex <= rightBound; columnIndex++) {
|
|
276
|
+
yield [rowIndex, columnIndex];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
export function* combineIterators(...generators) {
|
|
281
|
+
for (const generator of generators) {
|
|
282
|
+
if (generator)
|
|
283
|
+
yield* generator;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
export const iterateCellsInRange = (range) => {
|
|
287
|
+
return iterateCells(range.startRowIndex, range.endColumnIndex, range.endRowIndex, range.startColumnIndex);
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Iterate all cells in multiple selections
|
|
291
|
+
* @param selections
|
|
292
|
+
* @returns
|
|
293
|
+
*/
|
|
294
|
+
export const iterateSelections = function* (selections) {
|
|
295
|
+
for (const selection of selections) {
|
|
296
|
+
yield iterateCellsInRange(selection.range);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from "./numbers";
|
|
2
|
+
export * from "./uuid";
|
|
3
|
+
export * from "./typeguards";
|
|
4
|
+
export * from "./string";
|
|
5
|
+
export * from "./formula";
|
|
6
|
+
export * from "./color";
|
|
7
|
+
export * from "./dom";
|
|
8
|
+
export * from "./locale";
|
|
9
|
+
export * from "./date";
|
|
10
|
+
export * from "./log";
|
|
11
|
+
export * from "./array";
|
|
12
|
+
export * from "./formatter";
|
|
13
|
+
export * from "./memoize";
|
|
14
|
+
export * from "./cell-data-helpers";
|
|
15
|
+
export * from "./selection";
|
|
16
|
+
export * from "./colors";
|
|
17
|
+
export * from "./formula-refs";
|
|
18
|
+
export * from "./sort";
|
|
19
|
+
export * from "./table-styles";
|
|
20
|
+
export * from "./conditional-format";
|
|
21
|
+
export * from "./data-validation";
|
|
22
|
+
export * from "./content-hash";
|
|
23
|
+
export * from "./shared-string-canonical";
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export * from "./numbers";
|
|
2
|
+
export * from "./uuid";
|
|
3
|
+
export * from "./typeguards";
|
|
4
|
+
export * from "./string";
|
|
5
|
+
export * from "./formula";
|
|
6
|
+
export * from "./color";
|
|
7
|
+
export * from "./dom";
|
|
8
|
+
export * from "./locale";
|
|
9
|
+
export * from "./date";
|
|
10
|
+
export * from "./log";
|
|
11
|
+
export * from "./array";
|
|
12
|
+
export * from "./formatter";
|
|
13
|
+
export * from "./memoize";
|
|
14
|
+
export * from "./cell-data-helpers";
|
|
15
|
+
export * from "./selection";
|
|
16
|
+
export * from "./colors";
|
|
17
|
+
export * from "./formula-refs";
|
|
18
|
+
export * from "./sort";
|
|
19
|
+
export * from "./table-styles";
|
|
20
|
+
export * from "./conditional-format";
|
|
21
|
+
export * from "./data-validation";
|
|
22
|
+
export * from "./content-hash";
|
|
23
|
+
export * from "./shared-string-canonical";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const getCurrentLocale: () => string;
|
|
2
|
+
export type DatePartType = "month" | "day" | "year";
|
|
3
|
+
/**
|
|
4
|
+
* PARSER metadata only: relative day/month order for a locale, with the
|
|
5
|
+
* year deliberately moved last so the date-parser's regex can use fixed
|
|
6
|
+
* capture-group positions. This ordering is WRONG for display in
|
|
7
|
+
* year-first locales (ja-JP, hu-HU, sv-SE, …) — formatting helpers must
|
|
8
|
+
* use the `formatToParts`-driven builders below instead.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getLocaleDatePartsNotMemoized: (locale: string) => [DatePartType, string, string][];
|
|
11
|
+
export declare const getLocaleDateParts: (locale: string) => [DatePartType, string, string][];
|
|
12
|
+
/**
|
|
13
|
+
* Default numeric (short) date pattern for a locale, preserving the
|
|
14
|
+
* locale's field order, separators, literal text and zero-padding as
|
|
15
|
+
* reported by `Intl.DateTimeFormat(...).formatToParts()` — e.g.
|
|
16
|
+
* de-DE → `d.m.yyyy`, hu-HU → `yyyy. mm. dd.`, en-CA → `yyyy-mm-dd`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const getDefaultDateFormat: (locale?: string) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Default time pattern for a locale, honoring its 12/24-hour convention,
|
|
21
|
+
* separators and hour padding — e.g. en-US → `h:mm:ss AM/PM`,
|
|
22
|
+
* de-DE → `hh:mm:ss`, fi-FI → `h.mm.ss`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const getDefaultTimeFormat: (locale?: string, precision?: "minute" | "second") => string;
|
|
25
|
+
export declare const getDefaultDateTimeFormat: (locale?: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Long (full) date pattern for a locale, following the locale's own
|
|
28
|
+
* field placement and literal text — e.g. de-DE →
|
|
29
|
+
* `[$-de-DE]dddd, d. mmmm yyyy`, ja-JP → `[$-ja-JP]yyyy"年"m"月"d"日"dddd`.
|
|
30
|
+
* Localized weekday/month names are best-effort: they render through the
|
|
31
|
+
* spreadsheet formatter's own locale data via the `[$-locale]` tag.
|
|
32
|
+
*/
|
|
33
|
+
export declare const getLongDateFormat: (locale?: string) => string;
|
|
34
|
+
//# sourceMappingURL=locale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../locale.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,cAU5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,QAAQ,MAAM,qCAkC3D,CAAC;AAEF,eAAO,MAAM,kBAAkB,sDAAyC,CAAC;AAqFzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAQ,MAA2B,WAClC,CAAC;AAuCvC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAQ,MAA2B,EACnC,YAAW,QAAQ,GAAG,QAAmB,WACS,CAAC;AAErD,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,WAEvD,CAAC;AA2CF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAQ,MAA2B,WAClC,CAAC"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { memoize } from "./memoize";
|
|
2
|
+
let defaultLocale;
|
|
3
|
+
export const getCurrentLocale = () => {
|
|
4
|
+
if (defaultLocale) {
|
|
5
|
+
return defaultLocale;
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
defaultLocale = Intl.DateTimeFormat().resolvedOptions().locale;
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
defaultLocale = "en-US";
|
|
12
|
+
}
|
|
13
|
+
return defaultLocale;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* PARSER metadata only: relative day/month order for a locale, with the
|
|
17
|
+
* year deliberately moved last so the date-parser's regex can use fixed
|
|
18
|
+
* capture-group positions. This ordering is WRONG for display in
|
|
19
|
+
* year-first locales (ja-JP, hu-HU, sv-SE, …) — formatting helpers must
|
|
20
|
+
* use the `formatToParts`-driven builders below instead.
|
|
21
|
+
*/
|
|
22
|
+
export const getLocaleDatePartsNotMemoized = (locale) => {
|
|
23
|
+
let parts = [];
|
|
24
|
+
try {
|
|
25
|
+
const formatObj = new Intl.DateTimeFormat(locale).formatToParts(new Date());
|
|
26
|
+
for (const part of formatObj) {
|
|
27
|
+
if (part.type === "day") {
|
|
28
|
+
parts.push(["day", "d", "dd"]);
|
|
29
|
+
}
|
|
30
|
+
if (part.type === "month") {
|
|
31
|
+
parts.push(["month", "m", "mm"]);
|
|
32
|
+
}
|
|
33
|
+
if (part.type === "year") {
|
|
34
|
+
parts.push(["year", "yy", "yyyy"]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Always move year to last to prevent
|
|
38
|
+
// errors in Regex (duplicate capture group)
|
|
39
|
+
parts.sort((_, [typeB]) => {
|
|
40
|
+
if (typeB === "year") {
|
|
41
|
+
return -1;
|
|
42
|
+
}
|
|
43
|
+
return 1;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
// en-US
|
|
48
|
+
parts = [
|
|
49
|
+
["month", "m", "mm"],
|
|
50
|
+
["day", "d", "dd"],
|
|
51
|
+
["year", "yy", "yyyy"],
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
return parts;
|
|
55
|
+
};
|
|
56
|
+
export const getLocaleDateParts = memoize(getLocaleDatePartsNotMemoized);
|
|
57
|
+
/**
|
|
58
|
+
* Fixed sample instant used to discover a locale's date/time pattern via
|
|
59
|
+
* `formatToParts`. Every numeric field is single-digit (5 April 2008,
|
|
60
|
+
* 05:09:07 UTC) so locale padding is observable: a locale that renders
|
|
61
|
+
* "05" for the day pads days, one that renders "5" does not.
|
|
62
|
+
*/
|
|
63
|
+
const FORMAT_SAMPLE_DATE = new Date(Date.UTC(2008, 3, 5, 5, 9, 7));
|
|
64
|
+
/**
|
|
65
|
+
* Literal characters that spreadsheet number-format syntax accepts
|
|
66
|
+
* unquoted inside a date/time section. Anything else (words such as
|
|
67
|
+
* "г.", CJK markers such as 年/月/日, bidi controls, commas — which
|
|
68
|
+
* numfmt/Excel read as the thousands/scaling operator, e.g. hu-HU's
|
|
69
|
+
* `.,` literal — …) must be wrapped in double quotes.
|
|
70
|
+
*/
|
|
71
|
+
const SAFE_PATTERN_LITERAL = /^[\s./:-]*$/;
|
|
72
|
+
const escapePatternLiteral = (value) => {
|
|
73
|
+
if (SAFE_PATTERN_LITERAL.test(value)) {
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
// Number-format strings cannot represent an embedded double quote —
|
|
77
|
+
// no locale literal contains one, so dropping it is safe.
|
|
78
|
+
return `"${value.replace(/"/g, "")}"`;
|
|
79
|
+
};
|
|
80
|
+
const numericFieldToken = (short, long, partValue) => (partValue.length === 2 ? long : short);
|
|
81
|
+
const dateFieldToken = (part) => {
|
|
82
|
+
switch (part.type) {
|
|
83
|
+
case "day":
|
|
84
|
+
return numericFieldToken("d", "dd", part.value);
|
|
85
|
+
case "month":
|
|
86
|
+
return numericFieldToken("m", "mm", part.value);
|
|
87
|
+
case "year":
|
|
88
|
+
return part.value.length === 2 ? "yy" : "yyyy";
|
|
89
|
+
case "literal":
|
|
90
|
+
return escapePatternLiteral(part.value);
|
|
91
|
+
default:
|
|
92
|
+
// era and other exotic fields have no spreadsheet token — skip.
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const buildPatternFromParts = (parts, toToken) => {
|
|
97
|
+
let pattern = "";
|
|
98
|
+
for (const part of parts) {
|
|
99
|
+
const token = toToken(part);
|
|
100
|
+
if (token !== undefined) {
|
|
101
|
+
pattern += token;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// A locale's pattern may end (or begin) with a literal that belongs to
|
|
105
|
+
// trailing fields we skipped (e.g. an era) — trim stray whitespace.
|
|
106
|
+
return pattern.trim();
|
|
107
|
+
};
|
|
108
|
+
const getDefaultDateFormatMemoized = memoize((locale) => {
|
|
109
|
+
try {
|
|
110
|
+
const parts = new Intl.DateTimeFormat(locale, {
|
|
111
|
+
calendar: "gregory",
|
|
112
|
+
numberingSystem: "latn",
|
|
113
|
+
year: "numeric",
|
|
114
|
+
month: "numeric",
|
|
115
|
+
day: "numeric",
|
|
116
|
+
timeZone: "UTC",
|
|
117
|
+
}).formatToParts(FORMAT_SAMPLE_DATE);
|
|
118
|
+
const pattern = buildPatternFromParts(parts, dateFieldToken);
|
|
119
|
+
return pattern || "m/d/yyyy";
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
return "m/d/yyyy";
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Default numeric (short) date pattern for a locale, preserving the
|
|
127
|
+
* locale's field order, separators, literal text and zero-padding as
|
|
128
|
+
* reported by `Intl.DateTimeFormat(...).formatToParts()` — e.g.
|
|
129
|
+
* de-DE → `d.m.yyyy`, hu-HU → `yyyy. mm. dd.`, en-CA → `yyyy-mm-dd`.
|
|
130
|
+
*/
|
|
131
|
+
export const getDefaultDateFormat = (locale = getCurrentLocale()) => getDefaultDateFormatMemoized(locale);
|
|
132
|
+
const getDefaultTimeFormatMemoized = memoize((locale, precision) => {
|
|
133
|
+
try {
|
|
134
|
+
const parts = new Intl.DateTimeFormat(locale, {
|
|
135
|
+
numberingSystem: "latn",
|
|
136
|
+
hour: "numeric",
|
|
137
|
+
minute: "numeric",
|
|
138
|
+
...(precision === "second" ? { second: "numeric" } : {}),
|
|
139
|
+
timeZone: "UTC",
|
|
140
|
+
}).formatToParts(FORMAT_SAMPLE_DATE);
|
|
141
|
+
const pattern = buildPatternFromParts(parts, (part) => {
|
|
142
|
+
switch (part.type) {
|
|
143
|
+
case "hour":
|
|
144
|
+
return numericFieldToken("h", "hh", part.value);
|
|
145
|
+
case "minute":
|
|
146
|
+
return "mm";
|
|
147
|
+
case "second":
|
|
148
|
+
return "ss";
|
|
149
|
+
case "dayPeriod":
|
|
150
|
+
// Spreadsheet syntax only has the English AM/PM token; its
|
|
151
|
+
// presence is what switches the hour field to 12-hour mode.
|
|
152
|
+
return "AM/PM";
|
|
153
|
+
case "literal":
|
|
154
|
+
return escapePatternLiteral(part.value);
|
|
155
|
+
default:
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
const fallback = precision === "second" ? "h:mm:ss AM/PM" : "h:mm AM/PM";
|
|
160
|
+
return pattern || fallback;
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
return precision === "second" ? "h:mm:ss AM/PM" : "h:mm AM/PM";
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
/**
|
|
167
|
+
* Default time pattern for a locale, honoring its 12/24-hour convention,
|
|
168
|
+
* separators and hour padding — e.g. en-US → `h:mm:ss AM/PM`,
|
|
169
|
+
* de-DE → `hh:mm:ss`, fi-FI → `h.mm.ss`.
|
|
170
|
+
*/
|
|
171
|
+
export const getDefaultTimeFormat = (locale = getCurrentLocale(), precision = "second") => getDefaultTimeFormatMemoized(locale, precision);
|
|
172
|
+
export const getDefaultDateTimeFormat = (locale) => {
|
|
173
|
+
return getDefaultDateFormat(locale) + " " + getDefaultTimeFormat(locale);
|
|
174
|
+
};
|
|
175
|
+
const getLongDateFormatMemoized = memoize((locale) => {
|
|
176
|
+
try {
|
|
177
|
+
const parts = new Intl.DateTimeFormat(locale, {
|
|
178
|
+
calendar: "gregory",
|
|
179
|
+
numberingSystem: "latn",
|
|
180
|
+
weekday: "long",
|
|
181
|
+
year: "numeric",
|
|
182
|
+
month: "long",
|
|
183
|
+
day: "numeric",
|
|
184
|
+
timeZone: "UTC",
|
|
185
|
+
}).formatToParts(FORMAT_SAMPLE_DATE);
|
|
186
|
+
const pattern = buildPatternFromParts(parts, (part) => {
|
|
187
|
+
switch (part.type) {
|
|
188
|
+
case "weekday":
|
|
189
|
+
return "dddd";
|
|
190
|
+
case "month":
|
|
191
|
+
// CJK locales keep the month numeric even in long dates
|
|
192
|
+
// ("9月"): Intl reports the digit with 月/월 as a literal, and
|
|
193
|
+
// the formatter's own `mmmm` would re-append the marker.
|
|
194
|
+
return /^\d+$/.test(part.value)
|
|
195
|
+
? numericFieldToken("m", "mm", part.value)
|
|
196
|
+
: "mmmm";
|
|
197
|
+
case "day":
|
|
198
|
+
return numericFieldToken("d", "dd", part.value);
|
|
199
|
+
case "year":
|
|
200
|
+
return part.value.length === 2 ? "yy" : "yyyy";
|
|
201
|
+
case "literal":
|
|
202
|
+
return escapePatternLiteral(part.value);
|
|
203
|
+
default:
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
if (!pattern) {
|
|
208
|
+
return `[$-${locale}]dddd, mmmm d, yyyy`;
|
|
209
|
+
}
|
|
210
|
+
return `[$-${locale}]${pattern}`;
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
return `[$-${locale}]dddd, mmmm d, yyyy`;
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
/**
|
|
217
|
+
* Long (full) date pattern for a locale, following the locale's own
|
|
218
|
+
* field placement and literal text — e.g. de-DE →
|
|
219
|
+
* `[$-de-DE]dddd, d. mmmm yyyy`, ja-JP → `[$-ja-JP]yyyy"年"m"月"d"日"dddd`.
|
|
220
|
+
* Localized weekday/month names are best-effort: they render through the
|
|
221
|
+
* spreadsheet formatter's own locale data via the `[$-locale]` tag.
|
|
222
|
+
*/
|
|
223
|
+
export const getLongDateFormat = (locale = getCurrentLocale()) => getLongDateFormatMemoized(locale);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../log.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,GAAG,EAAE,iBAC6B,CAAC;AAChE,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,GAAG,EAAE,iBAC6B,CAAC;AAClE,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,GAAG,EAAE,iBAC6B,CAAC"}
|
package/dist/esm/log.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export const log = (...args) => process.env.NODE_ENV !== "production" && console.log(...args);
|
|
2
|
+
export const debug = (...args) => process.env.NODE_ENV !== "production" && console.debug(...args);
|
|
3
|
+
export const error = (...args) => process.env.NODE_ENV !== "production" && console.error(...args);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const memoize: <T extends unknown[], K>(fn: (...args: T) => K) => (...args: T) => K;
|
|
2
|
+
/**
|
|
3
|
+
* Mint a stable cellXfs key ("sid") for a CellFormat. The key is
|
|
4
|
+
* `contentHash` (FNV-1a-64 → 8-char base62) over a delimiter-separated
|
|
5
|
+
* canonical serialization of the format's defined properties — the
|
|
6
|
+
* previous 31-bit rolling int hash silently collided two different
|
|
7
|
+
* formats onto one registry key (first-writer wins, so e.g. a red
|
|
8
|
+
* format could hijack a blue one on import).
|
|
9
|
+
*
|
|
10
|
+
* Sids are minted at import/edit time and persisted in the doc's
|
|
11
|
+
* cellXfs map together with the cell references that carry them —
|
|
12
|
+
* readback resolves a stored sid against the stored map, never by
|
|
13
|
+
* re-hashing. Changing this algorithm therefore only affects newly
|
|
14
|
+
* minted keys; existing docs keep resolving their old sids.
|
|
15
|
+
*/
|
|
16
|
+
export declare const getCellXfsKey: (userObj: any | null | undefined) => string;
|
|
17
|
+
export declare const definedProps: <T extends Record<string, any> | undefined | null>(obj: T) => Partial<NonNullable<T>> | T;
|
|
18
|
+
//# sourceMappingURL=memoize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoize.d.ts","sourceRoot":"","sources":["../../memoize.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,MAE3D,GAAG,MAAM,CAAC,MASnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,GAAG,GAAG,IAAI,GAAG,SAAS,KAAG,MA4D/D,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,IAAI,EAC3E,KAAK,CAAC,KACL,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAU5B,CAAC"}
|