@rowsncolumns/utils 9.2.44 → 9.4.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.
Files changed (51) hide show
  1. package/dist/cjs/formula-locale/formula-locale-data.generated.d.ts +44 -0
  2. package/dist/cjs/formula-locale/formula-locale-data.generated.d.ts.map +1 -0
  3. package/dist/cjs/formula-locale/formula-locale-data.generated.js +5567 -0
  4. package/dist/cjs/formula-locale.d.ts +159 -0
  5. package/dist/cjs/formula-locale.d.ts.map +1 -0
  6. package/dist/cjs/formula-locale.js +804 -0
  7. package/dist/cjs/index.d.ts +4 -0
  8. package/dist/cjs/index.d.ts.map +1 -1
  9. package/dist/cjs/index.js +4 -0
  10. package/dist/cjs/sparkline-groups.d.ts +102 -0
  11. package/dist/cjs/sparkline-groups.d.ts.map +1 -0
  12. package/dist/cjs/sparkline-groups.js +452 -0
  13. package/dist/cjs/string.d.ts +15 -0
  14. package/dist/cjs/string.d.ts.map +1 -1
  15. package/dist/cjs/string.js +46 -1
  16. package/dist/cjs/table-names.d.ts +55 -0
  17. package/dist/cjs/table-names.d.ts.map +1 -0
  18. package/dist/cjs/table-names.js +189 -0
  19. package/dist/cjs/table-styles.d.ts +9 -0
  20. package/dist/cjs/table-styles.d.ts.map +1 -1
  21. package/dist/cjs/table-styles.js +53 -1
  22. package/dist/cjs/table-totals.d.ts +31 -0
  23. package/dist/cjs/table-totals.d.ts.map +1 -0
  24. package/dist/cjs/table-totals.js +84 -0
  25. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  26. package/dist/esm/formula-locale/formula-locale-data.generated.d.ts +44 -0
  27. package/dist/esm/formula-locale/formula-locale-data.generated.d.ts.map +1 -0
  28. package/dist/esm/formula-locale/formula-locale-data.generated.js +5564 -0
  29. package/dist/esm/formula-locale.d.ts +159 -0
  30. package/dist/esm/formula-locale.d.ts.map +1 -0
  31. package/dist/esm/formula-locale.js +0 -0
  32. package/dist/esm/index.d.ts +4 -0
  33. package/dist/esm/index.d.ts.map +1 -1
  34. package/dist/esm/index.js +4 -0
  35. package/dist/esm/sparkline-groups.d.ts +102 -0
  36. package/dist/esm/sparkline-groups.d.ts.map +1 -0
  37. package/dist/esm/sparkline-groups.js +387 -0
  38. package/dist/esm/string.d.ts +15 -0
  39. package/dist/esm/string.d.ts.map +1 -1
  40. package/dist/esm/string.js +43 -0
  41. package/dist/esm/table-names.d.ts +55 -0
  42. package/dist/esm/table-names.d.ts.map +1 -0
  43. package/dist/esm/table-names.js +129 -0
  44. package/dist/esm/table-styles.d.ts +9 -0
  45. package/dist/esm/table-styles.d.ts.map +1 -1
  46. package/dist/esm/table-styles.js +34 -1
  47. package/dist/esm/table-totals.d.ts +31 -0
  48. package/dist/esm/table-totals.d.ts.map +1 -0
  49. package/dist/esm/table-totals.js +68 -0
  50. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  51. package/package.json +5 -3
@@ -24,4 +24,8 @@ export * from "./content-hash";
24
24
  export * from "./shared-string-canonical";
25
25
  export * from "./keyboard";
26
26
  export * from "./sheet-span";
27
+ export * from "./formula-locale";
28
+ export * from "./table-names";
29
+ export * from "./table-totals";
30
+ export * from "./sparkline-groups";
27
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,uBAAuB,CAAC;AACtC,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;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
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,uBAAuB,CAAC;AACtC,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;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -27,3 +27,7 @@ tslib_1.__exportStar(require("./content-hash"), exports);
27
27
  tslib_1.__exportStar(require("./shared-string-canonical"), exports);
28
28
  tslib_1.__exportStar(require("./keyboard"), exports);
29
29
  tslib_1.__exportStar(require("./sheet-span"), exports);
