@devmm/puredocs-excel-formula 1.0.1 → 1.0.2

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.js CHANGED
@@ -2356,6 +2356,7 @@ function datedif(a, c) {
2356
2356
  function registerLookup(r) {
2357
2357
  r.register("VLOOKUP", vlookup, 3, 4);
2358
2358
  r.register("HLOOKUP", hlookup, 3, 4);
2359
+ r.register("XLOOKUP", xlookup, 3, 6);
2359
2360
  r.register("LOOKUP", lookup, 2, 3);
2360
2361
  r.register("INDEX", index_, 2, 3);
2361
2362
  r.register("MATCH", match, 2, 3);
@@ -2432,6 +2433,104 @@ function hlookup(a, c) {
2432
2433
  }
2433
2434
  return best >= 0 ? tbl.get(rowIdx, best) : FormulaValue.errorNA;
2434
2435
  }
2436
+ function wildcardRegex(pattern) {
2437
+ let out = "";
2438
+ for (let i = 0; i < pattern.length; i++) {
2439
+ const ch = pattern[i];
2440
+ if (ch === "~" && i + 1 < pattern.length) {
2441
+ const next = pattern[++i];
2442
+ out += next.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2443
+ } else if (ch === "*") out += ".*";
2444
+ else if (ch === "?") out += ".";
2445
+ else out += ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2446
+ }
2447
+ return new RegExp(`^${out}$`, "i");
2448
+ }
2449
+ function findMatch(n, get, lookupVal, matchMode, searchMode) {
2450
+ if ((searchMode === 2 || searchMode === -2) && matchMode !== 2) {
2451
+ const at = searchMode === 2 ? get : (j) => get(n - 1 - j);
2452
+ let lo = 0, hi = n - 1, lastLE = -1, firstGE = -1;
2453
+ while (lo <= hi) {
2454
+ const mid2 = lo + hi >>> 1;
2455
+ const cmp = FormulaValue.compare(at(mid2), lookupVal);
2456
+ if (cmp === 0) return searchMode === 2 ? mid2 : n - 1 - mid2;
2457
+ if (cmp < 0) {
2458
+ lastLE = mid2;
2459
+ lo = mid2 + 1;
2460
+ } else {
2461
+ firstGE = mid2;
2462
+ hi = mid2 - 1;
2463
+ }
2464
+ }
2465
+ const idx = matchMode === -1 ? lastLE : matchMode === 1 ? firstGE : -1;
2466
+ return idx < 0 ? -1 : searchMode === 2 ? idx : n - 1 - idx;
2467
+ }
2468
+ const reverse = searchMode === -1;
2469
+ const order = reverse ? Array.from({ length: n }, (_, k) => n - 1 - k) : Array.from({ length: n }, (_, k) => k);
2470
+ if (matchMode === 2) {
2471
+ const re = wildcardRegex(lookupVal.asText());
2472
+ for (const i of order) if (re.test(get(i).asText())) return i;
2473
+ return -1;
2474
+ }
2475
+ if (matchMode === 0) {
2476
+ for (const i of order) if (FormulaValue.areEqual(get(i), lookupVal)) return i;
2477
+ return -1;
2478
+ }
2479
+ let best = -1;
2480
+ let bestVal = null;
2481
+ for (const i of order) {
2482
+ const v = get(i);
2483
+ const cmp = FormulaValue.compare(v, lookupVal);
2484
+ if (cmp === 0) return i;
2485
+ if (matchMode === -1 && cmp < 0) {
2486
+ if (bestVal === null || FormulaValue.compare(v, bestVal) > 0) {
2487
+ best = i;
2488
+ bestVal = v;
2489
+ }
2490
+ } else if (matchMode === 1 && cmp > 0) {
2491
+ if (bestVal === null || FormulaValue.compare(v, bestVal) < 0) {
2492
+ best = i;
2493
+ bestVal = v;
2494
+ }
2495
+ }
2496
+ }
2497
+ return best;
2498
+ }
2499
+ function xlookup(a, c) {
2500
+ const lookupVal = a[0].evaluate(c);
2501
+ if (lookupVal.isError) return lookupVal;
2502
+ const lookupRaw = a[1].evaluate(c);
2503
+ if (lookupRaw.isError) return lookupRaw;
2504
+ const returnRaw = a[2].evaluate(c);
2505
+ if (returnRaw.isError) return returnRaw;
2506
+ const matchMode = a.length > 4 ? num2(a, c, 4) : { ok: true, n: 0 };
2507
+ if (!matchMode.ok) return matchMode.e;
2508
+ const searchMode = a.length > 5 ? num2(a, c, 5) : { ok: true, n: 1 };
2509
+ if (!searchMode.ok) return searchMode.e;
2510
+ const mm = Math.trunc(matchMode.n), sm = Math.trunc(searchMode.n);
2511
+ const la = lookupRaw.isArray ? lookupRaw.arrayVal : ArrayValue.fromScalar(lookupRaw);
2512
+ if (la.rows > 1 && la.columns > 1) return FormulaValue.errorValue;
2513
+ const vertical = !(la.rows === 1 && la.columns > 1);
2514
+ const n = vertical ? la.rows : la.columns;
2515
+ const get = vertical ? (i) => la.get(i, 0) : (i) => la.get(0, i);
2516
+ const idx = findMatch(n, get, lookupVal, mm, sm);
2517
+ if (idx < 0) {
2518
+ return a.length > 3 ? a[3].evaluate(c) : FormulaValue.errorNA;
2519
+ }
2520
+ const ret = returnRaw.isArray ? returnRaw.arrayVal : ArrayValue.fromScalar(returnRaw);
2521
+ if (vertical) {
2522
+ if (ret.rows !== n) return FormulaValue.errorValue;
2523
+ if (ret.columns === 1) return ret.get(idx, 0);
2524
+ const out2 = new ArrayValue(1, ret.columns);
2525
+ for (let col = 0; col < ret.columns; col++) out2.set(0, col, ret.get(idx, col));
2526
+ return FormulaValue.array(out2);
2527
+ }
2528
+ if (ret.columns !== n) return FormulaValue.errorValue;
2529
+ if (ret.rows === 1) return ret.get(0, idx);
2530
+ const out = new ArrayValue(ret.rows, 1);
2531
+ for (let r = 0; r < ret.rows; r++) out.set(r, 0, ret.get(r, idx));
2532
+ return FormulaValue.array(out);
2533
+ }
2435
2534
  function index_(a, c) {
2436
2535
  const arrVal = a[0].evaluate(c);
2437
2536
  if (arrVal.isError) return arrVal;
@@ -2965,6 +3064,10 @@ function registerFinance(r) {
2965
3064
  r.register("PV", pv, 3, 5);
2966
3065
  r.register("NPV", npv, 2);
2967
3066
  r.register("IRR", irr, 1, 2);
3067
+ r.register("RATE", rate, 3, 6);
3068
+ r.register("NPER", nper, 3, 5);
3069
+ r.register("XNPV", xnpv, 3, 3);
3070
+ r.register("XIRR", xirr, 2, 3);
2968
3071
  }
2969
3072
  function arg(a, c, idx, dflt) {
2970
3073
  if (idx >= a.length) return { ok: true, n: dflt };
@@ -2972,17 +3075,17 @@ function arg(a, c, idx, dflt) {
2972
3075
  return r.ok ? { ok: true, n: r.value } : { ok: false, e: r.error };
2973
3076
  }
2974
3077
  function pmt(a, c) {
2975
- const rate = arg(a, c, 0, 0);
2976
- if (!rate.ok) return rate.e;
2977
- const nper = arg(a, c, 1, 0);
2978
- if (!nper.ok) return nper.e;
3078
+ const rate2 = arg(a, c, 0, 0);
3079
+ if (!rate2.ok) return rate2.e;
3080
+ const nper2 = arg(a, c, 1, 0);
3081
+ if (!nper2.ok) return nper2.e;
2979
3082
  const pvv = arg(a, c, 2, 0);
2980
3083
  if (!pvv.ok) return pvv.e;
2981
3084
  const fvv = arg(a, c, 3, 0);
2982
3085
  if (!fvv.ok) return fvv.e;
2983
3086
  const type = arg(a, c, 4, 0);
2984
3087
  if (!type.ok) return type.e;
2985
- const r = rate.n, n = nper.n, present = pvv.n, future = fvv.n, t = type.n;
3088
+ const r = rate2.n, n = nper2.n, present = pvv.n, future = fvv.n, t = type.n;
2986
3089
  if (n === 0) return FormulaValue.errorNum;
2987
3090
  if (r === 0) return FormulaValue.number(-(present + future) / n);
2988
3091
  const pow = Math.pow(1 + r, n);
@@ -2991,46 +3094,46 @@ function pmt(a, c) {
2991
3094
  return FormulaValue.number(payment);
2992
3095
  }
2993
3096
  function fv(a, c) {
2994
- const rate = arg(a, c, 0, 0);
2995
- if (!rate.ok) return rate.e;
2996
- const nper = arg(a, c, 1, 0);
2997
- if (!nper.ok) return nper.e;
3097
+ const rate2 = arg(a, c, 0, 0);
3098
+ if (!rate2.ok) return rate2.e;
3099
+ const nper2 = arg(a, c, 1, 0);
3100
+ if (!nper2.ok) return nper2.e;
2998
3101
  const pmtv = arg(a, c, 2, 0);
2999
3102
  if (!pmtv.ok) return pmtv.e;
3000
3103
  const pvv = arg(a, c, 3, 0);
3001
3104
  if (!pvv.ok) return pvv.e;
3002
3105
  const type = arg(a, c, 4, 0);
3003
3106
  if (!type.ok) return type.e;
3004
- const r = rate.n, n = nper.n, payment = pmtv.n, present = pvv.n, t = type.n;
3107
+ const r = rate2.n, n = nper2.n, payment = pmtv.n, present = pvv.n, t = type.n;
3005
3108
  if (r === 0) return FormulaValue.number(-(present + payment * n));
3006
3109
  const pow = Math.pow(1 + r, n);
3007
3110
  return FormulaValue.number(-(present * pow + payment * (1 + r * t) * (pow - 1) / r));
3008
3111
  }
3009
3112
  function pv(a, c) {
3010
- const rate = arg(a, c, 0, 0);
3011
- if (!rate.ok) return rate.e;
3012
- const nper = arg(a, c, 1, 0);
3013
- if (!nper.ok) return nper.e;
3113
+ const rate2 = arg(a, c, 0, 0);
3114
+ if (!rate2.ok) return rate2.e;
3115
+ const nper2 = arg(a, c, 1, 0);
3116
+ if (!nper2.ok) return nper2.e;
3014
3117
  const pmtv = arg(a, c, 2, 0);
3015
3118
  if (!pmtv.ok) return pmtv.e;
3016
3119
  const fvv = arg(a, c, 3, 0);
3017
3120
  if (!fvv.ok) return fvv.e;
3018
3121
  const type = arg(a, c, 4, 0);
3019
3122
  if (!type.ok) return type.e;
3020
- const r = rate.n, n = nper.n, payment = pmtv.n, future = fvv.n, t = type.n;
3123
+ const r = rate2.n, n = nper2.n, payment = pmtv.n, future = fvv.n, t = type.n;
3021
3124
  if (r === 0) return FormulaValue.number(-(future + payment * n));
3022
3125
  const pow = Math.pow(1 + r, n);
3023
3126
  return FormulaValue.number(-(future + payment * (1 + r * t) * (pow - 1) / r) / pow);
3024
3127
  }
3025
3128
  function npv(a, c) {
3026
- const rate = FormulaHelper.evalDouble(a[0], c);
3027
- if (!rate.ok) return rate.error;
3028
- if (rate.value === -1) return FormulaValue.errorDiv0;
3129
+ const rate2 = FormulaHelper.evalDouble(a[0], c);
3130
+ if (!rate2.ok) return rate2.error;
3131
+ if (rate2.value === -1) return FormulaValue.errorDiv0;
3029
3132
  const flows = FormulaHelper.collectNumbers(a.slice(1), c);
3030
3133
  if (!flows.ok) return flows.error;
3031
3134
  let total = 0;
3032
3135
  for (let i = 0; i < flows.values.length; i++) {
3033
- total += flows.values[i] / Math.pow(1 + rate.value, i + 1);
3136
+ total += flows.values[i] / Math.pow(1 + rate2.value, i + 1);
3034
3137
  }
3035
3138
  return FormulaValue.number(total);
3036
3139
  }
@@ -3045,27 +3148,177 @@ function irr(a, c) {
3045
3148
  if (!g.ok) return g.error;
3046
3149
  guess = g.value;
3047
3150
  }
3048
- const npvAt = (rate2) => {
3151
+ const npvAt = (rate3) => {
3049
3152
  let sum2 = 0;
3050
- for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 + rate2, i);
3153
+ for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 + rate3, i);
3051
3154
  return sum2;
3052
3155
  };
3053
- let rate = guess;
3156
+ let rate2 = guess;
3157
+ for (let iter = 0; iter < 100; iter++) {
3158
+ const f = npvAt(rate2);
3159
+ if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
3160
+ const h = 1e-6;
3161
+ const deriv = (npvAt(rate2 + h) - f) / h;
3162
+ if (deriv === 0) break;
3163
+ const next = rate2 - f / deriv;
3164
+ if (!isFinite(next) || next <= -1) break;
3165
+ if (Math.abs(next - rate2) < 1e-9) {
3166
+ rate2 = next;
3167
+ break;
3168
+ }
3169
+ rate2 = next;
3170
+ }
3171
+ if (Math.abs(npvAt(rate2)) < 1e-6) return FormulaValue.number(rate2);
3172
+ return FormulaValue.errorNum;
3173
+ }
3174
+ function tvm(r, n, pmt2, pv2, fv2, type) {
3175
+ if (r === 0) return pv2 + pmt2 * n + fv2;
3176
+ const pow = Math.pow(1 + r, n);
3177
+ return pv2 * pow + pmt2 * (1 + r * type) * (pow - 1) / r + fv2;
3178
+ }
3179
+ function rate(a, c) {
3180
+ const nper2 = arg(a, c, 0, 0);
3181
+ if (!nper2.ok) return nper2.e;
3182
+ const pmtv = arg(a, c, 1, 0);
3183
+ if (!pmtv.ok) return pmtv.e;
3184
+ const pvv = arg(a, c, 2, 0);
3185
+ if (!pvv.ok) return pvv.e;
3186
+ const fvv = arg(a, c, 3, 0);
3187
+ if (!fvv.ok) return fvv.e;
3188
+ const type = arg(a, c, 4, 0);
3189
+ if (!type.ok) return type.e;
3190
+ const gs = arg(a, c, 5, 0.1);
3191
+ if (!gs.ok) return gs.e;
3192
+ const n = nper2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
3193
+ if (n === 0) return FormulaValue.errorNum;
3194
+ let r = gs.n;
3054
3195
  for (let iter = 0; iter < 100; iter++) {
3055
- const f = npvAt(rate);
3056
- if (Math.abs(f) < 1e-7) return FormulaValue.number(rate);
3196
+ const f = tvm(r, n, pmt2, pv2, fv2, t);
3197
+ if (Math.abs(f) < 1e-8) return FormulaValue.number(r);
3057
3198
  const h = 1e-6;
3058
- const deriv = (npvAt(rate + h) - f) / h;
3199
+ const deriv = (tvm(r + h, n, pmt2, pv2, fv2, t) - f) / h;
3059
3200
  if (deriv === 0) break;
3060
- const next = rate - f / deriv;
3201
+ const next = r - f / deriv;
3061
3202
  if (!isFinite(next) || next <= -1) break;
3062
- if (Math.abs(next - rate) < 1e-9) {
3063
- rate = next;
3203
+ if (Math.abs(next - r) < 1e-10) {
3204
+ r = next;
3064
3205
  break;
3065
3206
  }
3066
- rate = next;
3207
+ r = next;
3067
3208
  }
3068
- if (Math.abs(npvAt(rate)) < 1e-6) return FormulaValue.number(rate);
3209
+ if (Math.abs(tvm(r, n, pmt2, pv2, fv2, t)) < 1e-6) return FormulaValue.number(r);
3210
+ return FormulaValue.errorNum;
3211
+ }
3212
+ function nper(a, c) {
3213
+ const rate2 = arg(a, c, 0, 0);
3214
+ if (!rate2.ok) return rate2.e;
3215
+ const pmtv = arg(a, c, 1, 0);
3216
+ if (!pmtv.ok) return pmtv.e;
3217
+ const pvv = arg(a, c, 2, 0);
3218
+ if (!pvv.ok) return pvv.e;
3219
+ const fvv = arg(a, c, 3, 0);
3220
+ if (!fvv.ok) return fvv.e;
3221
+ const type = arg(a, c, 4, 0);
3222
+ if (!type.ok) return type.e;
3223
+ const r = rate2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
3224
+ if (r === 0) {
3225
+ if (pmt2 === 0) return FormulaValue.errorNum;
3226
+ return FormulaValue.number(-(pv2 + fv2) / pmt2);
3227
+ }
3228
+ const adj = pmt2 * (1 + r * t);
3229
+ const num5 = adj - fv2 * r;
3230
+ const den = adj + pv2 * r;
3231
+ if (den === 0 || num5 / den <= 0) return FormulaValue.errorNum;
3232
+ const result = Math.log(num5 / den) / Math.log(1 + r);
3233
+ if (!isFinite(result)) return FormulaValue.errorNum;
3234
+ return FormulaValue.number(result);
3235
+ }
3236
+ function flatNumbers(node, c) {
3237
+ const v = node.evaluate(c);
3238
+ if (v.isError) return { ok: false, e: v };
3239
+ const out = [];
3240
+ const push = (item) => {
3241
+ if (item.isError) return item;
3242
+ const d = item.tryAsDouble();
3243
+ if (!d.ok) return FormulaValue.errorValue;
3244
+ out.push(d.value);
3245
+ return null;
3246
+ };
3247
+ if (v.isArray) {
3248
+ for (const item of v.arrayVal.values()) {
3249
+ const err = push(item);
3250
+ if (err) return { ok: false, e: err };
3251
+ }
3252
+ } else {
3253
+ const err = push(v);
3254
+ if (err) return { ok: false, e: err };
3255
+ }
3256
+ return { ok: true, values: out };
3257
+ }
3258
+ function xnpvAt(rate2, values, days2) {
3259
+ let sum2 = 0;
3260
+ for (let i = 0; i < values.length; i++) {
3261
+ sum2 += values[i] / Math.pow(1 + rate2, days2[i] / 365);
3262
+ }
3263
+ return sum2;
3264
+ }
3265
+ function xnpv(a, c) {
3266
+ const rateRes = FormulaHelper.evalDouble(a[0], c);
3267
+ if (!rateRes.ok) return rateRes.error;
3268
+ const rate2 = rateRes.value;
3269
+ if (rate2 <= -1) return FormulaValue.errorNum;
3270
+ const valsRes = flatNumbers(a[1], c);
3271
+ if (!valsRes.ok) return valsRes.e;
3272
+ const datesRes = flatNumbers(a[2], c);
3273
+ if (!datesRes.ok) return datesRes.e;
3274
+ const values = valsRes.values;
3275
+ const dates = datesRes.values;
3276
+ if (values.length === 0 || values.length !== dates.length) return FormulaValue.errorNum;
3277
+ const base = Math.trunc(dates[0]);
3278
+ const days2 = dates.map((d) => Math.trunc(d) - base);
3279
+ if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
3280
+ return FormulaValue.number(xnpvAt(rate2, values, days2));
3281
+ }
3282
+ function xirr(a, c) {
3283
+ const valsRes = flatNumbers(a[0], c);
3284
+ if (!valsRes.ok) return valsRes.e;
3285
+ const datesRes = flatNumbers(a[1], c);
3286
+ if (!datesRes.ok) return datesRes.e;
3287
+ const values = valsRes.values;
3288
+ const dates = datesRes.values;
3289
+ if (values.length < 2 || values.length !== dates.length) return FormulaValue.errorNum;
3290
+ let guess = 0.1;
3291
+ if (a.length > 2) {
3292
+ const g = FormulaHelper.evalDouble(a[2], c);
3293
+ if (!g.ok) return g.error;
3294
+ guess = g.value;
3295
+ }
3296
+ const base = Math.trunc(dates[0]);
3297
+ const days2 = dates.map((d) => Math.trunc(d) - base);
3298
+ if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
3299
+ const derivAt = (rate3) => {
3300
+ let sum2 = 0;
3301
+ for (let i = 0; i < values.length; i++) {
3302
+ const e = days2[i] / 365;
3303
+ sum2 += -e * values[i] / Math.pow(1 + rate3, e + 1);
3304
+ }
3305
+ return sum2;
3306
+ };
3307
+ let rate2 = guess;
3308
+ for (let iter = 0; iter < 100; iter++) {
3309
+ const f = xnpvAt(rate2, values, days2);
3310
+ if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
3311
+ const deriv = derivAt(rate2);
3312
+ if (deriv === 0) break;
3313
+ const next = rate2 - f / deriv;
3314
+ if (!isFinite(next) || next <= -1) break;
3315
+ if (Math.abs(next - rate2) < 1e-9) {
3316
+ rate2 = next;
3317
+ break;
3318
+ }
3319
+ rate2 = next;
3320
+ }
3321
+ if (Math.abs(xnpvAt(rate2, values, days2)) < 1e-6) return FormulaValue.number(rate2);
3069
3322
  return FormulaValue.errorNum;
3070
3323
  }
3071
3324
 
@@ -3403,6 +3656,7 @@ function registerArray(r) {
3403
3656
  r.register("SEQUENCE", sequence, 1, 4);
3404
3657
  r.register("UNIQUE", unique, 1, 3);
3405
3658
  r.register("SORT", sort, 1, 4);
3659
+ r.register("SORTBY", sortBy, 2);
3406
3660
  r.register("FILTER", filter, 2, 3);
3407
3661
  r.register("MMULT", mmult, 2, 2);
3408
3662
  r.register("TEXTSPLIT", textSplit, 2, 6);
@@ -3497,6 +3751,58 @@ function sort(a, c) {
3497
3751
  const out = fromRows(sorted);
3498
3752
  return byCol2 ? FormulaValue.array(out.arrayVal.transpose()) : out;
3499
3753
  }
3754
+ function sortBy(a, c) {
3755
+ const v = a[0].evaluate(c);
3756
+ if (v.isError) return v;
3757
+ const data = asArray2(v);
3758
+ const keys = [];
3759
+ let i = 1;
3760
+ while (i < a.length) {
3761
+ const byVal = a[i].evaluate(c);
3762
+ if (byVal.isError) return byVal;
3763
+ i++;
3764
+ let dir = 1;
3765
+ if (i < a.length) {
3766
+ const maybeOrder = a[i].evaluate(c);
3767
+ if (maybeOrder.isError) return maybeOrder;
3768
+ if (!maybeOrder.isArray && maybeOrder.isNumeric) {
3769
+ const d = maybeOrder.tryAsDouble();
3770
+ if (d.ok) {
3771
+ dir = d.value < 0 ? -1 : 1;
3772
+ i++;
3773
+ }
3774
+ }
3775
+ }
3776
+ keys.push({ vals: [...asArray2(byVal).values()], dir });
3777
+ }
3778
+ if (keys.length === 0) return FormulaValue.errorValue;
3779
+ const n = keys[0].vals.length;
3780
+ if (keys.some((k) => k.vals.length !== n)) return FormulaValue.errorValue;
3781
+ const byRow2 = n === data.rows;
3782
+ const byColumn = !byRow2 && n === data.columns;
3783
+ if (!byRow2 && !byColumn) return FormulaValue.errorValue;
3784
+ const perm = Array.from({ length: n }, (_, k) => k);
3785
+ perm.sort((x, y) => {
3786
+ for (const key of keys) {
3787
+ const cmp = FormulaValue.compare(key.vals[x], key.vals[y]) * key.dir;
3788
+ if (cmp !== 0) return cmp;
3789
+ }
3790
+ return x - y;
3791
+ });
3792
+ const out = new ArrayValue(data.rows, data.columns);
3793
+ if (byRow2) {
3794
+ for (let r = 0; r < data.rows; r++) {
3795
+ const src = perm[r];
3796
+ for (let col = 0; col < data.columns; col++) out.set(r, col, data.get(src, col));
3797
+ }
3798
+ } else {
3799
+ for (let col = 0; col < data.columns; col++) {
3800
+ const src = perm[col];
3801
+ for (let r = 0; r < data.rows; r++) out.set(r, col, data.get(r, src));
3802
+ }
3803
+ }
3804
+ return FormulaValue.array(out);
3805
+ }
3500
3806
  function filter(a, c) {
3501
3807
  const v = a[0].evaluate(c);
3502
3808
  if (v.isError) return v;