@rowsncolumns/spreadsheet-state 28.0.73 → 28.0.75
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/api/advanced-filter.d.ts +72 -0
- package/dist/cjs/api/advanced-filter.d.ts.map +1 -0
- package/dist/cjs/api/advanced-filter.js +0 -0
- package/dist/cjs/api/datatype.d.ts.map +1 -1
- package/dist/cjs/api/datatype.js +8 -1
- package/dist/cjs/api/fill-series-spec.d.ts +35 -0
- package/dist/cjs/api/fill-series-spec.d.ts.map +1 -0
- package/dist/cjs/api/fill-series-spec.js +164 -0
- package/dist/cjs/api/fill.d.ts +95 -3
- package/dist/cjs/api/fill.d.ts.map +1 -1
- package/dist/cjs/api/fill.js +1186 -418
- package/dist/cjs/api/goal-seek.d.ts +29 -0
- package/dist/cjs/api/goal-seek.d.ts.map +1 -0
- package/dist/cjs/api/goal-seek.js +131 -0
- package/dist/cjs/api/immer-utils.d.ts.map +1 -1
- package/dist/cjs/api/immer-utils.js +21 -15
- package/dist/cjs/api/intl.d.ts.map +1 -1
- package/dist/cjs/api/paint-format.d.ts +55 -0
- package/dist/cjs/api/paint-format.d.ts.map +1 -0
- package/dist/cjs/api/paint-format.js +174 -0
- package/dist/cjs/api/split-text.d.ts +12 -0
- package/dist/cjs/api/split-text.d.ts.map +1 -1
- package/dist/cjs/api/split-text.js +41 -0
- package/dist/cjs/api/subtotal.d.ts +85 -0
- package/dist/cjs/api/subtotal.d.ts.map +1 -0
- package/dist/cjs/api/subtotal.js +250 -0
- package/dist/cjs/commands.d.ts +19 -1
- package/dist/cjs/commands.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-rule-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-rule-editor.js +83 -16
- package/dist/cjs/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation-worker.js +1 -0
- package/dist/cjs/hooks/use-calculation.d.ts +1 -1
- package/dist/cjs/hooks/use-on-advanced-filter.d.ts +21 -0
- package/dist/cjs/hooks/use-on-advanced-filter.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-advanced-filter.js +42 -0
- package/dist/cjs/hooks/use-on-fill.d.ts +13 -4
- package/dist/cjs/hooks/use-on-fill.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-fill.js +28 -7
- package/dist/cjs/hooks/use-on-goal-seek.d.ts +30 -0
- package/dist/cjs/hooks/use-on-goal-seek.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-goal-seek.js +140 -0
- package/dist/cjs/hooks/use-on-import-excel.d.ts +10 -1
- package/dist/cjs/hooks/use-on-import-excel.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-import-excel.js +8 -4
- package/dist/cjs/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-merge-unmerge-cells.js +53 -34
- package/dist/cjs/hooks/use-on-subtotal.d.ts +26 -0
- package/dist/cjs/hooks/use-on-subtotal.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-subtotal.js +53 -0
- package/dist/cjs/hooks/use-paint-format.d.ts +19 -3
- package/dist/cjs/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/cjs/hooks/use-paint-format.js +89 -32
- package/dist/cjs/hooks/use-sheet-properties.d.ts +2 -0
- package/dist/cjs/hooks/use-sheet-properties.d.ts.map +1 -1
- package/dist/cjs/hooks/use-sheet-properties.js +4 -0
- package/dist/cjs/hooks/use-split-text-to-columns.d.ts +2 -1
- package/dist/cjs/hooks/use-split-text-to-columns.d.ts.map +1 -1
- package/dist/cjs/hooks/use-split-text-to-columns.js +3 -2
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts +50 -36
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/cjs/hooks/use-spreadsheet-state.js +109 -19
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/interface/apply-fill.d.ts +3 -3
- package/dist/cjs/interface/apply-fill.d.ts.map +1 -1
- package/dist/cjs/interface/apply-fill.js +100 -53
- package/dist/cjs/interface/change-batch-stream.d.ts.map +1 -1
- package/dist/cjs/interface/change-batch-stream.js +12 -6
- package/dist/cjs/interface/change-batch.d.ts.map +1 -1
- package/dist/cjs/interface/change-batch.js +17 -9
- package/dist/cjs/interface/change-formatting.d.ts.map +1 -1
- package/dist/cjs/interface/change-formatting.js +30 -11
- package/dist/cjs/interface/split-text.d.ts +2 -1
- package/dist/cjs/interface/split-text.d.ts.map +1 -1
- package/dist/cjs/interface/split-text.js +7 -3
- package/dist/cjs/interface/spreadsheet-interface.d.ts +1 -1
- package/dist/cjs/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/cjs/interface/spreadsheet-interface.js +2 -2
- package/dist/cjs/sheet-cell.d.ts.map +1 -1
- package/dist/cjs/sheet-cell.js +37 -6
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/api/advanced-filter.d.ts +72 -0
- package/dist/esm/api/advanced-filter.d.ts.map +1 -0
- package/dist/esm/api/advanced-filter.js +0 -0
- package/dist/esm/api/datatype.d.ts.map +1 -1
- package/dist/esm/api/datatype.js +8 -1
- package/dist/esm/api/fill-series-spec.d.ts +35 -0
- package/dist/esm/api/fill-series-spec.d.ts.map +1 -0
- package/dist/esm/api/fill-series-spec.js +160 -0
- package/dist/esm/api/fill.d.ts +95 -3
- package/dist/esm/api/fill.d.ts.map +1 -1
- package/dist/esm/api/fill.js +1158 -418
- package/dist/esm/api/goal-seek.d.ts +29 -0
- package/dist/esm/api/goal-seek.d.ts.map +1 -0
- package/dist/esm/api/goal-seek.js +108 -0
- package/dist/esm/api/immer-utils.d.ts.map +1 -1
- package/dist/esm/api/immer-utils.js +21 -15
- package/dist/esm/api/intl.d.ts.map +1 -1
- package/dist/esm/api/paint-format.d.ts +55 -0
- package/dist/esm/api/paint-format.d.ts.map +1 -0
- package/dist/esm/api/paint-format.js +122 -0
- package/dist/esm/api/split-text.d.ts +12 -0
- package/dist/esm/api/split-text.d.ts.map +1 -1
- package/dist/esm/api/split-text.js +28 -0
- package/dist/esm/api/subtotal.d.ts +85 -0
- package/dist/esm/api/subtotal.d.ts.map +1 -0
- package/dist/esm/api/subtotal.js +181 -0
- package/dist/esm/commands.d.ts +19 -1
- package/dist/esm/commands.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-rule-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-rule-editor.js +52 -4
- package/dist/esm/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation-worker.js +1 -0
- package/dist/esm/hooks/use-calculation.d.ts +1 -1
- package/dist/esm/hooks/use-on-advanced-filter.d.ts +21 -0
- package/dist/esm/hooks/use-on-advanced-filter.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-advanced-filter.js +41 -0
- package/dist/esm/hooks/use-on-fill.d.ts +13 -4
- package/dist/esm/hooks/use-on-fill.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-fill.js +24 -4
- package/dist/esm/hooks/use-on-goal-seek.d.ts +30 -0
- package/dist/esm/hooks/use-on-goal-seek.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-goal-seek.js +82 -0
- package/dist/esm/hooks/use-on-import-excel.d.ts +10 -1
- package/dist/esm/hooks/use-on-import-excel.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-import-excel.js +8 -4
- package/dist/esm/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-merge-unmerge-cells.js +13 -13
- package/dist/esm/hooks/use-on-subtotal.d.ts +26 -0
- package/dist/esm/hooks/use-on-subtotal.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-subtotal.js +48 -0
- package/dist/esm/hooks/use-paint-format.d.ts +19 -3
- package/dist/esm/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/esm/hooks/use-paint-format.js +75 -30
- package/dist/esm/hooks/use-sheet-properties.d.ts +2 -0
- package/dist/esm/hooks/use-sheet-properties.d.ts.map +1 -1
- package/dist/esm/hooks/use-sheet-properties.js +4 -0
- package/dist/esm/hooks/use-split-text-to-columns.d.ts +2 -1
- package/dist/esm/hooks/use-split-text-to-columns.d.ts.map +1 -1
- package/dist/esm/hooks/use-split-text-to-columns.js +3 -2
- package/dist/esm/hooks/use-spreadsheet-state.d.ts +50 -36
- package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/esm/hooks/use-spreadsheet-state.js +100 -17
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +8 -0
- package/dist/esm/interface/apply-fill.d.ts +3 -3
- package/dist/esm/interface/apply-fill.d.ts.map +1 -1
- package/dist/esm/interface/apply-fill.js +93 -48
- package/dist/esm/interface/change-batch-stream.d.ts.map +1 -1
- package/dist/esm/interface/change-batch-stream.js +12 -6
- package/dist/esm/interface/change-batch.d.ts.map +1 -1
- package/dist/esm/interface/change-batch.js +15 -9
- package/dist/esm/interface/change-formatting.d.ts.map +1 -1
- package/dist/esm/interface/change-formatting.js +28 -11
- package/dist/esm/interface/split-text.d.ts +2 -1
- package/dist/esm/interface/split-text.d.ts.map +1 -1
- package/dist/esm/interface/split-text.js +6 -3
- package/dist/esm/interface/spreadsheet-interface.d.ts +1 -1
- package/dist/esm/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/esm/interface/spreadsheet-interface.js +2 -2
- package/dist/esm/sheet-cell.d.ts.map +1 -1
- package/dist/esm/sheet-cell.js +37 -6
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +20 -20
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excel's Data → What-If Analysis → Goal Seek solver.
|
|
3
|
+
*
|
|
4
|
+
* Excel's defaults are 100 iterations and a change-tolerance of 0.001 (its
|
|
5
|
+
* Calculation options → "Maximum Iterations" / "Maximum Change"). The
|
|
6
|
+
* search is a secant method — Excel's own is a secant/Newton hybrid — with
|
|
7
|
+
* bisection whenever a sign change has been bracketed and the secant step
|
|
8
|
+
* would leave the bracket, so a monotone target converges in a handful of
|
|
9
|
+
* evaluations while a badly scaled one still narrows a bracket.
|
|
10
|
+
*
|
|
11
|
+
* `evaluate(trial)` returns the set cell's value with the changing cell at
|
|
12
|
+
* `trial`; `undefined` means the trial produced an error (`#DIV/0!`, text…),
|
|
13
|
+
* which the solver treats as "step somewhere else".
|
|
14
|
+
*/
|
|
15
|
+
import type { GoalSeekResult, GoalSeekStatus } from "@rowsncolumns/spreadsheet";
|
|
16
|
+
export declare const GOAL_SEEK_MAX_ITERATIONS = 100;
|
|
17
|
+
export declare const GOAL_SEEK_TOLERANCE = 0.001;
|
|
18
|
+
export type GoalSeekEvaluate = (trial: number) => Promise<number | undefined>;
|
|
19
|
+
export type { GoalSeekResult, GoalSeekStatus };
|
|
20
|
+
export type GoalSeekOptions = {
|
|
21
|
+
evaluate: GoalSeekEvaluate;
|
|
22
|
+
targetValue: number;
|
|
23
|
+
/** Starting trial — the changing cell's current value (0 when blank). */
|
|
24
|
+
initialValue?: number;
|
|
25
|
+
maxIterations?: number;
|
|
26
|
+
tolerance?: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const goalSeek: ({ evaluate, targetValue, initialValue, maxIterations, tolerance, }: GoalSeekOptions) => Promise<GoalSeekResult>;
|
|
29
|
+
//# sourceMappingURL=goal-seek.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-seek.d.ts","sourceRoot":"","sources":["../../../api/goal-seek.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhF,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9E,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAE/C,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAKF,eAAO,MAAM,QAAQ,GAAU,oEAM5B,eAAe,KAAG,OAAO,CAAC,cAAc,CAqG1C,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { __awaiter, __generator } from "tslib";
|
|
2
|
+
export var GOAL_SEEK_MAX_ITERATIONS = 100;
|
|
3
|
+
export var GOAL_SEEK_TOLERANCE = 0.001;
|
|
4
|
+
var isUsable = function (value) {
|
|
5
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
6
|
+
};
|
|
7
|
+
export var goalSeek = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
8
|
+
var iterations, best, residualAt, finish, negative, positive, bracket, x0, f0, nudges, x1, shrinks, backoffs, f1, x2, slope, lo, hi;
|
|
9
|
+
var evaluate = _b.evaluate, targetValue = _b.targetValue, _c = _b.initialValue, initialValue = _c === void 0 ? 0 : _c, _d = _b.maxIterations, maxIterations = _d === void 0 ? GOAL_SEEK_MAX_ITERATIONS : _d, _e = _b.tolerance, tolerance = _e === void 0 ? GOAL_SEEK_TOLERANCE : _e;
|
|
10
|
+
return __generator(this, function (_f) {
|
|
11
|
+
switch (_f.label) {
|
|
12
|
+
case 0:
|
|
13
|
+
iterations = 0;
|
|
14
|
+
best = {
|
|
15
|
+
value: initialValue,
|
|
16
|
+
currentValue: undefined,
|
|
17
|
+
residual: Number.POSITIVE_INFINITY,
|
|
18
|
+
};
|
|
19
|
+
residualAt = function (trial) { return __awaiter(void 0, void 0, void 0, function () {
|
|
20
|
+
var current, residual;
|
|
21
|
+
return __generator(this, function (_a) {
|
|
22
|
+
switch (_a.label) {
|
|
23
|
+
case 0:
|
|
24
|
+
iterations++;
|
|
25
|
+
return [4 /*yield*/, evaluate(trial)];
|
|
26
|
+
case 1:
|
|
27
|
+
current = _a.sent();
|
|
28
|
+
if (!isUsable(current))
|
|
29
|
+
return [2 /*return*/, undefined];
|
|
30
|
+
residual = current - targetValue;
|
|
31
|
+
if (Math.abs(residual) < best.residual) {
|
|
32
|
+
best = { value: trial, currentValue: current, residual: Math.abs(residual) };
|
|
33
|
+
}
|
|
34
|
+
return [2 /*return*/, residual];
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}); };
|
|
38
|
+
finish = function (status) { return ({
|
|
39
|
+
status: status,
|
|
40
|
+
value: best.value,
|
|
41
|
+
currentValue: best.currentValue,
|
|
42
|
+
targetValue: targetValue,
|
|
43
|
+
iterations: iterations,
|
|
44
|
+
}); };
|
|
45
|
+
bracket = function (x, f) {
|
|
46
|
+
if (f < 0)
|
|
47
|
+
negative = x;
|
|
48
|
+
else
|
|
49
|
+
positive = x;
|
|
50
|
+
};
|
|
51
|
+
x0 = initialValue;
|
|
52
|
+
return [4 /*yield*/, residualAt(x0)];
|
|
53
|
+
case 1:
|
|
54
|
+
f0 = _f.sent();
|
|
55
|
+
nudges = 0;
|
|
56
|
+
_f.label = 2;
|
|
57
|
+
case 2:
|
|
58
|
+
if (!(f0 === undefined && iterations < maxIterations && nudges < 8)) return [3 /*break*/, 4];
|
|
59
|
+
x0 = x0 === 0 ? 1 : x0 * 2;
|
|
60
|
+
return [4 /*yield*/, residualAt(x0)];
|
|
61
|
+
case 3:
|
|
62
|
+
f0 = _f.sent();
|
|
63
|
+
nudges++;
|
|
64
|
+
return [3 /*break*/, 2];
|
|
65
|
+
case 4:
|
|
66
|
+
if (f0 === undefined)
|
|
67
|
+
return [2 /*return*/, finish("not-found")];
|
|
68
|
+
if (Math.abs(f0) <= tolerance)
|
|
69
|
+
return [2 /*return*/, finish("found")];
|
|
70
|
+
bracket(x0, f0);
|
|
71
|
+
x1 = x0 === 0 ? 0.01 : x0 * 1.01;
|
|
72
|
+
shrinks = 0;
|
|
73
|
+
backoffs = 0;
|
|
74
|
+
_f.label = 5;
|
|
75
|
+
case 5:
|
|
76
|
+
if (!(iterations < maxIterations)) return [3 /*break*/, 7];
|
|
77
|
+
return [4 /*yield*/, residualAt(x1)];
|
|
78
|
+
case 6:
|
|
79
|
+
f1 = _f.sent();
|
|
80
|
+
if (f1 === undefined) {
|
|
81
|
+
// Errored trial: pull it halfway back toward the last good point.
|
|
82
|
+
if (++shrinks > 16)
|
|
83
|
+
return [2 /*return*/, finish("not-found")];
|
|
84
|
+
x1 = x0 + (x1 - x0) / 2;
|
|
85
|
+
return [3 /*break*/, 5];
|
|
86
|
+
}
|
|
87
|
+
shrinks = 0;
|
|
88
|
+
if (Math.abs(f1) <= tolerance)
|
|
89
|
+
return [2 /*return*/, finish("found")];
|
|
90
|
+
bracket(x1, f1);
|
|
91
|
+
// A secant step that made things worse with no sign change in sight is
|
|
92
|
+
// heading away from the root (a flat or curving function such as =1/A1):
|
|
93
|
+
// back off — half the step, in the opposite direction — instead of
|
|
94
|
+
// following it to infinity. The bracketed case below never needs this.
|
|
95
|
+
if ((negative === undefined || positive === undefined) &&
|
|
96
|
+
Math.abs(f1) > Math.abs(f0)) {
|
|
97
|
+
if (++backoffs > 24)
|
|
98
|
+
return [2 /*return*/, finish("not-found")];
|
|
99
|
+
x1 = x0 - (x1 - x0) / 2;
|
|
100
|
+
return [3 /*break*/, 5];
|
|
101
|
+
}
|
|
102
|
+
backoffs = 0;
|
|
103
|
+
x2 = void 0;
|
|
104
|
+
slope = f1 - f0;
|
|
105
|
+
if (slope === 0 || !Number.isFinite(slope)) {
|
|
106
|
+
// Flat: widen the step in the same direction to find any change.
|
|
107
|
+
x2 = x1 + (x1 - x0 || 0.01) * 2;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
x2 = x1 - (f1 * (x1 - x0)) / slope;
|
|
111
|
+
}
|
|
112
|
+
if (negative !== undefined && positive !== undefined) {
|
|
113
|
+
lo = Math.min(negative, positive);
|
|
114
|
+
hi = Math.max(negative, positive);
|
|
115
|
+
if (!Number.isFinite(x2) || x2 <= lo || x2 >= hi) {
|
|
116
|
+
x2 = (lo + hi) / 2;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (!Number.isFinite(x2)) {
|
|
120
|
+
return [2 /*return*/, finish("not-found")];
|
|
121
|
+
}
|
|
122
|
+
if (x2 === x1)
|
|
123
|
+
return [2 /*return*/, finish(Math.abs(f1) <= tolerance ? "found" : "not-found")];
|
|
124
|
+
x0 = x1;
|
|
125
|
+
f0 = f1;
|
|
126
|
+
x1 = x2;
|
|
127
|
+
return [3 /*break*/, 5];
|
|
128
|
+
case 7: return [2 /*return*/, finish("not-found")];
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}); };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,IAAI,2BAA2B,EAC/C,SAAS,IAAI,oBAAoB,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI7E,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,2BAA2B,CAAC;AASnC,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAQxE,KAAK,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC7D,KAAK,gBAAgB,CAAC,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,SAAS,IACzD,2BAA2B,CAAC,CAAC,CAAC,CAAC;AAEjC,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EACjD,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAC1B,SAAS,MAAM,EACf,WAAW,MAAM,KAgBD,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,EAC9D,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EACvD,SAAS,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,KACjE,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAa9C,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,QAAQ,EACxD,UAAU,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,oBAItC,CAAC;
|
|
1
|
+
{"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,8 +50,7 @@ var isGenericNumberFormatType = function (type) { return !type || type === "NUMB
|
|
|
50
50
|
* Date-family types — when the derived (resolved) type is one of these
|
|
51
51
|
* and the precedent's type is also in this set, we preserve the
|
|
52
52
|
* precedent's exact custom pattern instead of synthesizing a locale
|
|
53
|
-
* default
|
|
54
|
-
* (EDATE, EOMONTH, …) where `=EDATE(A1, 1)` keeps A1's custom pattern.
|
|
53
|
+
* default (`=DATE(YEAR(A1), MONTH(A1), 1)` keeps A1's custom pattern).
|
|
55
54
|
*/
|
|
56
55
|
var isDateFamilyType = function (type) { return type === "DATE" || type === "TIME" || type === "DATE_TIME"; };
|
|
57
56
|
var customNumberFormatMap = {
|
|
@@ -70,6 +69,7 @@ var formatDerivationRules = {
|
|
|
70
69
|
UNIQUE: { type: "fixed_index", index: 0 },
|
|
71
70
|
TAKE: { type: "fixed_index", index: 0 },
|
|
72
71
|
DROP: { type: "fixed_index", index: 0 },
|
|
72
|
+
TRIMRANGE: { type: "fixed_index", index: 0 },
|
|
73
73
|
EXPAND: { type: "fixed_index", index: 0 },
|
|
74
74
|
TOCOL: { type: "fixed_index", index: 0 },
|
|
75
75
|
TOROW: { type: "fixed_index", index: 0 },
|
|
@@ -163,18 +163,21 @@ var functionReturnTypes = {
|
|
|
163
163
|
NETWORKDAYS: "NUMBER",
|
|
164
164
|
"NETWORKDAYS.INTL": "NUMBER",
|
|
165
165
|
DAYS360: "NUMBER",
|
|
166
|
+
// The date-arithmetic functions return date serials, but Excel does
|
|
167
|
+
// NOT auto-format them: `=EDATE(DATE(2026,1,31),1)` shows 46081 in a
|
|
168
|
+
// General cell until the user formats it (rowsncolumns/spreadsheet#642
|
|
169
|
+
// B-09). NUMBER — like DATEVALUE — rather than absent, so a nested
|
|
170
|
+
// DATE()/TODAY() argument cannot promote the result to a date (the
|
|
171
|
+
// outermost function decides, as in `=YEAR(TODAY())`).
|
|
172
|
+
EDATE: "NUMBER",
|
|
173
|
+
EOMONTH: "NUMBER",
|
|
174
|
+
WORKDAY: "NUMBER",
|
|
175
|
+
"WORKDAY.INTL": "NUMBER",
|
|
166
176
|
// ─── Date/time — date producers (must render as DATE/TIME/DATE_TIME) ─
|
|
167
177
|
NOW: "DATE_TIME",
|
|
168
178
|
TODAY: "DATE",
|
|
169
179
|
DATE: "DATE",
|
|
170
180
|
TIME: "TIME",
|
|
171
|
-
EDATE: "DATE",
|
|
172
|
-
EOMONTH: "DATE",
|
|
173
|
-
// WORKDAY returns a date serial number — must render as DATE, not
|
|
174
|
-
// raw NUMBER (was a bug: cells showed e.g. "45292" instead of the
|
|
175
|
-
// calendar date).
|
|
176
|
-
WORKDAY: "DATE",
|
|
177
|
-
"WORKDAY.INTL": "DATE",
|
|
178
181
|
// ─── Aggregation / rounding (return NUMBER; CURRENCY precedent
|
|
179
182
|
// preserved via the "expectedOutputType === NUMBER + numFormat
|
|
180
183
|
// CURRENCY → keep numFormat" branch) ──────────────────────────
|
|
@@ -321,7 +324,10 @@ var currencyDecimalAdjustmentFunctions = new Set([
|
|
|
321
324
|
"QUOTIENT",
|
|
322
325
|
]);
|
|
323
326
|
// Get all function names from formula
|
|
324
|
-
|
|
327
|
+
// Function names may be dotted (`WORKDAY.INTL`, `PERCENTILE.INC`, `FORECAST.ETS`); without the
|
|
328
|
+
// `.` the match stopped at the suffix (`INTL(`) and the dotted keys of `functionReturnTypes` /
|
|
329
|
+
// `formatDerivationRules` never applied.
|
|
330
|
+
var functionRegex = /([A-Za-z0-9_.]+)\s*\(/g;
|
|
325
331
|
export var getFunctionNamesFromFormula = function (formula) {
|
|
326
332
|
var match;
|
|
327
333
|
var matches = [];
|
|
@@ -521,7 +527,7 @@ resolvePrecedentNumberFormat) {
|
|
|
521
527
|
effectivePrecedents = filterPrecedentsByBounds(effectivePrecedents, directBounds);
|
|
522
528
|
var upperFormula = formula === null || formula === void 0 ? void 0 : formula.trim().toUpperCase();
|
|
523
529
|
if (upperFormula) {
|
|
524
|
-
var functionNameMatch = upperFormula.match(/^=([A-Z0-9_]+)\(/);
|
|
530
|
+
var functionNameMatch = upperFormula.match(/^=([A-Z0-9_.]+)\(/);
|
|
525
531
|
topLevelFunctionName = functionNameMatch ? functionNameMatch[1] : undefined;
|
|
526
532
|
var rule = topLevelFunctionName
|
|
527
533
|
? formatDerivationRules[topLevelFunctionName]
|
|
@@ -700,10 +706,10 @@ resolvePrecedentNumberFormat) {
|
|
|
700
706
|
// Date/time types need a concrete pattern — without one the renderer
|
|
701
707
|
// falls back to "General" and shows the serial number (the
|
|
702
708
|
// =TODAY() bug). When the precedent itself is a date-family format
|
|
703
|
-
// with a pattern, inherit that pattern (e.g. `=
|
|
704
|
-
// A1's custom `yyyy-mm-dd` instead of falling
|
|
705
|
-
// default). Otherwise mirror the format toolbar's
|
|
706
|
-
// type.
|
|
709
|
+
// with a pattern, inherit that pattern (e.g. `=DATE(YEAR(A1),
|
|
710
|
+
// MONTH(A1), 1)` keeps A1's custom `yyyy-mm-dd` instead of falling
|
|
711
|
+
// back to the locale default). Otherwise mirror the format toolbar's
|
|
712
|
+
// default for the type.
|
|
707
713
|
if (isDateFamilyType(resolvedNumberFormat.type) &&
|
|
708
714
|
isDateFamilyType(numFormat === null || numFormat === void 0 ? void 0 : numFormat.type) &&
|
|
709
715
|
(numFormat === null || numFormat === void 0 ? void 0 : numFormat.pattern)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intl.d.ts","sourceRoot":"","sources":["../../../api/intl.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,EAAE,gBAAc,WAK5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM
|
|
1
|
+
{"version":3,"file":"intl.d.ts","sourceRoot":"","sources":["../../../api/intl.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,EAAE,gBAAc,WAK5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM;WAlCxC,MAAM;aAAW,MAAM;eAAa,MAAM;iBAAe,MAAM;CA6EzE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM;eA1E5B,MAAM;YAAU,OAAO;YAAU,OAAO;iBAAe,OAAO;CAqH5E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM;UAtHxC,MAAM;YAAU,OAAO;YAAU,OAAO;CAkJjD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM;aA/JlC,MAAM;eAAa,MAAM;WAAS,MAAM;aAgMpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,wBAkBhD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,YAuBnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,gBA0BtD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { CellFormat, CellInterface, GridRange } from "@rowsncolumns/common-types";
|
|
2
|
+
/**
|
|
3
|
+
* Format-painter pattern shared by both engines: the captured 2-D format grid plus the
|
|
4
|
+
* source block's merge configuration, re-based to the block's top-left so it can be tiled
|
|
5
|
+
* onto any target (Google Sheets copies merges with the format; Excel's painter does too).
|
|
6
|
+
*/
|
|
7
|
+
export type PaintPattern = {
|
|
8
|
+
formats: (CellFormat | null | undefined)[][];
|
|
9
|
+
/** Merges fully inside the source block, as 0-based offsets from its top-left. */
|
|
10
|
+
merges: GridRange[];
|
|
11
|
+
/** Source block size — the tiling period. */
|
|
12
|
+
rows: number;
|
|
13
|
+
cols: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The merges the painter carries from a source block: every merge that lies FULLY inside
|
|
17
|
+
* `source`, re-based to 0-based offsets from the block's top-left. A merge reaching outside the
|
|
18
|
+
* block is not part of its pattern (Sheets/Excel behave the same — the painter copies the look of
|
|
19
|
+
* the selected cells, not of the cells around them).
|
|
20
|
+
*/
|
|
21
|
+
export declare const collectPaintMerges: (merges: GridRange[] | null | undefined, source: GridRange) => GridRange[];
|
|
22
|
+
/**
|
|
23
|
+
* The block the painter captures when it is armed WITHOUT a drag selection. A plain click on a
|
|
24
|
+
* merged cell selects the whole merged area in Excel and Sheets, but the grid reports it as the
|
|
25
|
+
* anchor active cell plus an empty selection list — so the source is the merge containing the
|
|
26
|
+
* active cell when there is one, otherwise the single cell.
|
|
27
|
+
*/
|
|
28
|
+
export declare const paintSourceForActiveCell: (merges: GridRange[] | null | undefined, activeCell: CellInterface) => GridRange;
|
|
29
|
+
/**
|
|
30
|
+
* Excel stores a merged area's style on every constituent cell, and the grid paints a merge with
|
|
31
|
+
* its anchor's format. Copy the anchor's captured format over the covered cells of every merge in
|
|
32
|
+
* the pattern (in place) so the painted target carries the fill on all of them — an unmerge at the
|
|
33
|
+
* target, or a partial tile that drops the merge, still leaves every cell looking as it did.
|
|
34
|
+
*/
|
|
35
|
+
export declare const spreadMergeAnchorFormats: (formats: (CellFormat | null | undefined)[][], relativeMerges: GridRange[]) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Tile a pattern's relative merges across `target` with the pattern's period (`rows` × `cols`),
|
|
38
|
+
* the same way the format grid itself is tiled by the formatting applier. A merge that a partial
|
|
39
|
+
* trailing tile would push past the target's edge is dropped — the painter never creates a merge
|
|
40
|
+
* that the user did not drag over.
|
|
41
|
+
*/
|
|
42
|
+
export declare const tilePaintMerges: (relativeMerges: GridRange[], rows: number, cols: number, target: GridRange) => GridRange[];
|
|
43
|
+
/**
|
|
44
|
+
* The banded (table stripe / alternating-colour) format the grid paints under a cell, looked up
|
|
45
|
+
* in the map `getBandedCells` builds for a sheet.
|
|
46
|
+
*/
|
|
47
|
+
export declare const getBandedCellFormat: (bandedCells: Map<string, CellFormat> | undefined | null, rowIndex: number, columnIndex: number) => CellFormat | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Layer a cell's explicit format over the banded format the grid would paint beneath it, so the
|
|
50
|
+
* captured pattern carries the VISIBLE look (Sheets copies the alternating colours as static cell
|
|
51
|
+
* fills — it does not create a table or banding at the target). Explicit keys win; an explicit
|
|
52
|
+
* `undefined` never clobbers a banded value.
|
|
53
|
+
*/
|
|
54
|
+
export declare const layerBandedFormat: (explicit: CellFormat | null | undefined, banded: CellFormat | undefined) => CellFormat | null | undefined;
|
|
55
|
+
//# sourceMappingURL=paint-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paint-format.d.ts","sourceRoot":"","sources":["../../../api/paint-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,SAAS,EACV,MAAM,4BAA4B,CAAC;AAGpC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAAE,CAAC;IAC7C,kFAAkF;IAClF,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAQF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS,EAAE,GAAG,IAAI,GAAG,SAAS,EACtC,QAAQ,SAAS,KAChB,SAAS,EAaX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,QAAQ,SAAS,EAAE,GAAG,IAAI,GAAG,SAAS,EACtC,YAAY,aAAa,KACxB,SAkBF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACnC,SAAS,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAAE,EAC5C,gBAAgB,SAAS,EAAE,KAC1B,IAYF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,gBAAgB,SAAS,EAAE,EAC3B,MAAM,MAAM,EACZ,MAAM,MAAM,EACZ,QAAQ,SAAS,KAChB,SAAS,EAqBX,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,aAAa,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,GAAG,IAAI,EACvD,UAAU,MAAM,EAChB,aAAa,MAAM,KAClB,UAAU,GAAG,SACyC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,UAAU,GAAG,IAAI,GAAG,SAAS,EACvC,QAAQ,UAAU,GAAG,SAAS,KAC7B,UAAU,GAAG,IAAI,GAAG,SAWtB,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { __assign, __read, __values } from "tslib";
|
|
2
|
+
import { cellIdentifier, isCellWithinBounds } from "@rowsncolumns/grid";
|
|
3
|
+
var rangeContains = function (outer, inner) {
|
|
4
|
+
return inner.startRowIndex >= outer.startRowIndex &&
|
|
5
|
+
inner.endRowIndex <= outer.endRowIndex &&
|
|
6
|
+
inner.startColumnIndex >= outer.startColumnIndex &&
|
|
7
|
+
inner.endColumnIndex <= outer.endColumnIndex;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The merges the painter carries from a source block: every merge that lies FULLY inside
|
|
11
|
+
* `source`, re-based to 0-based offsets from the block's top-left. A merge reaching outside the
|
|
12
|
+
* block is not part of its pattern (Sheets/Excel behave the same — the painter copies the look of
|
|
13
|
+
* the selected cells, not of the cells around them).
|
|
14
|
+
*/
|
|
15
|
+
export var collectPaintMerges = function (merges, source) {
|
|
16
|
+
var e_1, _a;
|
|
17
|
+
if (!(merges === null || merges === void 0 ? void 0 : merges.length))
|
|
18
|
+
return [];
|
|
19
|
+
var out = [];
|
|
20
|
+
try {
|
|
21
|
+
for (var merges_1 = __values(merges), merges_1_1 = merges_1.next(); !merges_1_1.done; merges_1_1 = merges_1.next()) {
|
|
22
|
+
var merge = merges_1_1.value;
|
|
23
|
+
if (!rangeContains(source, merge))
|
|
24
|
+
continue;
|
|
25
|
+
out.push({
|
|
26
|
+
startRowIndex: merge.startRowIndex - source.startRowIndex,
|
|
27
|
+
endRowIndex: merge.endRowIndex - source.startRowIndex,
|
|
28
|
+
startColumnIndex: merge.startColumnIndex - source.startColumnIndex,
|
|
29
|
+
endColumnIndex: merge.endColumnIndex - source.startColumnIndex,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
34
|
+
finally {
|
|
35
|
+
try {
|
|
36
|
+
if (merges_1_1 && !merges_1_1.done && (_a = merges_1.return)) _a.call(merges_1);
|
|
37
|
+
}
|
|
38
|
+
finally { if (e_1) throw e_1.error; }
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The block the painter captures when it is armed WITHOUT a drag selection. A plain click on a
|
|
44
|
+
* merged cell selects the whole merged area in Excel and Sheets, but the grid reports it as the
|
|
45
|
+
* anchor active cell plus an empty selection list — so the source is the merge containing the
|
|
46
|
+
* active cell when there is one, otherwise the single cell.
|
|
47
|
+
*/
|
|
48
|
+
export var paintSourceForActiveCell = function (merges, activeCell) {
|
|
49
|
+
var merge = merges === null || merges === void 0 ? void 0 : merges.find(function (candidate) {
|
|
50
|
+
return isCellWithinBounds(activeCell, candidate);
|
|
51
|
+
});
|
|
52
|
+
if (merge) {
|
|
53
|
+
return {
|
|
54
|
+
startRowIndex: merge.startRowIndex,
|
|
55
|
+
endRowIndex: merge.endRowIndex,
|
|
56
|
+
startColumnIndex: merge.startColumnIndex,
|
|
57
|
+
endColumnIndex: merge.endColumnIndex,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
startRowIndex: activeCell.rowIndex,
|
|
62
|
+
endRowIndex: activeCell.rowIndex,
|
|
63
|
+
startColumnIndex: activeCell.columnIndex,
|
|
64
|
+
endColumnIndex: activeCell.columnIndex,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Excel stores a merged area's style on every constituent cell, and the grid paints a merge with
|
|
69
|
+
* its anchor's format. Copy the anchor's captured format over the covered cells of every merge in
|
|
70
|
+
* the pattern (in place) so the painted target carries the fill on all of them — an unmerge at the
|
|
71
|
+
* target, or a partial tile that drops the merge, still leaves every cell looking as it did.
|
|
72
|
+
*/
|
|
73
|
+
export var spreadMergeAnchorFormats = function (formats, relativeMerges) {
|
|
74
|
+
var e_2, _a;
|
|
75
|
+
var _b;
|
|
76
|
+
try {
|
|
77
|
+
for (var relativeMerges_1 = __values(relativeMerges), relativeMerges_1_1 = relativeMerges_1.next(); !relativeMerges_1_1.done; relativeMerges_1_1 = relativeMerges_1.next()) {
|
|
78
|
+
var merge = relativeMerges_1_1.value;
|
|
79
|
+
var anchor = (_b = formats[merge.startRowIndex]) === null || _b === void 0 ? void 0 : _b[merge.startColumnIndex];
|
|
80
|
+
for (var r = merge.startRowIndex; r <= merge.endRowIndex; r++) {
|
|
81
|
+
var row = formats[r];
|
|
82
|
+
if (!row)
|
|
83
|
+
continue;
|
|
84
|
+
for (var c = merge.startColumnIndex; c <= merge.endColumnIndex; c++) {
|
|
85
|
+
if (r === merge.startRowIndex && c === merge.startColumnIndex)
|
|
86
|
+
continue;
|
|
87
|
+
if (c < row.length)
|
|
88
|
+
row[c] = anchor;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
94
|
+
finally {
|
|
95
|
+
try {
|
|
96
|
+
if (relativeMerges_1_1 && !relativeMerges_1_1.done && (_a = relativeMerges_1.return)) _a.call(relativeMerges_1);
|
|
97
|
+
}
|
|
98
|
+
finally { if (e_2) throw e_2.error; }
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Tile a pattern's relative merges across `target` with the pattern's period (`rows` × `cols`),
|
|
103
|
+
* the same way the format grid itself is tiled by the formatting applier. A merge that a partial
|
|
104
|
+
* trailing tile would push past the target's edge is dropped — the painter never creates a merge
|
|
105
|
+
* that the user did not drag over.
|
|
106
|
+
*/
|
|
107
|
+
export var tilePaintMerges = function (relativeMerges, rows, cols, target) {
|
|
108
|
+
var e_3, _a;
|
|
109
|
+
if (!relativeMerges.length || rows <= 0 || cols <= 0)
|
|
110
|
+
return [];
|
|
111
|
+
var out = [];
|
|
112
|
+
for (var top_1 = target.startRowIndex; top_1 <= target.endRowIndex; top_1 += rows) {
|
|
113
|
+
for (var left = target.startColumnIndex; left <= target.endColumnIndex; left += cols) {
|
|
114
|
+
try {
|
|
115
|
+
for (var relativeMerges_2 = (e_3 = void 0, __values(relativeMerges)), relativeMerges_2_1 = relativeMerges_2.next(); !relativeMerges_2_1.done; relativeMerges_2_1 = relativeMerges_2.next()) {
|
|
116
|
+
var merge = relativeMerges_2_1.value;
|
|
117
|
+
var placed = {
|
|
118
|
+
startRowIndex: top_1 + merge.startRowIndex,
|
|
119
|
+
endRowIndex: top_1 + merge.endRowIndex,
|
|
120
|
+
startColumnIndex: left + merge.startColumnIndex,
|
|
121
|
+
endColumnIndex: left + merge.endColumnIndex,
|
|
122
|
+
};
|
|
123
|
+
if (rangeContains(target, placed))
|
|
124
|
+
out.push(placed);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
128
|
+
finally {
|
|
129
|
+
try {
|
|
130
|
+
if (relativeMerges_2_1 && !relativeMerges_2_1.done && (_a = relativeMerges_2.return)) _a.call(relativeMerges_2);
|
|
131
|
+
}
|
|
132
|
+
finally { if (e_3) throw e_3.error; }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* The banded (table stripe / alternating-colour) format the grid paints under a cell, looked up
|
|
140
|
+
* in the map `getBandedCells` builds for a sheet.
|
|
141
|
+
*/
|
|
142
|
+
export var getBandedCellFormat = function (bandedCells, rowIndex, columnIndex) {
|
|
143
|
+
return bandedCells === null || bandedCells === void 0 ? void 0 : bandedCells.get(cellIdentifier(rowIndex, columnIndex));
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Layer a cell's explicit format over the banded format the grid would paint beneath it, so the
|
|
147
|
+
* captured pattern carries the VISIBLE look (Sheets copies the alternating colours as static cell
|
|
148
|
+
* fills — it does not create a table or banding at the target). Explicit keys win; an explicit
|
|
149
|
+
* `undefined` never clobbers a banded value.
|
|
150
|
+
*/
|
|
151
|
+
export var layerBandedFormat = function (explicit, banded) {
|
|
152
|
+
var e_4, _a;
|
|
153
|
+
if (!banded)
|
|
154
|
+
return explicit;
|
|
155
|
+
var merged = __assign({}, banded);
|
|
156
|
+
if (explicit) {
|
|
157
|
+
try {
|
|
158
|
+
for (var _b = __values(Object.entries(explicit)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
159
|
+
var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
|
|
160
|
+
if (value !== undefined) {
|
|
161
|
+
merged[key] = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
166
|
+
finally {
|
|
167
|
+
try {
|
|
168
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
169
|
+
}
|
|
170
|
+
finally { if (e_4) throw e_4.error; }
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return merged;
|
|
174
|
+
};
|
|
@@ -1,2 +1,14 @@
|
|
|
1
|
+
import type { SplitTextOptions } from "@rowsncolumns/spreadsheet";
|
|
1
2
|
export declare const splitTextToColumns: (values: (string | null | undefined)[], delimiter?: string) => string[][];
|
|
3
|
+
export type { SplitTextOptions };
|
|
4
|
+
/** Normalized, ascending, de-duplicated positive break positions. */
|
|
5
|
+
export declare const normalizeColumnBreaks: (columnBreaks: number[]) => number[];
|
|
6
|
+
/**
|
|
7
|
+
* Excel's Text to Columns → Fixed width: cut each cell at the given
|
|
8
|
+
* character positions. Fields are trimmed like the delimited path (Excel's
|
|
9
|
+
* General column data format drops the padding spaces fixed-width data is
|
|
10
|
+
* aligned with). Cells without breaks inside their text still split — the
|
|
11
|
+
* trailing fields are empty — so the resulting block is rectangular.
|
|
12
|
+
*/
|
|
13
|
+
export declare const splitTextFixedWidth: (values: (string | null | undefined)[], columnBreaks: number[]) => string[][];
|
|
2
14
|
//# sourceMappingURL=split-text.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-text.d.ts","sourceRoot":"","sources":["../../../api/split-text.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"split-text.d.ts","sourceRoot":"","sources":["../../../api/split-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,YAAW,MAAY,KACtB,MAAM,EAAE,EAwBV,CAAC;AAEF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,GAAI,cAAc,MAAM,EAAE,KAAG,MAAM,EAG3C,CAAC;AAE3B;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,cAAc,MAAM,EAAE,KACrB,MAAM,EAAE,EAgBV,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { __read, __spreadArray, __values } from "tslib";
|
|
1
2
|
import { isNil } from "@rowsncolumns/utils";
|
|
2
3
|
// Split text to columns - takes a single column and returns 2D array
|
|
3
4
|
export var splitTextToColumns = function (values, delimiter) {
|
|
@@ -23,3 +24,43 @@ export var splitTextToColumns = function (values, delimiter) {
|
|
|
23
24
|
return trimmedParts;
|
|
24
25
|
});
|
|
25
26
|
};
|
|
27
|
+
/** Normalized, ascending, de-duplicated positive break positions. */
|
|
28
|
+
export var normalizeColumnBreaks = function (columnBreaks) {
|
|
29
|
+
return __spreadArray([], __read(new Set(columnBreaks)), false).filter(function (position) { return Number.isInteger(position) && position > 0; })
|
|
30
|
+
.sort(function (a, b) { return a - b; });
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Excel's Text to Columns → Fixed width: cut each cell at the given
|
|
34
|
+
* character positions. Fields are trimmed like the delimited path (Excel's
|
|
35
|
+
* General column data format drops the padding spaces fixed-width data is
|
|
36
|
+
* aligned with). Cells without breaks inside their text still split — the
|
|
37
|
+
* trailing fields are empty — so the resulting block is rectangular.
|
|
38
|
+
*/
|
|
39
|
+
export var splitTextFixedWidth = function (values, columnBreaks) {
|
|
40
|
+
var breaks = normalizeColumnBreaks(columnBreaks);
|
|
41
|
+
return values.map(function (cell) {
|
|
42
|
+
var e_1, _a;
|
|
43
|
+
if (isNil(cell)) {
|
|
44
|
+
return [""];
|
|
45
|
+
}
|
|
46
|
+
var text = String(cell);
|
|
47
|
+
var parts = [];
|
|
48
|
+
var start = 0;
|
|
49
|
+
try {
|
|
50
|
+
for (var breaks_1 = __values(breaks), breaks_1_1 = breaks_1.next(); !breaks_1_1.done; breaks_1_1 = breaks_1.next()) {
|
|
51
|
+
var position = breaks_1_1.value;
|
|
52
|
+
parts.push(text.slice(start, position).trim());
|
|
53
|
+
start = position;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
57
|
+
finally {
|
|
58
|
+
try {
|
|
59
|
+
if (breaks_1_1 && !breaks_1_1.done && (_a = breaks_1.return)) _a.call(breaks_1);
|
|
60
|
+
}
|
|
61
|
+
finally { if (e_1) throw e_1.error; }
|
|
62
|
+
}
|
|
63
|
+
parts.push(text.slice(start).trim());
|
|
64
|
+
return parts;
|
|
65
|
+
});
|
|
66
|
+
};
|