@devmm/puredocs-excel-formula 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +554 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +554 -63
- package/dist/index.js.map +1 -1
- package/package.json +45 -45
- package/LICENSE +0 -21
package/dist/index.cjs
CHANGED
|
@@ -2358,9 +2358,11 @@ function datedif(a, c) {
|
|
|
2358
2358
|
function registerLookup(r) {
|
|
2359
2359
|
r.register("VLOOKUP", vlookup, 3, 4);
|
|
2360
2360
|
r.register("HLOOKUP", hlookup, 3, 4);
|
|
2361
|
+
r.register("XLOOKUP", xlookup, 3, 6);
|
|
2361
2362
|
r.register("LOOKUP", lookup, 2, 3);
|
|
2362
2363
|
r.register("INDEX", index_, 2, 3);
|
|
2363
2364
|
r.register("MATCH", match, 2, 3);
|
|
2365
|
+
r.register("XMATCH", xmatch, 2, 4);
|
|
2364
2366
|
r.register("CHOOSE", choose, 2);
|
|
2365
2367
|
r.register("ADDRESS", address, 2, 5);
|
|
2366
2368
|
r.register("ROW", row, 0, 1);
|
|
@@ -2434,6 +2436,121 @@ function hlookup(a, c) {
|
|
|
2434
2436
|
}
|
|
2435
2437
|
return best >= 0 ? tbl.get(rowIdx, best) : FormulaValue.errorNA;
|
|
2436
2438
|
}
|
|
2439
|
+
function wildcardRegex(pattern) {
|
|
2440
|
+
let out = "";
|
|
2441
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
2442
|
+
const ch = pattern[i];
|
|
2443
|
+
if (ch === "~" && i + 1 < pattern.length) {
|
|
2444
|
+
const next = pattern[++i];
|
|
2445
|
+
out += next.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2446
|
+
} else if (ch === "*") out += ".*";
|
|
2447
|
+
else if (ch === "?") out += ".";
|
|
2448
|
+
else out += ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2449
|
+
}
|
|
2450
|
+
return new RegExp(`^${out}$`, "i");
|
|
2451
|
+
}
|
|
2452
|
+
function findMatch(n, get, lookupVal, matchMode, searchMode) {
|
|
2453
|
+
if ((searchMode === 2 || searchMode === -2) && matchMode !== 2) {
|
|
2454
|
+
const at = searchMode === 2 ? get : (j) => get(n - 1 - j);
|
|
2455
|
+
let lo = 0, hi = n - 1, lastLE = -1, firstGE = -1;
|
|
2456
|
+
while (lo <= hi) {
|
|
2457
|
+
const mid2 = lo + hi >>> 1;
|
|
2458
|
+
const cmp = FormulaValue.compare(at(mid2), lookupVal);
|
|
2459
|
+
if (cmp === 0) return searchMode === 2 ? mid2 : n - 1 - mid2;
|
|
2460
|
+
if (cmp < 0) {
|
|
2461
|
+
lastLE = mid2;
|
|
2462
|
+
lo = mid2 + 1;
|
|
2463
|
+
} else {
|
|
2464
|
+
firstGE = mid2;
|
|
2465
|
+
hi = mid2 - 1;
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
const idx = matchMode === -1 ? lastLE : matchMode === 1 ? firstGE : -1;
|
|
2469
|
+
return idx < 0 ? -1 : searchMode === 2 ? idx : n - 1 - idx;
|
|
2470
|
+
}
|
|
2471
|
+
const reverse = searchMode === -1;
|
|
2472
|
+
const order = reverse ? Array.from({ length: n }, (_, k) => n - 1 - k) : Array.from({ length: n }, (_, k) => k);
|
|
2473
|
+
if (matchMode === 2) {
|
|
2474
|
+
const re = wildcardRegex(lookupVal.asText());
|
|
2475
|
+
for (const i of order) if (re.test(get(i).asText())) return i;
|
|
2476
|
+
return -1;
|
|
2477
|
+
}
|
|
2478
|
+
if (matchMode === 0) {
|
|
2479
|
+
for (const i of order) if (FormulaValue.areEqual(get(i), lookupVal)) return i;
|
|
2480
|
+
return -1;
|
|
2481
|
+
}
|
|
2482
|
+
let best = -1;
|
|
2483
|
+
let bestVal = null;
|
|
2484
|
+
for (const i of order) {
|
|
2485
|
+
const v = get(i);
|
|
2486
|
+
const cmp = FormulaValue.compare(v, lookupVal);
|
|
2487
|
+
if (cmp === 0) return i;
|
|
2488
|
+
if (matchMode === -1 && cmp < 0) {
|
|
2489
|
+
if (bestVal === null || FormulaValue.compare(v, bestVal) > 0) {
|
|
2490
|
+
best = i;
|
|
2491
|
+
bestVal = v;
|
|
2492
|
+
}
|
|
2493
|
+
} else if (matchMode === 1 && cmp > 0) {
|
|
2494
|
+
if (bestVal === null || FormulaValue.compare(v, bestVal) < 0) {
|
|
2495
|
+
best = i;
|
|
2496
|
+
bestVal = v;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
return best;
|
|
2501
|
+
}
|
|
2502
|
+
function xlookup(a, c) {
|
|
2503
|
+
const lookupVal = a[0].evaluate(c);
|
|
2504
|
+
if (lookupVal.isError) return lookupVal;
|
|
2505
|
+
const lookupRaw = a[1].evaluate(c);
|
|
2506
|
+
if (lookupRaw.isError) return lookupRaw;
|
|
2507
|
+
const returnRaw = a[2].evaluate(c);
|
|
2508
|
+
if (returnRaw.isError) return returnRaw;
|
|
2509
|
+
const matchMode = a.length > 4 ? num2(a, c, 4) : { ok: true, n: 0 };
|
|
2510
|
+
if (!matchMode.ok) return matchMode.e;
|
|
2511
|
+
const searchMode = a.length > 5 ? num2(a, c, 5) : { ok: true, n: 1 };
|
|
2512
|
+
if (!searchMode.ok) return searchMode.e;
|
|
2513
|
+
const mm = Math.trunc(matchMode.n), sm = Math.trunc(searchMode.n);
|
|
2514
|
+
const la = lookupRaw.isArray ? lookupRaw.arrayVal : ArrayValue.fromScalar(lookupRaw);
|
|
2515
|
+
if (la.rows > 1 && la.columns > 1) return FormulaValue.errorValue;
|
|
2516
|
+
const vertical = !(la.rows === 1 && la.columns > 1);
|
|
2517
|
+
const n = vertical ? la.rows : la.columns;
|
|
2518
|
+
const get = vertical ? (i) => la.get(i, 0) : (i) => la.get(0, i);
|
|
2519
|
+
const idx = findMatch(n, get, lookupVal, mm, sm);
|
|
2520
|
+
if (idx < 0) {
|
|
2521
|
+
return a.length > 3 ? a[3].evaluate(c) : FormulaValue.errorNA;
|
|
2522
|
+
}
|
|
2523
|
+
const ret = returnRaw.isArray ? returnRaw.arrayVal : ArrayValue.fromScalar(returnRaw);
|
|
2524
|
+
if (vertical) {
|
|
2525
|
+
if (ret.rows !== n) return FormulaValue.errorValue;
|
|
2526
|
+
if (ret.columns === 1) return ret.get(idx, 0);
|
|
2527
|
+
const out2 = new ArrayValue(1, ret.columns);
|
|
2528
|
+
for (let col = 0; col < ret.columns; col++) out2.set(0, col, ret.get(idx, col));
|
|
2529
|
+
return FormulaValue.array(out2);
|
|
2530
|
+
}
|
|
2531
|
+
if (ret.columns !== n) return FormulaValue.errorValue;
|
|
2532
|
+
if (ret.rows === 1) return ret.get(0, idx);
|
|
2533
|
+
const out = new ArrayValue(ret.rows, 1);
|
|
2534
|
+
for (let r = 0; r < ret.rows; r++) out.set(r, 0, ret.get(r, idx));
|
|
2535
|
+
return FormulaValue.array(out);
|
|
2536
|
+
}
|
|
2537
|
+
function xmatch(a, c) {
|
|
2538
|
+
const lookupVal = a[0].evaluate(c);
|
|
2539
|
+
if (lookupVal.isError) return lookupVal;
|
|
2540
|
+
const lookupRaw = a[1].evaluate(c);
|
|
2541
|
+
if (lookupRaw.isError) return lookupRaw;
|
|
2542
|
+
const matchMode = a.length > 2 ? num2(a, c, 2) : { ok: true, n: 0 };
|
|
2543
|
+
if (!matchMode.ok) return matchMode.e;
|
|
2544
|
+
const searchMode = a.length > 3 ? num2(a, c, 3) : { ok: true, n: 1 };
|
|
2545
|
+
if (!searchMode.ok) return searchMode.e;
|
|
2546
|
+
const la = lookupRaw.isArray ? lookupRaw.arrayVal : ArrayValue.fromScalar(lookupRaw);
|
|
2547
|
+
if (la.rows > 1 && la.columns > 1) return FormulaValue.errorValue;
|
|
2548
|
+
const vertical = !(la.rows === 1 && la.columns > 1);
|
|
2549
|
+
const n = vertical ? la.rows : la.columns;
|
|
2550
|
+
const get = vertical ? (i) => la.get(i, 0) : (i) => la.get(0, i);
|
|
2551
|
+
const idx = findMatch(n, get, lookupVal, Math.trunc(matchMode.n), Math.trunc(searchMode.n));
|
|
2552
|
+
return idx < 0 ? FormulaValue.errorNA : FormulaValue.number(idx + 1);
|
|
2553
|
+
}
|
|
2437
2554
|
function index_(a, c) {
|
|
2438
2555
|
const arrVal = a[0].evaluate(c);
|
|
2439
2556
|
if (arrVal.isError) return arrVal;
|
|
@@ -2967,6 +3084,24 @@ function registerFinance(r) {
|
|
|
2967
3084
|
r.register("PV", pv, 3, 5);
|
|
2968
3085
|
r.register("NPV", npv, 2);
|
|
2969
3086
|
r.register("IRR", irr, 1, 2);
|
|
3087
|
+
r.register("RATE", rate, 3, 6);
|
|
3088
|
+
r.register("NPER", nper, 3, 5);
|
|
3089
|
+
r.register("XNPV", xnpv, 3, 3);
|
|
3090
|
+
r.register("XIRR", xirr, 2, 3);
|
|
3091
|
+
r.register("IPMT", ipmt, 4, 6);
|
|
3092
|
+
r.register("PPMT", ppmt, 4, 6);
|
|
3093
|
+
}
|
|
3094
|
+
function pmtValue(r, n, pv2, fv2, type) {
|
|
3095
|
+
if (r === 0) return -(pv2 + fv2) / n;
|
|
3096
|
+
const pow = Math.pow(1 + r, n);
|
|
3097
|
+
let payment = (-fv2 - pv2 * pow) * r / (pow - 1);
|
|
3098
|
+
if (type === 1) payment /= 1 + r;
|
|
3099
|
+
return payment;
|
|
3100
|
+
}
|
|
3101
|
+
function fvValue(r, n, pmt2, pv2, type) {
|
|
3102
|
+
if (r === 0) return -(pv2 + pmt2 * n);
|
|
3103
|
+
const pow = Math.pow(1 + r, n);
|
|
3104
|
+
return -(pv2 * pow + pmt2 * (1 + r * type) * (pow - 1) / r);
|
|
2970
3105
|
}
|
|
2971
3106
|
function arg(a, c, idx, dflt) {
|
|
2972
3107
|
if (idx >= a.length) return { ok: true, n: dflt };
|
|
@@ -2974,65 +3109,59 @@ function arg(a, c, idx, dflt) {
|
|
|
2974
3109
|
return r.ok ? { ok: true, n: r.value } : { ok: false, e: r.error };
|
|
2975
3110
|
}
|
|
2976
3111
|
function pmt(a, c) {
|
|
2977
|
-
const
|
|
2978
|
-
if (!
|
|
2979
|
-
const
|
|
2980
|
-
if (!
|
|
3112
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3113
|
+
if (!rate2.ok) return rate2.e;
|
|
3114
|
+
const nper2 = arg(a, c, 1, 0);
|
|
3115
|
+
if (!nper2.ok) return nper2.e;
|
|
2981
3116
|
const pvv = arg(a, c, 2, 0);
|
|
2982
3117
|
if (!pvv.ok) return pvv.e;
|
|
2983
3118
|
const fvv = arg(a, c, 3, 0);
|
|
2984
3119
|
if (!fvv.ok) return fvv.e;
|
|
2985
3120
|
const type = arg(a, c, 4, 0);
|
|
2986
3121
|
if (!type.ok) return type.e;
|
|
2987
|
-
const r =
|
|
3122
|
+
const r = rate2.n, n = nper2.n, present = pvv.n, future = fvv.n, t = type.n;
|
|
2988
3123
|
if (n === 0) return FormulaValue.errorNum;
|
|
2989
|
-
|
|
2990
|
-
const pow = Math.pow(1 + r, n);
|
|
2991
|
-
let payment = (-future - present * pow) * r / (pow - 1);
|
|
2992
|
-
if (t === 1) payment /= 1 + r;
|
|
2993
|
-
return FormulaValue.number(payment);
|
|
3124
|
+
return FormulaValue.number(pmtValue(r, n, present, future, t));
|
|
2994
3125
|
}
|
|
2995
3126
|
function fv(a, c) {
|
|
2996
|
-
const
|
|
2997
|
-
if (!
|
|
2998
|
-
const
|
|
2999
|
-
if (!
|
|
3127
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3128
|
+
if (!rate2.ok) return rate2.e;
|
|
3129
|
+
const nper2 = arg(a, c, 1, 0);
|
|
3130
|
+
if (!nper2.ok) return nper2.e;
|
|
3000
3131
|
const pmtv = arg(a, c, 2, 0);
|
|
3001
3132
|
if (!pmtv.ok) return pmtv.e;
|
|
3002
3133
|
const pvv = arg(a, c, 3, 0);
|
|
3003
3134
|
if (!pvv.ok) return pvv.e;
|
|
3004
3135
|
const type = arg(a, c, 4, 0);
|
|
3005
3136
|
if (!type.ok) return type.e;
|
|
3006
|
-
const r =
|
|
3007
|
-
|
|
3008
|
-
const pow = Math.pow(1 + r, n);
|
|
3009
|
-
return FormulaValue.number(-(present * pow + payment * (1 + r * t) * (pow - 1) / r));
|
|
3137
|
+
const r = rate2.n, n = nper2.n, payment = pmtv.n, present = pvv.n, t = type.n;
|
|
3138
|
+
return FormulaValue.number(fvValue(r, n, payment, present, t));
|
|
3010
3139
|
}
|
|
3011
3140
|
function pv(a, c) {
|
|
3012
|
-
const
|
|
3013
|
-
if (!
|
|
3014
|
-
const
|
|
3015
|
-
if (!
|
|
3141
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3142
|
+
if (!rate2.ok) return rate2.e;
|
|
3143
|
+
const nper2 = arg(a, c, 1, 0);
|
|
3144
|
+
if (!nper2.ok) return nper2.e;
|
|
3016
3145
|
const pmtv = arg(a, c, 2, 0);
|
|
3017
3146
|
if (!pmtv.ok) return pmtv.e;
|
|
3018
3147
|
const fvv = arg(a, c, 3, 0);
|
|
3019
3148
|
if (!fvv.ok) return fvv.e;
|
|
3020
3149
|
const type = arg(a, c, 4, 0);
|
|
3021
3150
|
if (!type.ok) return type.e;
|
|
3022
|
-
const r =
|
|
3151
|
+
const r = rate2.n, n = nper2.n, payment = pmtv.n, future = fvv.n, t = type.n;
|
|
3023
3152
|
if (r === 0) return FormulaValue.number(-(future + payment * n));
|
|
3024
3153
|
const pow = Math.pow(1 + r, n);
|
|
3025
3154
|
return FormulaValue.number(-(future + payment * (1 + r * t) * (pow - 1) / r) / pow);
|
|
3026
3155
|
}
|
|
3027
3156
|
function npv(a, c) {
|
|
3028
|
-
const
|
|
3029
|
-
if (!
|
|
3030
|
-
if (
|
|
3157
|
+
const rate2 = exports.FormulaHelper.evalDouble(a[0], c);
|
|
3158
|
+
if (!rate2.ok) return rate2.error;
|
|
3159
|
+
if (rate2.value === -1) return FormulaValue.errorDiv0;
|
|
3031
3160
|
const flows = exports.FormulaHelper.collectNumbers(a.slice(1), c);
|
|
3032
3161
|
if (!flows.ok) return flows.error;
|
|
3033
3162
|
let total = 0;
|
|
3034
3163
|
for (let i = 0; i < flows.values.length; i++) {
|
|
3035
|
-
total += flows.values[i] / Math.pow(1 +
|
|
3164
|
+
total += flows.values[i] / Math.pow(1 + rate2.value, i + 1);
|
|
3036
3165
|
}
|
|
3037
3166
|
return FormulaValue.number(total);
|
|
3038
3167
|
}
|
|
@@ -3047,27 +3176,220 @@ function irr(a, c) {
|
|
|
3047
3176
|
if (!g.ok) return g.error;
|
|
3048
3177
|
guess = g.value;
|
|
3049
3178
|
}
|
|
3050
|
-
const npvAt = (
|
|
3179
|
+
const npvAt = (rate3) => {
|
|
3051
3180
|
let sum2 = 0;
|
|
3052
|
-
for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 +
|
|
3181
|
+
for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 + rate3, i);
|
|
3053
3182
|
return sum2;
|
|
3054
3183
|
};
|
|
3055
|
-
let
|
|
3184
|
+
let rate2 = guess;
|
|
3185
|
+
for (let iter = 0; iter < 100; iter++) {
|
|
3186
|
+
const f = npvAt(rate2);
|
|
3187
|
+
if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
|
|
3188
|
+
const h = 1e-6;
|
|
3189
|
+
const deriv = (npvAt(rate2 + h) - f) / h;
|
|
3190
|
+
if (deriv === 0) break;
|
|
3191
|
+
const next = rate2 - f / deriv;
|
|
3192
|
+
if (!isFinite(next) || next <= -1) break;
|
|
3193
|
+
if (Math.abs(next - rate2) < 1e-9) {
|
|
3194
|
+
rate2 = next;
|
|
3195
|
+
break;
|
|
3196
|
+
}
|
|
3197
|
+
rate2 = next;
|
|
3198
|
+
}
|
|
3199
|
+
if (Math.abs(npvAt(rate2)) < 1e-6) return FormulaValue.number(rate2);
|
|
3200
|
+
return FormulaValue.errorNum;
|
|
3201
|
+
}
|
|
3202
|
+
function tvm(r, n, pmt2, pv2, fv2, type) {
|
|
3203
|
+
if (r === 0) return pv2 + pmt2 * n + fv2;
|
|
3204
|
+
const pow = Math.pow(1 + r, n);
|
|
3205
|
+
return pv2 * pow + pmt2 * (1 + r * type) * (pow - 1) / r + fv2;
|
|
3206
|
+
}
|
|
3207
|
+
function rate(a, c) {
|
|
3208
|
+
const nper2 = arg(a, c, 0, 0);
|
|
3209
|
+
if (!nper2.ok) return nper2.e;
|
|
3210
|
+
const pmtv = arg(a, c, 1, 0);
|
|
3211
|
+
if (!pmtv.ok) return pmtv.e;
|
|
3212
|
+
const pvv = arg(a, c, 2, 0);
|
|
3213
|
+
if (!pvv.ok) return pvv.e;
|
|
3214
|
+
const fvv = arg(a, c, 3, 0);
|
|
3215
|
+
if (!fvv.ok) return fvv.e;
|
|
3216
|
+
const type = arg(a, c, 4, 0);
|
|
3217
|
+
if (!type.ok) return type.e;
|
|
3218
|
+
const gs = arg(a, c, 5, 0.1);
|
|
3219
|
+
if (!gs.ok) return gs.e;
|
|
3220
|
+
const n = nper2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3221
|
+
if (n === 0) return FormulaValue.errorNum;
|
|
3222
|
+
let r = gs.n;
|
|
3056
3223
|
for (let iter = 0; iter < 100; iter++) {
|
|
3057
|
-
const f =
|
|
3058
|
-
if (Math.abs(f) < 1e-
|
|
3224
|
+
const f = tvm(r, n, pmt2, pv2, fv2, t);
|
|
3225
|
+
if (Math.abs(f) < 1e-8) return FormulaValue.number(r);
|
|
3059
3226
|
const h = 1e-6;
|
|
3060
|
-
const deriv = (
|
|
3227
|
+
const deriv = (tvm(r + h, n, pmt2, pv2, fv2, t) - f) / h;
|
|
3061
3228
|
if (deriv === 0) break;
|
|
3062
|
-
const next =
|
|
3229
|
+
const next = r - f / deriv;
|
|
3063
3230
|
if (!isFinite(next) || next <= -1) break;
|
|
3064
|
-
if (Math.abs(next -
|
|
3065
|
-
|
|
3231
|
+
if (Math.abs(next - r) < 1e-10) {
|
|
3232
|
+
r = next;
|
|
3066
3233
|
break;
|
|
3067
3234
|
}
|
|
3068
|
-
|
|
3235
|
+
r = next;
|
|
3069
3236
|
}
|
|
3070
|
-
if (Math.abs(
|
|
3237
|
+
if (Math.abs(tvm(r, n, pmt2, pv2, fv2, t)) < 1e-6) return FormulaValue.number(r);
|
|
3238
|
+
return FormulaValue.errorNum;
|
|
3239
|
+
}
|
|
3240
|
+
function nper(a, c) {
|
|
3241
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3242
|
+
if (!rate2.ok) return rate2.e;
|
|
3243
|
+
const pmtv = arg(a, c, 1, 0);
|
|
3244
|
+
if (!pmtv.ok) return pmtv.e;
|
|
3245
|
+
const pvv = arg(a, c, 2, 0);
|
|
3246
|
+
if (!pvv.ok) return pvv.e;
|
|
3247
|
+
const fvv = arg(a, c, 3, 0);
|
|
3248
|
+
if (!fvv.ok) return fvv.e;
|
|
3249
|
+
const type = arg(a, c, 4, 0);
|
|
3250
|
+
if (!type.ok) return type.e;
|
|
3251
|
+
const r = rate2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3252
|
+
if (r === 0) {
|
|
3253
|
+
if (pmt2 === 0) return FormulaValue.errorNum;
|
|
3254
|
+
return FormulaValue.number(-(pv2 + fv2) / pmt2);
|
|
3255
|
+
}
|
|
3256
|
+
const adj = pmt2 * (1 + r * t);
|
|
3257
|
+
const num5 = adj - fv2 * r;
|
|
3258
|
+
const den = adj + pv2 * r;
|
|
3259
|
+
if (den === 0 || num5 / den <= 0) return FormulaValue.errorNum;
|
|
3260
|
+
const result = Math.log(num5 / den) / Math.log(1 + r);
|
|
3261
|
+
if (!isFinite(result)) return FormulaValue.errorNum;
|
|
3262
|
+
return FormulaValue.number(result);
|
|
3263
|
+
}
|
|
3264
|
+
function interestForPeriod(r, per, n, pv2, fv2, t) {
|
|
3265
|
+
const pay = pmtValue(r, n, pv2, fv2, t);
|
|
3266
|
+
if (t === 1) {
|
|
3267
|
+
if (per === 1) return 0;
|
|
3268
|
+
return fvValue(r, per - 2, pay, pv2, 1) * r / (1 + r);
|
|
3269
|
+
}
|
|
3270
|
+
return fvValue(r, per - 1, pay, pv2, 0) * r;
|
|
3271
|
+
}
|
|
3272
|
+
function ipmt(a, c) {
|
|
3273
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3274
|
+
if (!rate2.ok) return rate2.e;
|
|
3275
|
+
const perv = arg(a, c, 1, 0);
|
|
3276
|
+
if (!perv.ok) return perv.e;
|
|
3277
|
+
const nper2 = arg(a, c, 2, 0);
|
|
3278
|
+
if (!nper2.ok) return nper2.e;
|
|
3279
|
+
const pvv = arg(a, c, 3, 0);
|
|
3280
|
+
if (!pvv.ok) return pvv.e;
|
|
3281
|
+
const fvv = arg(a, c, 4, 0);
|
|
3282
|
+
if (!fvv.ok) return fvv.e;
|
|
3283
|
+
const type = arg(a, c, 5, 0);
|
|
3284
|
+
if (!type.ok) return type.e;
|
|
3285
|
+
const r = rate2.n, per = perv.n, n = nper2.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3286
|
+
if (n === 0 || per < 1 || per > n) return FormulaValue.errorNum;
|
|
3287
|
+
return FormulaValue.number(interestForPeriod(r, per, n, pv2, fv2, t));
|
|
3288
|
+
}
|
|
3289
|
+
function ppmt(a, c) {
|
|
3290
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3291
|
+
if (!rate2.ok) return rate2.e;
|
|
3292
|
+
const perv = arg(a, c, 1, 0);
|
|
3293
|
+
if (!perv.ok) return perv.e;
|
|
3294
|
+
const nper2 = arg(a, c, 2, 0);
|
|
3295
|
+
if (!nper2.ok) return nper2.e;
|
|
3296
|
+
const pvv = arg(a, c, 3, 0);
|
|
3297
|
+
if (!pvv.ok) return pvv.e;
|
|
3298
|
+
const fvv = arg(a, c, 4, 0);
|
|
3299
|
+
if (!fvv.ok) return fvv.e;
|
|
3300
|
+
const type = arg(a, c, 5, 0);
|
|
3301
|
+
if (!type.ok) return type.e;
|
|
3302
|
+
const r = rate2.n, per = perv.n, n = nper2.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3303
|
+
if (n === 0 || per < 1 || per > n) return FormulaValue.errorNum;
|
|
3304
|
+
const pay = pmtValue(r, n, pv2, fv2, t);
|
|
3305
|
+
return FormulaValue.number(pay - interestForPeriod(r, per, n, pv2, fv2, t));
|
|
3306
|
+
}
|
|
3307
|
+
function flatNumbers(node, c) {
|
|
3308
|
+
const v = node.evaluate(c);
|
|
3309
|
+
if (v.isError) return { ok: false, e: v };
|
|
3310
|
+
const out = [];
|
|
3311
|
+
const push = (item) => {
|
|
3312
|
+
if (item.isError) return item;
|
|
3313
|
+
const d = item.tryAsDouble();
|
|
3314
|
+
if (!d.ok) return FormulaValue.errorValue;
|
|
3315
|
+
out.push(d.value);
|
|
3316
|
+
return null;
|
|
3317
|
+
};
|
|
3318
|
+
if (v.isArray) {
|
|
3319
|
+
for (const item of v.arrayVal.values()) {
|
|
3320
|
+
const err = push(item);
|
|
3321
|
+
if (err) return { ok: false, e: err };
|
|
3322
|
+
}
|
|
3323
|
+
} else {
|
|
3324
|
+
const err = push(v);
|
|
3325
|
+
if (err) return { ok: false, e: err };
|
|
3326
|
+
}
|
|
3327
|
+
return { ok: true, values: out };
|
|
3328
|
+
}
|
|
3329
|
+
function xnpvAt(rate2, values, days2) {
|
|
3330
|
+
let sum2 = 0;
|
|
3331
|
+
for (let i = 0; i < values.length; i++) {
|
|
3332
|
+
sum2 += values[i] / Math.pow(1 + rate2, days2[i] / 365);
|
|
3333
|
+
}
|
|
3334
|
+
return sum2;
|
|
3335
|
+
}
|
|
3336
|
+
function xnpv(a, c) {
|
|
3337
|
+
const rateRes = exports.FormulaHelper.evalDouble(a[0], c);
|
|
3338
|
+
if (!rateRes.ok) return rateRes.error;
|
|
3339
|
+
const rate2 = rateRes.value;
|
|
3340
|
+
if (rate2 <= -1) return FormulaValue.errorNum;
|
|
3341
|
+
const valsRes = flatNumbers(a[1], c);
|
|
3342
|
+
if (!valsRes.ok) return valsRes.e;
|
|
3343
|
+
const datesRes = flatNumbers(a[2], c);
|
|
3344
|
+
if (!datesRes.ok) return datesRes.e;
|
|
3345
|
+
const values = valsRes.values;
|
|
3346
|
+
const dates = datesRes.values;
|
|
3347
|
+
if (values.length === 0 || values.length !== dates.length) return FormulaValue.errorNum;
|
|
3348
|
+
const base = Math.trunc(dates[0]);
|
|
3349
|
+
const days2 = dates.map((d) => Math.trunc(d) - base);
|
|
3350
|
+
if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
|
|
3351
|
+
return FormulaValue.number(xnpvAt(rate2, values, days2));
|
|
3352
|
+
}
|
|
3353
|
+
function xirr(a, c) {
|
|
3354
|
+
const valsRes = flatNumbers(a[0], c);
|
|
3355
|
+
if (!valsRes.ok) return valsRes.e;
|
|
3356
|
+
const datesRes = flatNumbers(a[1], c);
|
|
3357
|
+
if (!datesRes.ok) return datesRes.e;
|
|
3358
|
+
const values = valsRes.values;
|
|
3359
|
+
const dates = datesRes.values;
|
|
3360
|
+
if (values.length < 2 || values.length !== dates.length) return FormulaValue.errorNum;
|
|
3361
|
+
let guess = 0.1;
|
|
3362
|
+
if (a.length > 2) {
|
|
3363
|
+
const g = exports.FormulaHelper.evalDouble(a[2], c);
|
|
3364
|
+
if (!g.ok) return g.error;
|
|
3365
|
+
guess = g.value;
|
|
3366
|
+
}
|
|
3367
|
+
const base = Math.trunc(dates[0]);
|
|
3368
|
+
const days2 = dates.map((d) => Math.trunc(d) - base);
|
|
3369
|
+
if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
|
|
3370
|
+
const derivAt = (rate3) => {
|
|
3371
|
+
let sum2 = 0;
|
|
3372
|
+
for (let i = 0; i < values.length; i++) {
|
|
3373
|
+
const e = days2[i] / 365;
|
|
3374
|
+
sum2 += -e * values[i] / Math.pow(1 + rate3, e + 1);
|
|
3375
|
+
}
|
|
3376
|
+
return sum2;
|
|
3377
|
+
};
|
|
3378
|
+
let rate2 = guess;
|
|
3379
|
+
for (let iter = 0; iter < 100; iter++) {
|
|
3380
|
+
const f = xnpvAt(rate2, values, days2);
|
|
3381
|
+
if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
|
|
3382
|
+
const deriv = derivAt(rate2);
|
|
3383
|
+
if (deriv === 0) break;
|
|
3384
|
+
const next = rate2 - f / deriv;
|
|
3385
|
+
if (!isFinite(next) || next <= -1) break;
|
|
3386
|
+
if (Math.abs(next - rate2) < 1e-9) {
|
|
3387
|
+
rate2 = next;
|
|
3388
|
+
break;
|
|
3389
|
+
}
|
|
3390
|
+
rate2 = next;
|
|
3391
|
+
}
|
|
3392
|
+
if (Math.abs(xnpvAt(rate2, values, days2)) < 1e-6) return FormulaValue.number(rate2);
|
|
3071
3393
|
return FormulaValue.errorNum;
|
|
3072
3394
|
}
|
|
3073
3395
|
|
|
@@ -3405,10 +3727,17 @@ function registerArray(r) {
|
|
|
3405
3727
|
r.register("SEQUENCE", sequence, 1, 4);
|
|
3406
3728
|
r.register("UNIQUE", unique, 1, 3);
|
|
3407
3729
|
r.register("SORT", sort, 1, 4);
|
|
3730
|
+
r.register("SORTBY", sortBy, 2);
|
|
3408
3731
|
r.register("FILTER", filter, 2, 3);
|
|
3409
3732
|
r.register("MMULT", mmult, 2, 2);
|
|
3410
3733
|
r.register("TEXTSPLIT", textSplit, 2, 6);
|
|
3734
|
+
r.register("VSTACK", vstack, 1);
|
|
3735
|
+
r.register("HSTACK", hstack, 1);
|
|
3736
|
+
r.register("TOCOL", toCol, 1, 3);
|
|
3737
|
+
r.register("TOROW", toRow, 1, 3);
|
|
3411
3738
|
}
|
|
3739
|
+
var MAX_ROWS = 1048576;
|
|
3740
|
+
var MAX_COLS = 16384;
|
|
3412
3741
|
var asArray2 = (v) => v.isArray ? v.arrayVal : ArrayValue.fromScalar(v);
|
|
3413
3742
|
function fromRows(rows2) {
|
|
3414
3743
|
const nr = rows2.length;
|
|
@@ -3455,26 +3784,53 @@ function sequence(a, c) {
|
|
|
3455
3784
|
}
|
|
3456
3785
|
return FormulaValue.array(arr);
|
|
3457
3786
|
}
|
|
3458
|
-
function
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3787
|
+
function cellKey(v) {
|
|
3788
|
+
switch (v.kind) {
|
|
3789
|
+
case "number":
|
|
3790
|
+
return "n" + (v.numberValue === 0 ? "0" : String(v.numberValue));
|
|
3791
|
+
case "text":
|
|
3792
|
+
return "t" + v.textValue.toUpperCase();
|
|
3793
|
+
// case-insensitive
|
|
3794
|
+
case "boolean":
|
|
3795
|
+
return v.booleanValue ? "b1" : "b0";
|
|
3796
|
+
case "blank":
|
|
3797
|
+
return "B";
|
|
3798
|
+
case "error":
|
|
3799
|
+
return "e" + v.errorCode;
|
|
3800
|
+
default:
|
|
3801
|
+
return "x";
|
|
3802
|
+
}
|
|
3462
3803
|
}
|
|
3463
3804
|
function unique(a, c) {
|
|
3464
3805
|
const v = a[0].evaluate(c);
|
|
3465
3806
|
if (v.isError) return v;
|
|
3466
3807
|
const byCol2 = a.length > 1 ? a[1].evaluate(c).coerceToBool().booleanValue : false;
|
|
3467
3808
|
const exactlyOnce = a.length > 2 ? a[2].evaluate(c).coerceToBool().booleanValue : false;
|
|
3468
|
-
|
|
3469
|
-
const
|
|
3470
|
-
const
|
|
3809
|
+
const base = byCol2 ? asArray2(v).transpose() : asArray2(v);
|
|
3810
|
+
const map = /* @__PURE__ */ new Map();
|
|
3811
|
+
const order = [];
|
|
3812
|
+
for (let r = 0; r < base.rows; r++) {
|
|
3813
|
+
const cells = new Array(base.columns);
|
|
3814
|
+
let key = "";
|
|
3815
|
+
for (let col = 0; col < base.columns; col++) {
|
|
3816
|
+
const cell = base.get(r, col);
|
|
3817
|
+
cells[col] = cell;
|
|
3818
|
+
const k = cellKey(cell);
|
|
3819
|
+
key += k.length + ":" + k;
|
|
3820
|
+
}
|
|
3821
|
+
const hit = map.get(key);
|
|
3822
|
+
if (hit) hit.count++;
|
|
3823
|
+
else {
|
|
3824
|
+
map.set(key, { cells, count: 1 });
|
|
3825
|
+
order.push(key);
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3471
3828
|
const result = [];
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
});
|
|
3829
|
+
for (const key of order) {
|
|
3830
|
+
const e = map.get(key);
|
|
3831
|
+
if (exactlyOnce && e.count > 1) continue;
|
|
3832
|
+
result.push(e.cells);
|
|
3833
|
+
}
|
|
3478
3834
|
if (result.length === 0) return FormulaValue.error(8 /* Calc */);
|
|
3479
3835
|
const out = fromRows(result);
|
|
3480
3836
|
return byCol2 ? FormulaValue.array(out.arrayVal.transpose()) : out;
|
|
@@ -3499,6 +3855,58 @@ function sort(a, c) {
|
|
|
3499
3855
|
const out = fromRows(sorted);
|
|
3500
3856
|
return byCol2 ? FormulaValue.array(out.arrayVal.transpose()) : out;
|
|
3501
3857
|
}
|
|
3858
|
+
function sortBy(a, c) {
|
|
3859
|
+
const v = a[0].evaluate(c);
|
|
3860
|
+
if (v.isError) return v;
|
|
3861
|
+
const data = asArray2(v);
|
|
3862
|
+
const keys = [];
|
|
3863
|
+
let i = 1;
|
|
3864
|
+
while (i < a.length) {
|
|
3865
|
+
const byVal = a[i].evaluate(c);
|
|
3866
|
+
if (byVal.isError) return byVal;
|
|
3867
|
+
i++;
|
|
3868
|
+
let dir = 1;
|
|
3869
|
+
if (i < a.length) {
|
|
3870
|
+
const maybeOrder = a[i].evaluate(c);
|
|
3871
|
+
if (maybeOrder.isError) return maybeOrder;
|
|
3872
|
+
if (!maybeOrder.isArray && maybeOrder.isNumeric) {
|
|
3873
|
+
const d = maybeOrder.tryAsDouble();
|
|
3874
|
+
if (d.ok) {
|
|
3875
|
+
dir = d.value < 0 ? -1 : 1;
|
|
3876
|
+
i++;
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
keys.push({ vals: [...asArray2(byVal).values()], dir });
|
|
3881
|
+
}
|
|
3882
|
+
if (keys.length === 0) return FormulaValue.errorValue;
|
|
3883
|
+
const n = keys[0].vals.length;
|
|
3884
|
+
if (keys.some((k) => k.vals.length !== n)) return FormulaValue.errorValue;
|
|
3885
|
+
const byRow2 = n === data.rows;
|
|
3886
|
+
const byColumn = !byRow2 && n === data.columns;
|
|
3887
|
+
if (!byRow2 && !byColumn) return FormulaValue.errorValue;
|
|
3888
|
+
const perm = Array.from({ length: n }, (_, k) => k);
|
|
3889
|
+
perm.sort((x, y) => {
|
|
3890
|
+
for (const key of keys) {
|
|
3891
|
+
const cmp = FormulaValue.compare(key.vals[x], key.vals[y]) * key.dir;
|
|
3892
|
+
if (cmp !== 0) return cmp;
|
|
3893
|
+
}
|
|
3894
|
+
return x - y;
|
|
3895
|
+
});
|
|
3896
|
+
const out = new ArrayValue(data.rows, data.columns);
|
|
3897
|
+
if (byRow2) {
|
|
3898
|
+
for (let r = 0; r < data.rows; r++) {
|
|
3899
|
+
const src = perm[r];
|
|
3900
|
+
for (let col = 0; col < data.columns; col++) out.set(r, col, data.get(src, col));
|
|
3901
|
+
}
|
|
3902
|
+
} else {
|
|
3903
|
+
for (let col = 0; col < data.columns; col++) {
|
|
3904
|
+
const src = perm[col];
|
|
3905
|
+
for (let r = 0; r < data.rows; r++) out.set(r, col, data.get(r, src));
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
return FormulaValue.array(out);
|
|
3909
|
+
}
|
|
3502
3910
|
function filter(a, c) {
|
|
3503
3911
|
const v = a[0].evaluate(c);
|
|
3504
3912
|
if (v.isError) return v;
|
|
@@ -3580,6 +3988,89 @@ function textSplit(a, c) {
|
|
|
3580
3988
|
});
|
|
3581
3989
|
return fromRows(rows2);
|
|
3582
3990
|
}
|
|
3991
|
+
function vstack(a, c) {
|
|
3992
|
+
const parts = [];
|
|
3993
|
+
let totalRows = 0, maxCols = 0;
|
|
3994
|
+
for (const node of a) {
|
|
3995
|
+
const arr = asArray2(node.evaluate(c));
|
|
3996
|
+
parts.push(arr);
|
|
3997
|
+
totalRows += arr.rows;
|
|
3998
|
+
if (arr.columns > maxCols) maxCols = arr.columns;
|
|
3999
|
+
}
|
|
4000
|
+
if (totalRows > MAX_ROWS || maxCols > MAX_COLS) return FormulaValue.errorNum;
|
|
4001
|
+
const out = new ArrayValue(totalRows, maxCols);
|
|
4002
|
+
let rowOff = 0;
|
|
4003
|
+
for (const arr of parts) {
|
|
4004
|
+
for (let r = 0; r < arr.rows; r++) {
|
|
4005
|
+
for (let col = 0; col < maxCols; col++) {
|
|
4006
|
+
out.set(rowOff + r, col, col < arr.columns ? arr.get(r, col) : FormulaValue.errorNA);
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
rowOff += arr.rows;
|
|
4010
|
+
}
|
|
4011
|
+
return FormulaValue.array(out);
|
|
4012
|
+
}
|
|
4013
|
+
function hstack(a, c) {
|
|
4014
|
+
const parts = [];
|
|
4015
|
+
let totalCols = 0, maxRows = 0;
|
|
4016
|
+
for (const node of a) {
|
|
4017
|
+
const arr = asArray2(node.evaluate(c));
|
|
4018
|
+
parts.push(arr);
|
|
4019
|
+
totalCols += arr.columns;
|
|
4020
|
+
if (arr.rows > maxRows) maxRows = arr.rows;
|
|
4021
|
+
}
|
|
4022
|
+
if (maxRows > MAX_ROWS || totalCols > MAX_COLS) return FormulaValue.errorNum;
|
|
4023
|
+
const out = new ArrayValue(maxRows, totalCols);
|
|
4024
|
+
let colOff = 0;
|
|
4025
|
+
for (const arr of parts) {
|
|
4026
|
+
for (let col = 0; col < arr.columns; col++) {
|
|
4027
|
+
for (let r = 0; r < maxRows; r++) {
|
|
4028
|
+
out.set(r, colOff + col, r < arr.rows ? arr.get(r, col) : FormulaValue.errorNA);
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
colOff += arr.columns;
|
|
4032
|
+
}
|
|
4033
|
+
return FormulaValue.array(out);
|
|
4034
|
+
}
|
|
4035
|
+
function flatten(a, c) {
|
|
4036
|
+
const arr = asArray2(a[0].evaluate(c));
|
|
4037
|
+
const ig = num4(a, c, 1, 0);
|
|
4038
|
+
if (!ig.ok) return { ok: false, e: ig.e };
|
|
4039
|
+
const ignore = Math.trunc(ig.n);
|
|
4040
|
+
const byCol2 = a.length > 2 ? a[2].evaluate(c).coerceToBool().booleanValue : false;
|
|
4041
|
+
const skip = (x) => (ignore & 1) !== 0 && x.isBlank || (ignore & 2) !== 0 && x.isError;
|
|
4042
|
+
const values = [];
|
|
4043
|
+
if (byCol2) {
|
|
4044
|
+
for (let col = 0; col < arr.columns; col++)
|
|
4045
|
+
for (let r = 0; r < arr.rows; r++) {
|
|
4046
|
+
const x = arr.get(r, col);
|
|
4047
|
+
if (!skip(x)) values.push(x);
|
|
4048
|
+
}
|
|
4049
|
+
} else {
|
|
4050
|
+
for (let r = 0; r < arr.rows; r++)
|
|
4051
|
+
for (let col = 0; col < arr.columns; col++) {
|
|
4052
|
+
const x = arr.get(r, col);
|
|
4053
|
+
if (!skip(x)) values.push(x);
|
|
4054
|
+
}
|
|
4055
|
+
}
|
|
4056
|
+
return { ok: true, values };
|
|
4057
|
+
}
|
|
4058
|
+
function toCol(a, c) {
|
|
4059
|
+
const f = flatten(a, c);
|
|
4060
|
+
if (!f.ok) return f.e;
|
|
4061
|
+
if (f.values.length === 0) return FormulaValue.errorNA;
|
|
4062
|
+
const out = new ArrayValue(f.values.length, 1);
|
|
4063
|
+
for (let i = 0; i < f.values.length; i++) out.set(i, 0, f.values[i]);
|
|
4064
|
+
return FormulaValue.array(out);
|
|
4065
|
+
}
|
|
4066
|
+
function toRow(a, c) {
|
|
4067
|
+
const f = flatten(a, c);
|
|
4068
|
+
if (!f.ok) return f.e;
|
|
4069
|
+
if (f.values.length === 0) return FormulaValue.errorNA;
|
|
4070
|
+
const out = new ArrayValue(1, f.values.length);
|
|
4071
|
+
for (let i = 0; i < f.values.length; i++) out.set(0, i, f.values[i]);
|
|
4072
|
+
return FormulaValue.array(out);
|
|
4073
|
+
}
|
|
3583
4074
|
|
|
3584
4075
|
// src/function-registry.ts
|
|
3585
4076
|
var _default, _functions, _FunctionRegistry_instances, registerBuiltIns_fn;
|
|
@@ -4382,8 +4873,8 @@ writeResult_fn = function(e) {
|
|
|
4382
4873
|
for (let dc = 0; dc < cols && !collides; dc++) {
|
|
4383
4874
|
if (dr === 0 && dc === 0) continue;
|
|
4384
4875
|
const r = e.row + dr, c = e.col + dc;
|
|
4385
|
-
const
|
|
4386
|
-
if (__privateMethod(this, _RecalcEngine_instances, isOccupied_fn).call(this,
|
|
4876
|
+
const cellKey2 = keyOf(e.sheet, puredocsExcel.cellRefFromRowCol(r, c));
|
|
4877
|
+
if (__privateMethod(this, _RecalcEngine_instances, isOccupied_fn).call(this, cellKey2, e.sheetName, puredocsExcel.cellRefFromRowCol(r, c), anchorKey, prevSpill)) {
|
|
4387
4878
|
collides = true;
|
|
4388
4879
|
}
|
|
4389
4880
|
}
|
|
@@ -4404,9 +4895,9 @@ writeResult_fn = function(e) {
|
|
|
4404
4895
|
__privateGet(this, _model).setCellValue(e.sheetName, ref, arr.get(dr, dc).toObject());
|
|
4405
4896
|
changed.push({ sheet: e.sheet, row: r, col: c });
|
|
4406
4897
|
if (dr !== 0 || dc !== 0) {
|
|
4407
|
-
const
|
|
4408
|
-
newSpill.add(
|
|
4409
|
-
__privateGet(this, _spillOwner).set(
|
|
4898
|
+
const cellKey2 = keyOf(e.sheet, ref);
|
|
4899
|
+
newSpill.add(cellKey2);
|
|
4900
|
+
__privateGet(this, _spillOwner).set(cellKey2, anchorKey);
|
|
4410
4901
|
}
|
|
4411
4902
|
}
|
|
4412
4903
|
}
|
|
@@ -4426,11 +4917,11 @@ writeResult_fn = function(e) {
|
|
|
4426
4917
|
};
|
|
4427
4918
|
};
|
|
4428
4919
|
/** Whether a target cell already holds content that blocks a spill. */
|
|
4429
|
-
isOccupied_fn = function(
|
|
4430
|
-
if (__privateGet(this, _formulas).has(
|
|
4431
|
-
const owner = __privateGet(this, _spillOwner).get(
|
|
4920
|
+
isOccupied_fn = function(cellKey2, sheetName, ref, anchorKey, prevSpill) {
|
|
4921
|
+
if (__privateGet(this, _formulas).has(cellKey2) && cellKey2 !== anchorKey) return true;
|
|
4922
|
+
const owner = __privateGet(this, _spillOwner).get(cellKey2);
|
|
4432
4923
|
if (owner && owner !== anchorKey) return true;
|
|
4433
|
-
if (prevSpill.has(
|
|
4924
|
+
if (prevSpill.has(cellKey2)) return false;
|
|
4434
4925
|
const v = __privateGet(this, _model).getCellValue(sheetName, ref);
|
|
4435
4926
|
return v !== null && v !== void 0 && v !== "";
|
|
4436
4927
|
};
|
|
@@ -4438,10 +4929,10 @@ isOccupied_fn = function(cellKey, sheetName, ref, anchorKey, prevSpill) {
|
|
|
4438
4929
|
clearSpill_fn = function(anchorKey, changed) {
|
|
4439
4930
|
const spill = __privateGet(this, _spills).get(anchorKey);
|
|
4440
4931
|
if (!spill) return;
|
|
4441
|
-
for (const
|
|
4442
|
-
const cell = parseKey(
|
|
4932
|
+
for (const cellKey2 of spill) {
|
|
4933
|
+
const cell = parseKey(cellKey2);
|
|
4443
4934
|
__privateGet(this, _model).setCellValue(__privateGet(this, _sheetNames).get(cell.sheet) ?? cell.sheet, cell.ref, null);
|
|
4444
|
-
__privateGet(this, _spillOwner).delete(
|
|
4935
|
+
__privateGet(this, _spillOwner).delete(cellKey2);
|
|
4445
4936
|
changed.push({ sheet: cell.sheet, row: cell.row, col: cell.col });
|
|
4446
4937
|
}
|
|
4447
4938
|
__privateGet(this, _spills).delete(anchorKey);
|