30
+ tslib_1.__exportStar(require("./formula-locale"), exports);
31
+ tslib_1.__exportStar(require("./table-names"), exports);
32
+ tslib_1.__exportStar(require("./table-totals"), exports);
33
+ tslib_1.__exportStar(require("./sparkline-groups"), exports);
@@ -0,0 +1,102 @@
1
+ import type { CellInterface, GridRange, SparkLineResultOptions } from "@rowsncolumns/common-types";
2
+ /**
3
+ * Excel sparkline groups (Insert → Sparklines → Line / Column / Win-Loss) on top of the
4
+ * `=SPARKLINE(dataRange, {options})` cell formula — the shape the XLSX importers of BOTH engines
5
+ * produce for an `<x14:sparklineGroup>` (one formula per `<x14:sparkline>`, the group's attributes
6
+ * as the option literal) and the shape the exporters fold back into a group (cells sharing one option
7
+ * fingerprint share one `<x14:sparklineGroup>`). A group therefore has no separate document object:
8
+ * it is the connected run of location cells whose SPARKLINE formulas carry identical options. That
9
+ * keeps live recalc, reference shifting on insert/delete and the round-trip as ordinary formula
10
+ * behavior on both engines.
11
+ */
12
+ export type SparklineGroupType = "line" | "column" | "winloss";
13
+ /** One sparkline of a group: the cell it paints in and the data range it charts. */
14
+ export type SparklineGroupMember = {
15
+ cell: CellInterface;
16
+ /** As written in the formula (optionally sheet-qualified, e.g. `Data!A2:E2`). */
17
+ dataRange: string;
18
+ };
19
+ /** The group options (everything but `charttype`, which is the group's `type`). */
20
+ export type SparklineGroupOptions = Omit<SparkLineResultOptions, "charttype">;
21
+ export type SparklineGroup = {
22
+ sheetId: number;
23
+ type: SparklineGroupType;
24
+ options: SparklineGroupOptions;
25
+ /** In location order (top → bottom, then left → right). */
26
+ members: SparklineGroupMember[];
27
+ };
28
+ export type ParsedSparklineFormula = {
29
+ dataRange: string;
30
+ options: SparkLineResultOptions;
31
+ };
32
+ export declare const isSparklineFormula: (formula: unknown) => formula is string;
33
+ /**
34
+ * `=SPARKLINE(A1:E1,{"charttype","column","color","#FF0000"})` → its data range and options with the
35
+ * keys canonicalized to `SparkLineResultOptions` (both option-literal shapes and the legacy
36
+ * `highpoint`/… spellings are accepted). `null` when the formula is not a SPARKLINE call.
37
+ */
38
+ export declare const parseSparklineFormula: (formula: string) => ParsedSparklineFormula | null;
39
+ /**
40
+ * The inverse of {@link parseSparklineFormula}: `=SPARKLINE(range)` when no option is set, else
41
+ * `=SPARKLINE(range,{"k",v,…})` in the importers' emission order. Unset, `false` and `line`
42
+ * (the default type) options are omitted.
43
+ */
44
+ export declare const buildSparklineFormula: (dataRange: string, options?: SparkLineResultOptions) => string;
45
+ export declare const sparklineTypeFromOptions: (options: SparkLineResultOptions | undefined) => SparklineGroupType;
46
+ /** Group identity: two SPARKLINE cells belong to one group when this string matches. */
47
+ export declare const sparklineOptionsFingerprint: (options: SparkLineResultOptions) => string;
48
+ export type ResolveSparklineGroupArgs = {
49
+ sheetId: number;
50
+ cell: CellInterface;
51
+ /** The user-entered formula of a cell (`undefined` for a non-formula cell). */
52
+ getFormula: (sheetId: number, rowIndex: number, columnIndex: number) => string | undefined;
53
+ /** Upper bound on the cells walked (a runaway sheet-wide fill would freeze the UI). */
54
+ maxCells?: number;
55
+ };
56
+ /**
57
+ * The sparkline group containing `cell`: the 4-connected run of SPARKLINE cells around it whose
58
+ * options match the cell's. `undefined` when the cell holds no SPARKLINE formula.
59
+ */
60
+ export declare const resolveSparklineGroup: ({ sheetId, cell, getFormula, maxCells, }: ResolveSparklineGroupArgs) => SparklineGroup | undefined;
61
+ export type ParsedRangeAddress = {
62
+ /** The sheet name as typed (quotes removed), `undefined` for a local reference. */
63
+ sheetName?: string;
64
+ range: GridRange;
65
+ };
66
+ /** `'Q1 Data'!A1:E5` / `Sheet1!A1` / `$A$1:$E$5` → its sheet name and grid range. */
67
+ export declare const parseRangeAddress: (address: string) => ParsedRangeAddress | null;
68
+ /** A grid range → `A1:E5` (a single cell → `A1`), optionally sheet-qualified. */
69
+ export declare const rangeToA1: (range: GridRange, sheetName?: string) => string;
70
+ export type PlanSparklineGroupArgs = {
71
+ /** Excel's "Data Range" (may be sheet-qualified). */
72
+ dataRange: string;
73
+ /** Excel's "Location Range" — a single row or column of cells on the group's sheet. */
74
+ locationRange: string;
75
+ };
76
+ export type SparklineGroupPlan = {
77
+ members: SparklineGroupMember[];
78
+ error?: undefined;
79
+ } | {
80
+ members?: undefined;
81
+ error: string;
82
+ };
83
+ /**
84
+ * Excel's Create Sparklines rule: one sparkline per location cell, each charting one row (or one
85
+ * column) of the data range. A single location cell charts the whole data range; otherwise the data
86
+ * range must span exactly as many rows, or exactly as many columns, as the location has cells.
87
+ */
88
+ export declare const planSparklineGroup: ({ dataRange, locationRange, }: PlanSparklineGroupArgs) => SparklineGroupPlan;
89
+ /**
90
+ * The location Excel's dialog is seeded with for a data selection: the column just right of the
91
+ * data (one sparkline per data row), or the cell right of a single-row selection.
92
+ */
93
+ export declare const defaultSparklineLocation: (data: GridRange) => GridRange;
94
+ /** The bounding range of a group's location cells (its members are a single row or column run). */
95
+ export declare const sparklineGroupLocation: (group: SparklineGroup) => GridRange;
96
+ /**
97
+ * The group's "Data Range" as Excel's Edit Group dialog shows it: the union of the members' ranges
98
+ * when they tile one rectangle by rows or columns; otherwise `undefined` (members chart unrelated
99
+ * ranges — Excel then shows the individual ranges only).
100
+ */
101
+ export declare const sparklineGroupDataRange: (group: SparklineGroup) => string | undefined;
102
+ //# sourceMappingURL=sparkline-groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkline-groups.d.ts","sourceRoot":"","sources":["../../sparkline-groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,452 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sparklineGroupDataRange = exports.sparklineGroupLocation = exports.defaultSparklineLocation = exports.planSparklineGroup = exports.rangeToA1 = exports.parseRangeAddress = exports.resolveSparklineGroup = exports.sparklineOptionsFingerprint = exports.sparklineTypeFromOptions = exports.buildSparklineFormula = exports.parseSparklineFormula = exports.isSparklineFormula = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var selection_1 = require("./selection");
6
+ var string_1 = require("./string");
7
+ /** Lower-cased option key → the `SparkLineResultOptions` key the renderer reads. */
8
+ var OPTION_KEYS = {
9
+ charttype: "charttype",
10
+ color: "color",
11
+ colorhigh: "colorHigh",
12
+ colorlow: "colorLow",
13
+ colorfirst: "colorFirst",
14
+ colorlast: "colorLast",
15
+ colormarkers: "colorMarkers",
16
+ colornegative: "colorNegative",
17
+ emptycells: "emptycells",
18
+ dateaxis: "dateaxis",
19
+ markers: "markers",
20
+ high: "high",
21
+ highpoint: "high",
22
+ low: "low",
23
+ lowpoint: "low",
24
+ first: "first",
25
+ firstpoint: "first",
26
+ last: "last",
27
+ lastpoint: "last",
28
+ negative: "negative",
29
+ negativepoints: "negative",
30
+ axis: "axis",
31
+ rtl: "rtl",
32
+ displayhidden: "displayhidden",
33
+ lineweight: "lineweight",
34
+ max: "max",
35
+ min: "min",
36
+ minaxistype: "minaxistype",
37
+ maxaxistype: "maxaxistype",
38
+ };
39
+ /** Emission order of `buildSparklineFormula` — the XLSX importers' order, so a group written here
40
+ * and a group read from a workbook produce byte-identical formulas. */
41
+ var OPTION_ORDER = [
42
+ "charttype",
43
+ "color",
44
+ "colorHigh",
45
+ "colorLow",
46
+ "colorFirst",
47
+ "colorLast",
48
+ "colorMarkers",
49
+ "colorNegative",
50
+ "emptycells",
51
+ "dateaxis",
52
+ "markers",
53
+ "high",
54
+ "low",
55
+ "first",
56
+ "last",
57
+ "negative",
58
+ "axis",
59
+ "rtl",
60
+ "displayhidden",
61
+ "lineweight",
62
+ "max",
63
+ "min",
64
+ "minaxistype",
65
+ "maxaxistype",
66
+ ];
67
+ var SPARKLINE_HEAD = /^\s*=\s*SPARKLINE\s*\(/i;
68
+ var isSparklineFormula = function (formula) {
69
+ return typeof formula === "string" && SPARKLINE_HEAD.test(formula);
70
+ };
71
+ exports.isSparklineFormula = isSparklineFormula;
72
+ /**
73
+ * Split the argument list of a SPARKLINE call at its top-level commas, honoring quotes, braces and
74
+ * nested parentheses (so `'Q1, Q2'!A1:E1` and `{...}` literals stay whole).
75
+ */
76
+ var splitTopLevel = function (args) {
77
+ var e_1, _a;
78
+ var parts = [];
79
+ var depth = 0;
80
+ var quote = null;
81
+ var current = "";
82
+ try {
83
+ for (var args_1 = tslib_1.__values(args), args_1_1 = args_1.next(); !args_1_1.done; args_1_1 = args_1.next()) {
84
+ var ch = args_1_1.value;
85
+ if (quote) {
86
+ current += ch;
87
+ if (ch === quote)
88
+ quote = null;
89
+ continue;
90
+ }
91
+ if (ch === "'" || ch === '"') {
92
+ quote = ch;
93
+ current += ch;
94
+ continue;
95
+ }
96
+ if (ch === "(" || ch === "{")
97
+ depth++;
98
+ if (ch === ")" || ch === "}")
99
+ depth--;
100
+ if (ch === "," && depth === 0) {
101
+ parts.push(current);
102
+ current = "";
103
+ continue;
104
+ }
105
+ current += ch;
106
+ }
107
+ }
108
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
109
+ finally {
110
+ try {
111
+ if (args_1_1 && !args_1_1.done && (_a = args_1.return)) _a.call(args_1);
112
+ }
113
+ finally { if (e_1) throw e_1.error; }
114
+ }
115
+ parts.push(current);
116
+ return parts;
117
+ };
118
+ /** The tokens of an option literal body (`"k",v,"k2",v2` or `"k",v;"k2",v2`), quotes intact. */
119
+ var tokenizeLiteral = function (body) {
120
+ return splitTopLevel(body.replace(/;/g, ","))
121
+ .map(function (t) { return t.trim(); })
122
+ .filter(function (t) { return t.length > 0; });
123
+ };
124
+ var parseOptionValue = function (raw) {
125
+ if (raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2) {
126
+ return raw.slice(1, -1).replace(/""/g, '"');
127
+ }
128
+ var upper = raw.toUpperCase();
129
+ if (upper === "TRUE")
130
+ return true;
131
+ if (upper === "FALSE")
132
+ return false;
133
+ var n = Number(raw);
134
+ return Number.isFinite(n) ? n : raw;
135
+ };
136
+ /**
137
+ * `=SPARKLINE(A1:E1,{"charttype","column","color","#FF0000"})` → its data range and options with the
138
+ * keys canonicalized to `SparkLineResultOptions` (both option-literal shapes and the legacy
139
+ * `highpoint`/… spellings are accepted). `null` when the formula is not a SPARKLINE call.
140
+ */
141
+ var parseSparklineFormula = function (formula) {
142
+ var _a;
143
+ if (!(0, exports.isSparklineFormula)(formula))
144
+ return null;
145
+ var open = formula.indexOf("(");
146
+ var close = formula.lastIndexOf(")");
147
+ if (open < 0 || close < open)
148
+ return null;
149
+ var _b = tslib_1.__read(splitTopLevel(formula.slice(open + 1, close)), 2), dataArg = _b[0], optionsArg = _b[1];
150
+ var dataRange = (_a = dataArg === null || dataArg === void 0 ? void 0 : dataArg.trim()) !== null && _a !== void 0 ? _a : "";
151
+ if (!dataRange)
152
+ return null;
153
+ var options = {};
154
+ var literal = optionsArg === null || optionsArg === void 0 ? void 0 : optionsArg.trim();
155
+ if (literal && literal.startsWith("{") && literal.endsWith("}")) {
156
+ var tokens = tokenizeLiteral(literal.slice(1, -1));
157
+ for (var i = 0; i + 1 < tokens.length; i += 2) {
158
+ var rawKey = parseOptionValue(tokens[i]);
159
+ var key = OPTION_KEYS[String(rawKey).toLowerCase()];
160
+ if (!key)
161
+ continue;
162
+ options[key] = parseOptionValue(tokens[i + 1]);
163
+ }
164
+ }
165
+ return { dataRange: dataRange, options: options };
166
+ };
167
+ exports.parseSparklineFormula = parseSparklineFormula;
168
+ var quote = function (s) { return "\"".concat(s.replace(/"/g, '""'), "\""); };
169
+ /**
170
+ * The inverse of {@link parseSparklineFormula}: `=SPARKLINE(range)` when no option is set, else
171
+ * `=SPARKLINE(range,{"k",v,…})` in the importers' emission order. Unset, `false` and `line`
172
+ * (the default type) options are omitted.
173
+ */
174
+ var buildSparklineFormula = function (dataRange, options) {
175
+ var e_2, _a;
176
+ if (options === void 0) { options = {}; }
177
+ var pairs = [];
178
+ try {
179
+ for (var OPTION_ORDER_1 = tslib_1.__values(OPTION_ORDER), OPTION_ORDER_1_1 = OPTION_ORDER_1.next(); !OPTION_ORDER_1_1.done; OPTION_ORDER_1_1 = OPTION_ORDER_1.next()) {
180
+ var key = OPTION_ORDER_1_1.value;
181
+ var value = options[key];
182
+ if (value === undefined || value === null || value === false)
183
+ continue;
184
+ if (key === "charttype" && value === "line")
185
+ continue;
186
+ if (typeof value === "boolean") {
187
+ pairs.push(quote(key), "TRUE");
188
+ }
189
+ else if (typeof value === "number") {
190
+ if (!Number.isFinite(value))
191
+ continue;
192
+ pairs.push(quote(key), String(value));
193
+ }
194
+ else {
195
+ pairs.push(quote(key), quote(String(value)));
196
+ }
197
+ }
198
+ }
199
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
200
+ finally {
201
+ try {
202
+ if (OPTION_ORDER_1_1 && !OPTION_ORDER_1_1.done && (_a = OPTION_ORDER_1.return)) _a.call(OPTION_ORDER_1);
203
+ }
204
+ finally { if (e_2) throw e_2.error; }
205
+ }
206
+ return pairs.length
207
+ ? "=SPARKLINE(".concat(dataRange, ",{").concat(pairs.join(","), "})")
208
+ : "=SPARKLINE(".concat(dataRange, ")");
209
+ };
210
+ exports.buildSparklineFormula = buildSparklineFormula;
211
+ var sparklineTypeFromOptions = function (options) {
212
+ return (options === null || options === void 0 ? void 0 : options.charttype) === "column" || (options === null || options === void 0 ? void 0 : options.charttype) === "winloss"
213
+ ? options.charttype
214
+ : "line";
215
+ };
216
+ exports.sparklineTypeFromOptions = sparklineTypeFromOptions;
217
+ /** Group identity: two SPARKLINE cells belong to one group when this string matches. */
218
+ var sparklineOptionsFingerprint = function (options) {
219
+ return OPTION_ORDER.map(function (key) {
220
+ var value = options[key];
221
+ if (value === undefined || value === null || value === false)
222
+ return "";
223
+ if (key === "charttype" && value === "line")
224
+ return "";
225
+ return String(value);
226
+ }).join("|");
227
+ };
228
+ exports.sparklineOptionsFingerprint = sparklineOptionsFingerprint;
229
+ /**
230
+ * The sparkline group containing `cell`: the 4-connected run of SPARKLINE cells around it whose
231
+ * options match the cell's. `undefined` when the cell holds no SPARKLINE formula.
232
+ */
233
+ var resolveSparklineGroup = function (_a) {
234
+ var e_3, _b;
235
+ var sheetId = _a.sheetId, cell = _a.cell, getFormula = _a.getFormula, _c = _a.maxCells, maxCells = _c === void 0 ? 4096 : _c;
236
+ var parse = function (rowIndex, columnIndex) {
237
+ var formula = getFormula(sheetId, rowIndex, columnIndex);
238
+ return formula ? (0, exports.parseSparklineFormula)(formula) : null;
239
+ };
240
+ var seed = parse(cell.rowIndex, cell.columnIndex);
241
+ if (!seed)
242
+ return undefined;
243
+ var fingerprint = (0, exports.sparklineOptionsFingerprint)(seed.options);
244
+ var key = function (r, c) { return "".concat(r, ":").concat(c); };
245
+ var seen = new Set([key(cell.rowIndex, cell.columnIndex)]);
246
+ var members = [
247
+ { cell: { rowIndex: cell.rowIndex, columnIndex: cell.columnIndex }, dataRange: seed.dataRange },
248
+ ];
249
+ var queue = [members[0].cell];
250
+ while (queue.length && members.length < maxCells) {
251
+ var _d = queue.shift(), rowIndex = _d.rowIndex, columnIndex = _d.columnIndex;
252
+ try {
253
+ for (var _e = (e_3 = void 0, tslib_1.__values([
254
+ [rowIndex - 1, columnIndex],
255
+ [rowIndex + 1, columnIndex],
256
+ [rowIndex, columnIndex - 1],
257
+ [rowIndex, columnIndex + 1],
258
+ ])), _f = _e.next(); !_f.done; _f = _e.next()) {
259
+ var _g = tslib_1.__read(_f.value, 2), r = _g[0], c = _g[1];
260
+ if (r < 1 || c < 1 || seen.has(key(r, c)))
261
+ continue;
262
+ seen.add(key(r, c));
263
+ var parsed = parse(r, c);
264
+ if (!parsed || (0, exports.sparklineOptionsFingerprint)(parsed.options) !== fingerprint) {
265
+ continue;
266
+ }
267
+ var member = { cell: { rowIndex: r, columnIndex: c }, dataRange: parsed.dataRange };
268
+ members.push(member);
269
+ queue.push(member.cell);
270
+ }
271
+ }
272
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
273
+ finally {
274
+ try {
275
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
276
+ }
277
+ finally { if (e_3) throw e_3.error; }
278
+ }
279
+ }
280
+ members.sort(function (a, b) { return a.cell.rowIndex - b.cell.rowIndex || a.cell.columnIndex - b.cell.columnIndex; });
281
+ var _h = seed.options, _charttype = _h.charttype, options = tslib_1.__rest(_h, ["charttype"]);
282
+ return { sheetId: sheetId, type: (0, exports.sparklineTypeFromOptions)(seed.options), options: options, members: members };
283
+ };
284
+ exports.resolveSparklineGroup = resolveSparklineGroup;
285
+ var A1_RANGE = /^\$?[A-Za-z]{1,3}\$?\d+(?::\$?[A-Za-z]{1,3}\$?\d+)?$/;
286
+ /** `'Q1 Data'!A1:E5` / `Sheet1!A1` / `$A$1:$E$5` → its sheet name and grid range. */
287
+ var parseRangeAddress = function (address) {
288
+ var trimmed = address.trim();
289
+ if (!trimmed)
290
+ return null;
291
+ var bang = trimmed.lastIndexOf("!");
292
+ var sheetPart = bang >= 0 ? trimmed.slice(0, bang) : undefined;
293
+ var cellPart = bang >= 0 ? trimmed.slice(bang + 1) : trimmed;
294
+ if (!A1_RANGE.test(cellPart))
295
+ return null;
296
+ var selection = (0, selection_1.addressToSelection)(cellPart.replace(/\$/g, ""));
297
+ if (!selection)
298
+ return null;
299
+ var sheetName = sheetPart !== undefined ? String((0, string_1.desanitizeSheetName)(sheetPart)) : undefined;
300
+ return { sheetName: sheetName, range: selection.range };
301
+ };
302
+ exports.parseRangeAddress = parseRangeAddress;
303
+ /** A grid range → `A1:E5` (a single cell → `A1`), optionally sheet-qualified. */
304
+ var rangeToA1 = function (range, sheetName) {
305
+ var from = (0, string_1.cellToAddress)({
306
+ rowIndex: range.startRowIndex,
307
+ columnIndex: range.startColumnIndex,
308
+ });
309
+ var to = (0, string_1.cellToAddress)({
310
+ rowIndex: range.endRowIndex,
311
+ columnIndex: range.endColumnIndex,
312
+ });
313
+ var prefix = sheetName ? "".concat((0, string_1.sanitizeSheetName)(sheetName), "!") : "";
314
+ return "".concat(prefix).concat(from === to ? from : "".concat(from, ":").concat(to));
315
+ };
316
+ exports.rangeToA1 = rangeToA1;
317
+ /**
318
+ * Excel's Create Sparklines rule: one sparkline per location cell, each charting one row (or one
319
+ * column) of the data range. A single location cell charts the whole data range; otherwise the data
320
+ * range must span exactly as many rows, or exactly as many columns, as the location has cells.
321
+ */
322
+ var planSparklineGroup = function (_a) {
323
+ var dataRange = _a.dataRange, locationRange = _a.locationRange;
324
+ var data = (0, exports.parseRangeAddress)(dataRange);
325
+ if (!data)
326
+ return { error: "The data range is not valid." };
327
+ var location = (0, exports.parseRangeAddress)(locationRange);
328
+ if (!location)
329
+ return { error: "The location range is not valid." };
330
+ var loc = location.range;
331
+ var locRows = loc.endRowIndex - loc.startRowIndex + 1;
332
+ var locCols = loc.endColumnIndex - loc.startColumnIndex + 1;
333
+ if (locRows > 1 && locCols > 1) {
334
+ return { error: "The location range must be a single row or column." };
335
+ }
336
+ var cells = [];
337
+ for (var r = loc.startRowIndex; r <= loc.endRowIndex; r++) {
338
+ for (var c = loc.startColumnIndex; c <= loc.endColumnIndex; c++) {
339
+ cells.push({ rowIndex: r, columnIndex: c });
340
+ }
341
+ }
342
+ var d = data.range;
343
+ var dataRows = d.endRowIndex - d.startRowIndex + 1;
344
+ var dataCols = d.endColumnIndex - d.startColumnIndex + 1;
345
+ var qualify = function (range) { return (0, exports.rangeToA1)(range, data.sheetName); };
346
+ if (cells.length === 1) {
347
+ return { members: [{ cell: cells[0], dataRange: qualify(d) }] };
348
+ }
349
+ if (dataRows === cells.length) {
350
+ return {
351
+ members: cells.map(function (cell, i) { return ({
352
+ cell: cell,
353
+ dataRange: qualify({
354
+ startRowIndex: d.startRowIndex + i,
355
+ endRowIndex: d.startRowIndex + i,
356
+ startColumnIndex: d.startColumnIndex,
357
+ endColumnIndex: d.endColumnIndex,
358
+ }),
359
+ }); }),
360
+ };
361
+ }
362
+ if (dataCols === cells.length) {
363
+ return {
364
+ members: cells.map(function (cell, i) { return ({
365
+ cell: cell,
366
+ dataRange: qualify({
367
+ startRowIndex: d.startRowIndex,
368
+ endRowIndex: d.endRowIndex,
369
+ startColumnIndex: d.startColumnIndex + i,
370
+ endColumnIndex: d.startColumnIndex + i,
371
+ }),
372
+ }); }),
373
+ };
374
+ }
375
+ return {
376
+ error: "The data range must have the same number of rows or columns as the location range.",
377
+ };
378
+ };
379
+ exports.planSparklineGroup = planSparklineGroup;
380
+ /**
381
+ * The location Excel's dialog is seeded with for a data selection: the column just right of the
382
+ * data (one sparkline per data row), or the cell right of a single-row selection.
383
+ */
384
+ var defaultSparklineLocation = function (data) {
385
+ var rows = data.endRowIndex - data.startRowIndex + 1;
386
+ var columnIndex = data.endColumnIndex + 1;
387
+ return rows > 1
388
+ ? {
389
+ startRowIndex: data.startRowIndex,
390
+ endRowIndex: data.endRowIndex,
391
+ startColumnIndex: columnIndex,
392
+ endColumnIndex: columnIndex,
393
+ }
394
+ : {
395
+ startRowIndex: data.startRowIndex,
396
+ endRowIndex: data.startRowIndex,
397
+ startColumnIndex: columnIndex,
398
+ endColumnIndex: columnIndex,
399
+ };
400
+ };
401
+ exports.defaultSparklineLocation = defaultSparklineLocation;
402
+ /** The bounding range of a group's location cells (its members are a single row or column run). */
403
+ var sparklineGroupLocation = function (group) {
404
+ var rows = group.members.map(function (m) { return m.cell.rowIndex; });
405
+ var cols = group.members.map(function (m) { return m.cell.columnIndex; });
406
+ return {
407
+ startRowIndex: Math.min.apply(Math, tslib_1.__spreadArray([], tslib_1.__read(rows), false)),
408
+ endRowIndex: Math.max.apply(Math, tslib_1.__spreadArray([], tslib_1.__read(rows), false)),
409
+ startColumnIndex: Math.min.apply(Math, tslib_1.__spreadArray([], tslib_1.__read(cols), false)),
410
+ endColumnIndex: Math.max.apply(Math, tslib_1.__spreadArray([], tslib_1.__read(cols), false)),
411
+ };
412
+ };
413
+ exports.sparklineGroupLocation = sparklineGroupLocation;
414
+ /**
415
+ * The group's "Data Range" as Excel's Edit Group dialog shows it: the union of the members' ranges
416
+ * when they tile one rectangle by rows or columns; otherwise `undefined` (members chart unrelated
417
+ * ranges — Excel then shows the individual ranges only).
418
+ */
419
+ var sparklineGroupDataRange = function (group) {
420
+ var parsed = group.members.map(function (m) { return (0, exports.parseRangeAddress)(m.dataRange); });
421
+ if (parsed.some(function (p) { return !p; }))
422
+ return undefined;
423
+ var ranges = parsed;
424
+ var sheetName = ranges[0].sheetName;
425
+ if (ranges.some(function (r) { return r.sheetName !== sheetName; }))
426
+ return undefined;
427
+ if (ranges.length === 1)
428
+ return (0, exports.rangeToA1)(ranges[0].range, sheetName);
429
+ var first = ranges[0].range;
430
+ var byRows = ranges.every(function (r, i) {
431
+ return r.range.startColumnIndex === first.startColumnIndex &&
432
+ r.range.endColumnIndex === first.endColumnIndex &&
433
+ r.range.startRowIndex === first.startRowIndex + i &&
434
+ r.range.endRowIndex === r.range.startRowIndex;
435
+ });
436
+ var byCols = ranges.every(function (r, i) {
437
+ return r.range.startRowIndex === first.startRowIndex &&
438
+ r.range.endRowIndex === first.endRowIndex &&
439
+ r.range.startColumnIndex === first.startColumnIndex + i &&
440
+ r.range.endColumnIndex === r.range.startColumnIndex;
441
+ });
442
+ if (!byRows && !byCols)
443
+ return undefined;
444
+ var last = ranges[ranges.length - 1].range;
445
+ return (0, exports.rangeToA1)({
446
+ startRowIndex: first.startRowIndex,
447
+ startColumnIndex: first.startColumnIndex,
448
+ endRowIndex: byRows ? last.endRowIndex : first.endRowIndex,
449
+ endColumnIndex: byCols ? last.endColumnIndex : first.endColumnIndex,
450
+ }, sheetName);
451
+ };
452
+ exports.sparklineGroupDataRange = sparklineGroupDataRange;
@@ -52,6 +52,21 @@ export declare const desanitizeSheetName: (name: string | undefined) => string |
52
52
  * @returns
53
53
  */
54
54
  export declare const escapeCharacters: (str: string) => string;
55
+ /**
56
+ * Regular-expression source for an Excel wildcard pattern: `*` matches any run
57
+ * of characters, `?` exactly one, and `~` escapes the next character (`~*` is a
58
+ * literal asterisk). Every other character is matched literally. Callers anchor
59
+ * the source (`^…$` for "equals", `^…` for "begins with", …) and compile it
60
+ * case-insensitively — Excel's text criteria never distinguish case.
61
+ */
62
+ export declare const wildcardPatternToRegExpSource: (pattern: string) => string;
63
+ /**
64
+ * Does `text` satisfy an Excel wildcard `pattern` (see
65
+ * `wildcardPatternToRegExpSource`) under the given anchoring? `equals` is a
66
+ * whole-string match, `startsWith` / `endsWith` anchor one side, `contains`
67
+ * neither. Case-insensitive like Excel's AutoFilter and COUNTIF.
68
+ */
69
+ export declare const matchesWildcardPattern: (pattern: string, text: string, anchor: "equals" | "startsWith" | "endsWith" | "contains") => boolean;
55
70
  /**
56
71
  * Get selection from start and end cell
57
72
  * @param start
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../string.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAK3E;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,aAAa,KAAG,SAKvD,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,SAAS,MAAM,EACf,UAAS;IACP,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,KACL,aAAa,GAAG,IAuDlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,uBAEvD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,uBAErD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,aAAa,GAAG,IAAI,EAC1B,0BAAwB,EACxB,uBAAqB,EACrB,sBAAoB,EACpB,mBAAiB,KAChB,MAAM,GAAG,IAiBX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,GAAG,SAAS,EAC7B,OAAO,SAAS,WAUjB,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,GAAG,SAAS,uBASzD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,GAAG,SAAS,uBAgB3D,CAAC;AAKF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,WAI3C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,aAAa,EACpB,MAAK,aAAa,GAAG,IAAY,KAChC,SAQF,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,WAKzD,CAAC;AAUF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,WAoB/C,CAAC"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../string.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAK3E;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,aAAa,KAAG,SAKvD,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,SAAS,MAAM,EACf,UAAS;IACP,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,KACL,aAAa,GAAG,IAuDlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,uBAEvD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,uBAErD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,aAAa,GAAG,IAAI,EAC1B,0BAAwB,EACxB,uBAAqB,EACrB,sBAAoB,EACpB,mBAAiB,KAChB,MAAM,GAAG,IAiBX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,GAAG,SAAS,EAC7B,OAAO,SAAS,WAUjB,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,GAAG,SAAS,uBASzD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,GAAG,SAAS,uBAgB3D,CAAC;AAKF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,WAI3C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,MAAM,KAAG,MAe/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,QAAQ,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,KACxD,OAWF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,aAAa,EACpB,MAAK,aAAa,GAAG,IAAY,KAChC,SAQF,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,WAKzD,CAAC;AAUF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,WAoB/C,CAAC"}