@odoo/o-spreadsheet 18.1.21 → 18.1.22
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/o-spreadsheet.cjs.js +202 -114
- package/dist/o-spreadsheet.esm.js +202 -114
- package/dist/o-spreadsheet.iife.js +202 -114
- package/dist/o-spreadsheet.iife.min.js +367 -367
- package/dist/o_spreadsheet.xml +5 -5
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.22
|
|
6
|
+
* @date 2025-05-26T12:35:56.145Z
|
|
7
|
+
* @hash ff4b0ba
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -4142,6 +4142,113 @@ function transposeMatrix(matrix) {
|
|
|
4142
4142
|
}
|
|
4143
4143
|
return generateMatrix(matrix[0].length, matrix.length, (i, j) => matrix[j][i]);
|
|
4144
4144
|
}
|
|
4145
|
+
/**
|
|
4146
|
+
* Enables a formula function to accept matrix or vector inputs instead of simple value, computing results across multiple dimensions.
|
|
4147
|
+
*
|
|
4148
|
+
* ```
|
|
4149
|
+
* / |‾ ‾| \ |‾ ‾|
|
|
4150
|
+
* | | [A] | | | compute(A, D, E), compute(A, D, F), compute(A, D, G) |
|
|
4151
|
+
* applyVectorization| compute, | [B], D, [E, F, G] | | <=> | compute(B, D, E), compute(B, D, F), compute(B, D, G) |
|
|
4152
|
+
* | | [C] | | | compute(C, D, E), compute(C, D, F), compute(C, D, G) |
|
|
4153
|
+
* \ |_ _| / |_ _|
|
|
4154
|
+
* ```
|
|
4155
|
+
*
|
|
4156
|
+
* By default, all arguments are vectorized. To control which arguments are vectorized,
|
|
4157
|
+
* pass an `acceptToVectorize` boolean array of the same length as `args`:
|
|
4158
|
+
* - `true` enables vectorization for that argument
|
|
4159
|
+
* - `false` disables vectorization for that argument
|
|
4160
|
+
*
|
|
4161
|
+
* For example, with `[true, true, false]` on previous example you get:
|
|
4162
|
+
*
|
|
4163
|
+
* ```
|
|
4164
|
+
* |‾ ‾|
|
|
4165
|
+
* | compute(A, D, [E, F, G]) |
|
|
4166
|
+
* | compute(B, D, [E, F, G]) |
|
|
4167
|
+
* | compute(C, D, [E, F, G]) |
|
|
4168
|
+
* |_ _|
|
|
4169
|
+
* ```
|
|
4170
|
+
*
|
|
4171
|
+
* @remarks
|
|
4172
|
+
* This helper is automatically applied (by default) to **all** `compute` functions
|
|
4173
|
+
* across the various spreadsheet formula modules:
|
|
4174
|
+
* - If an argument is declared **scalar** (not `"range"`), it is vectorized.
|
|
4175
|
+
* - If **all** arguments are declared **ranges**, no vectorization occurs.
|
|
4176
|
+
* - e.g. `SUM(A1:B2)` returns a 1×1 sum over the range.
|
|
4177
|
+
* - e.g. `COS(A1:B2)` over `A1:B2` returns a 2×2 element-wise result.
|
|
4178
|
+
* - For special behaviors (e.g. the `IF` function), you may declare all arguments
|
|
4179
|
+
* as ranges and invoke this helper directly within your `compute` implementation.
|
|
4180
|
+
*/
|
|
4181
|
+
function applyVectorization(formula, args, acceptToVectorize = undefined) {
|
|
4182
|
+
let countVectorizedCol = 1;
|
|
4183
|
+
let countVectorizedRow = 1;
|
|
4184
|
+
let vectorizedColLimit = Infinity;
|
|
4185
|
+
let vectorizedRowLimit = Infinity;
|
|
4186
|
+
let vectorArgsType = undefined;
|
|
4187
|
+
for (let i = 0; i < args.length; i++) {
|
|
4188
|
+
const arg = args[i];
|
|
4189
|
+
if (isMatrix(arg) && (acceptToVectorize === undefined || acceptToVectorize[i])) {
|
|
4190
|
+
const nColumns = arg.length;
|
|
4191
|
+
const nRows = arg[0].length;
|
|
4192
|
+
if (nColumns !== 1 || nRows !== 1) {
|
|
4193
|
+
vectorArgsType ??= new Array(args.length);
|
|
4194
|
+
if (nColumns !== 1 && nRows !== 1) {
|
|
4195
|
+
vectorArgsType[i] = "matrix";
|
|
4196
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4197
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4198
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4199
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4200
|
+
}
|
|
4201
|
+
else if (nColumns !== 1) {
|
|
4202
|
+
vectorArgsType[i] = "horizontal";
|
|
4203
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4204
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4205
|
+
}
|
|
4206
|
+
else if (nRows !== 1) {
|
|
4207
|
+
vectorArgsType[i] = "vertical";
|
|
4208
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4209
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4210
|
+
}
|
|
4211
|
+
}
|
|
4212
|
+
else {
|
|
4213
|
+
args[i] = arg[0][0];
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
if (countVectorizedCol === 1 && countVectorizedRow === 1) {
|
|
4218
|
+
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
4219
|
+
return formula(...args);
|
|
4220
|
+
}
|
|
4221
|
+
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
4222
|
+
switch (vectorArgsType?.[index]) {
|
|
4223
|
+
case "matrix":
|
|
4224
|
+
return arg[i][j];
|
|
4225
|
+
case "horizontal":
|
|
4226
|
+
return arg[i][0];
|
|
4227
|
+
case "vertical":
|
|
4228
|
+
return arg[0][j];
|
|
4229
|
+
case undefined:
|
|
4230
|
+
return arg;
|
|
4231
|
+
}
|
|
4232
|
+
});
|
|
4233
|
+
return generateMatrix(countVectorizedCol, countVectorizedRow, (col, row) => {
|
|
4234
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
4235
|
+
return new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
4236
|
+
}
|
|
4237
|
+
const singleCellComputeResult = formula(...getArgOffset(col, row));
|
|
4238
|
+
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
4239
|
+
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
4240
|
+
// we won't be able to return the values.
|
|
4241
|
+
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
4242
|
+
// create an array with these parts.
|
|
4243
|
+
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
4244
|
+
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
4245
|
+
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
4246
|
+
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
4247
|
+
return isMatrix(singleCellComputeResult)
|
|
4248
|
+
? singleCellComputeResult[0][0]
|
|
4249
|
+
: singleCellComputeResult;
|
|
4250
|
+
});
|
|
4251
|
+
}
|
|
4145
4252
|
// -----------------------------------------------------------------------------
|
|
4146
4253
|
// CONDITIONAL EXPLORE FUNCTIONS
|
|
4147
4254
|
// -----------------------------------------------------------------------------
|
|
@@ -7433,14 +7540,20 @@ function multiplyMatrices(matrix1, matrix2) {
|
|
|
7433
7540
|
/**
|
|
7434
7541
|
* Return the input if it's a scalar or the first element of the input if it's a matrix.
|
|
7435
7542
|
*/
|
|
7436
|
-
function toScalar(
|
|
7437
|
-
if (!isMatrix(
|
|
7438
|
-
return
|
|
7543
|
+
function toScalar(arg) {
|
|
7544
|
+
if (!isMatrix(arg)) {
|
|
7545
|
+
return arg;
|
|
7439
7546
|
}
|
|
7440
|
-
if (
|
|
7547
|
+
if (!isSingleElementMatrix(arg)) {
|
|
7441
7548
|
throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
|
|
7442
7549
|
}
|
|
7443
|
-
return
|
|
7550
|
+
return arg[0][0];
|
|
7551
|
+
}
|
|
7552
|
+
function isSingleElementMatrix(matrix) {
|
|
7553
|
+
return matrix.length === 1 && matrix[0].length === 1;
|
|
7554
|
+
}
|
|
7555
|
+
function isMultipleElementMatrix(arg) {
|
|
7556
|
+
return isMatrix(arg) && !isSingleElementMatrix(arg);
|
|
7444
7557
|
}
|
|
7445
7558
|
|
|
7446
7559
|
function assertSameNumberOfElements(...args) {
|
|
@@ -15284,7 +15397,7 @@ const FILTER = {
|
|
|
15284
15397
|
}
|
|
15285
15398
|
return mode === "row" ? transposeMatrix(result) : result;
|
|
15286
15399
|
},
|
|
15287
|
-
isExported:
|
|
15400
|
+
isExported: false,
|
|
15288
15401
|
};
|
|
15289
15402
|
// -----------------------------------------------------------------------------
|
|
15290
15403
|
// SORT
|
|
@@ -18415,16 +18528,23 @@ const FALSE = {
|
|
|
18415
18528
|
const IF = {
|
|
18416
18529
|
description: _t("Returns value depending on logical expression."),
|
|
18417
18530
|
args: [
|
|
18418
|
-
arg("logical_expression (boolean)", _t("An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.")),
|
|
18419
|
-
arg("value_if_true (any)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
18420
|
-
arg("value_if_false (any, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
18531
|
+
arg("logical_expression (boolean, range<boolean>)", _t("An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.")),
|
|
18532
|
+
arg("value_if_true (any, range)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
18533
|
+
arg("value_if_false (any, range, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
18421
18534
|
],
|
|
18422
18535
|
compute: function (logicalExpression, valueIfTrue, valueIfFalse) {
|
|
18423
|
-
|
|
18536
|
+
if (isMultipleElementMatrix(logicalExpression)) {
|
|
18537
|
+
return applyVectorization(IF.compute, [logicalExpression, valueIfTrue, valueIfFalse]);
|
|
18538
|
+
}
|
|
18539
|
+
let result = toBoolean(toScalar(logicalExpression)) ? valueIfTrue : valueIfFalse;
|
|
18540
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18541
|
+
if (!isMultipleElementMatrix(result)) {
|
|
18542
|
+
result = toScalar(result);
|
|
18543
|
+
}
|
|
18424
18544
|
if (result === undefined) {
|
|
18425
18545
|
return { value: "" };
|
|
18426
18546
|
}
|
|
18427
|
-
if (result.value === null) {
|
|
18547
|
+
if (!isMatrix(result) && result.value === null) {
|
|
18428
18548
|
return { ...result, value: "" };
|
|
18429
18549
|
}
|
|
18430
18550
|
return result;
|
|
@@ -18437,15 +18557,22 @@ const IF = {
|
|
|
18437
18557
|
const IFERROR = {
|
|
18438
18558
|
description: _t("Value if it is not an error, otherwise 2nd argument."),
|
|
18439
18559
|
args: [
|
|
18440
|
-
arg("value (any)", _t("The value to return if value itself is not an error.")),
|
|
18441
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
18560
|
+
arg("value (any, range)", _t("The value to return if value itself is not an error.")),
|
|
18561
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
18442
18562
|
],
|
|
18443
|
-
compute: function (value, valueIfError
|
|
18444
|
-
|
|
18563
|
+
compute: function (value, valueIfError) {
|
|
18564
|
+
if (isMultipleElementMatrix(value)) {
|
|
18565
|
+
return applyVectorization(IFERROR.compute, [value, valueIfError]);
|
|
18566
|
+
}
|
|
18567
|
+
let result = isEvaluationError(toScalar(value)?.value) ? valueIfError : value;
|
|
18568
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18569
|
+
if (!isMultipleElementMatrix(result)) {
|
|
18570
|
+
result = toScalar(result);
|
|
18571
|
+
}
|
|
18445
18572
|
if (result === undefined) {
|
|
18446
18573
|
return { value: "" };
|
|
18447
18574
|
}
|
|
18448
|
-
if (result.value === null) {
|
|
18575
|
+
if (!isMatrix(result) && result.value === null) {
|
|
18449
18576
|
return { ...result, value: "" };
|
|
18450
18577
|
}
|
|
18451
18578
|
return result;
|
|
@@ -18458,15 +18585,22 @@ const IFERROR = {
|
|
|
18458
18585
|
const IFNA = {
|
|
18459
18586
|
description: _t("Value if it is not an #N/A error, otherwise 2nd argument."),
|
|
18460
18587
|
args: [
|
|
18461
|
-
arg("value (any)", _t("The value to return if value itself is not #N/A an error.")),
|
|
18462
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
18588
|
+
arg("value (any, range)", _t("The value to return if value itself is not #N/A an error.")),
|
|
18589
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
18463
18590
|
],
|
|
18464
|
-
compute: function (value, valueIfError
|
|
18465
|
-
|
|
18591
|
+
compute: function (value, valueIfError) {
|
|
18592
|
+
if (isMultipleElementMatrix(value)) {
|
|
18593
|
+
return applyVectorization(IFNA.compute, [value, valueIfError]);
|
|
18594
|
+
}
|
|
18595
|
+
let result = toScalar(value)?.value === CellErrorType.NotAvailable ? valueIfError : value;
|
|
18596
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18597
|
+
if (!isMultipleElementMatrix(result)) {
|
|
18598
|
+
result = toScalar(result);
|
|
18599
|
+
}
|
|
18466
18600
|
if (result === undefined) {
|
|
18467
18601
|
return { value: "" };
|
|
18468
18602
|
}
|
|
18469
|
-
if (result.value === null) {
|
|
18603
|
+
if (!isMatrix(result) && result.value === null) {
|
|
18470
18604
|
return { ...result, value: "" };
|
|
18471
18605
|
}
|
|
18472
18606
|
return result;
|
|
@@ -18479,23 +18613,31 @@ const IFNA = {
|
|
|
18479
18613
|
const IFS = {
|
|
18480
18614
|
description: _t("Returns a value depending on multiple logical expressions."),
|
|
18481
18615
|
args: [
|
|
18482
|
-
arg("condition1 (boolean)", _t("The first condition to be evaluated. This can be a boolean, a number, an array, or a reference to any of those.")),
|
|
18483
|
-
arg("value1 (any)", _t("The returned value if condition1 is TRUE.")),
|
|
18484
|
-
arg("condition2 (boolean, any, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
18485
|
-
arg("value2 (any, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
18616
|
+
arg("condition1 (boolean, range<boolean>)", _t("The first condition to be evaluated. This can be a boolean, a number, an array, or a reference to any of those.")),
|
|
18617
|
+
arg("value1 (any, range)", _t("The returned value if condition1 is TRUE.")),
|
|
18618
|
+
arg("condition2 (boolean, any, range, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
18619
|
+
arg("value2 (any, range, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
18486
18620
|
],
|
|
18487
18621
|
compute: function (...values) {
|
|
18488
18622
|
assert(() => values.length % 2 === 0, _t("Wrong number of arguments. Expected an even number of arguments."));
|
|
18489
|
-
|
|
18490
|
-
if (
|
|
18491
|
-
|
|
18492
|
-
|
|
18623
|
+
while (values.length > 0) {
|
|
18624
|
+
if (isMultipleElementMatrix(values[0])) {
|
|
18625
|
+
return applyVectorization(IFS.compute, values);
|
|
18626
|
+
}
|
|
18627
|
+
const condition = toBoolean(toScalar(values.shift()));
|
|
18628
|
+
let valueIfTrue = values.shift();
|
|
18629
|
+
if (condition) {
|
|
18630
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18631
|
+
if (!isMultipleElementMatrix(valueIfTrue)) {
|
|
18632
|
+
valueIfTrue = toScalar(valueIfTrue);
|
|
18633
|
+
}
|
|
18634
|
+
if (valueIfTrue === undefined) {
|
|
18493
18635
|
return { value: "" };
|
|
18494
18636
|
}
|
|
18495
|
-
if (
|
|
18496
|
-
return { ...
|
|
18637
|
+
if (!isMatrix(valueIfTrue) && valueIfTrue.value === null) {
|
|
18638
|
+
return { ...valueIfTrue, value: "" };
|
|
18497
18639
|
}
|
|
18498
|
-
return
|
|
18640
|
+
return valueIfTrue;
|
|
18499
18641
|
}
|
|
18500
18642
|
}
|
|
18501
18643
|
return new EvaluationError(_t("No match."));
|
|
@@ -20157,7 +20299,7 @@ const SPLIT = {
|
|
|
20157
20299
|
}
|
|
20158
20300
|
return transposeMatrix([result]);
|
|
20159
20301
|
},
|
|
20160
|
-
isExported:
|
|
20302
|
+
isExported: false,
|
|
20161
20303
|
};
|
|
20162
20304
|
// -----------------------------------------------------------------------------
|
|
20163
20305
|
// SUBSTITUTE
|
|
@@ -20350,86 +20492,21 @@ for (let category of categories) {
|
|
|
20350
20492
|
functionRegistry.add(name, { isExported: false, ...addDescr });
|
|
20351
20493
|
}
|
|
20352
20494
|
}
|
|
20353
|
-
|
|
20495
|
+
//------------------------------------------------------------------------------
|
|
20496
|
+
// CREATE COMPUTE FUNCTION
|
|
20497
|
+
//------------------------------------------------------------------------------
|
|
20354
20498
|
function createComputeFunction(descr, functionName) {
|
|
20355
20499
|
function vectorizedCompute(...args) {
|
|
20356
|
-
|
|
20357
|
-
let countVectorizableRow = 1;
|
|
20358
|
-
let vectorizableColLimit = Infinity;
|
|
20359
|
-
let vectorizableRowLimit = Infinity;
|
|
20360
|
-
let vectorArgsType = undefined;
|
|
20361
|
-
//#region Compute vectorisation limits
|
|
20500
|
+
const acceptToVectorize = [];
|
|
20362
20501
|
for (let i = 0; i < args.length; i++) {
|
|
20363
20502
|
const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
|
|
20364
20503
|
const arg = args[i];
|
|
20365
|
-
if (isMatrix(arg) && !argDefinition.acceptMatrix) {
|
|
20366
|
-
// if argDefinition does not accept a matrix but arg is still a matrix
|
|
20367
|
-
// --> triggers the arguments vectorization
|
|
20368
|
-
const nColumns = arg.length;
|
|
20369
|
-
const nRows = arg[0].length;
|
|
20370
|
-
if (nColumns !== 1 || nRows !== 1) {
|
|
20371
|
-
vectorArgsType ??= new Array(args.length);
|
|
20372
|
-
if (nColumns !== 1 && nRows !== 1) {
|
|
20373
|
-
vectorArgsType[i] = "matrix";
|
|
20374
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
20375
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
20376
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
20377
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
20378
|
-
}
|
|
20379
|
-
else if (nColumns !== 1) {
|
|
20380
|
-
vectorArgsType[i] = "horizontal";
|
|
20381
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
20382
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
20383
|
-
}
|
|
20384
|
-
else if (nRows !== 1) {
|
|
20385
|
-
vectorArgsType[i] = "vertical";
|
|
20386
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
20387
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
20388
|
-
}
|
|
20389
|
-
}
|
|
20390
|
-
else {
|
|
20391
|
-
args[i] = arg[0][0];
|
|
20392
|
-
}
|
|
20393
|
-
}
|
|
20394
20504
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
20395
20505
|
throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
|
|
20396
20506
|
}
|
|
20507
|
+
acceptToVectorize.push(!argDefinition.acceptMatrix);
|
|
20397
20508
|
}
|
|
20398
|
-
|
|
20399
|
-
if (countVectorizableCol === 1 && countVectorizableRow === 1) {
|
|
20400
|
-
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
20401
|
-
return errorHandlingCompute.apply(this, args);
|
|
20402
|
-
}
|
|
20403
|
-
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
20404
|
-
switch (vectorArgsType?.[index]) {
|
|
20405
|
-
case "matrix":
|
|
20406
|
-
return arg[i][j];
|
|
20407
|
-
case "horizontal":
|
|
20408
|
-
return arg[i][0];
|
|
20409
|
-
case "vertical":
|
|
20410
|
-
return arg[0][j];
|
|
20411
|
-
case undefined:
|
|
20412
|
-
return arg;
|
|
20413
|
-
}
|
|
20414
|
-
});
|
|
20415
|
-
return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
|
|
20416
|
-
if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
|
|
20417
|
-
return notAvailableError;
|
|
20418
|
-
}
|
|
20419
|
-
const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
|
|
20420
|
-
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
20421
|
-
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
20422
|
-
// we won't be able to return the values.
|
|
20423
|
-
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
20424
|
-
// create an array with these parts.
|
|
20425
|
-
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
20426
|
-
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
20427
|
-
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
20428
|
-
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
20429
|
-
return isMatrix(singleCellComputeResult)
|
|
20430
|
-
? singleCellComputeResult[0][0]
|
|
20431
|
-
: singleCellComputeResult;
|
|
20432
|
-
});
|
|
20509
|
+
return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
|
|
20433
20510
|
}
|
|
20434
20511
|
function errorHandlingCompute(...args) {
|
|
20435
20512
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -21274,7 +21351,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
21274
21351
|
proposals &&
|
|
21275
21352
|
!["ARG_SEPARATOR", "LEFT_PAREN", "OPERATOR"].includes(tokenAtCursor.type)) {
|
|
21276
21353
|
const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
|
|
21277
|
-
if (!exactMatch || filteredProposals.length
|
|
21354
|
+
if (!exactMatch || filteredProposals.length) {
|
|
21278
21355
|
proposals = filteredProposals;
|
|
21279
21356
|
}
|
|
21280
21357
|
}
|
|
@@ -46141,7 +46218,9 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
46141
46218
|
return dimension.order === "asc" ? -1 : 1;
|
|
46142
46219
|
}
|
|
46143
46220
|
if (dimension.type === "integer" || dimension.type === "datetime") {
|
|
46144
|
-
return dimension.order === "asc"
|
|
46221
|
+
return dimension.order === "asc"
|
|
46222
|
+
? toNumber(a, DEFAULT_LOCALE) - toNumber(b, DEFAULT_LOCALE)
|
|
46223
|
+
: toNumber(b, DEFAULT_LOCALE) - toNumber(a, DEFAULT_LOCALE);
|
|
46145
46224
|
}
|
|
46146
46225
|
return dimension.order === "asc" ? a.localeCompare(b) : b.localeCompare(a);
|
|
46147
46226
|
}
|
|
@@ -48907,8 +48986,7 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
48907
48986
|
if (!spreader) {
|
|
48908
48987
|
return undefined;
|
|
48909
48988
|
}
|
|
48910
|
-
|
|
48911
|
-
return cell?.content;
|
|
48989
|
+
return this.getters.getCellText(spreader, { showFormula: true });
|
|
48912
48990
|
}
|
|
48913
48991
|
get currentEditedCell() {
|
|
48914
48992
|
return {
|
|
@@ -51719,6 +51797,7 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51719
51797
|
const friction = 0.95;
|
|
51720
51798
|
const verticalScrollFactor = 1;
|
|
51721
51799
|
const horizontalScrollFactor = 1;
|
|
51800
|
+
const resetTimeoutDuration = 100;
|
|
51722
51801
|
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
51723
51802
|
let lastX = 0;
|
|
51724
51803
|
let lastY = 0;
|
|
@@ -51726,6 +51805,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
51726
51805
|
let velocityY = 0;
|
|
51727
51806
|
let isMouseDown = false;
|
|
51728
51807
|
let lastTime = 0;
|
|
51808
|
+
let resetTimeout = null;
|
|
51729
51809
|
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
51730
51810
|
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
51731
51811
|
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
@@ -51738,6 +51818,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
51738
51818
|
function onTouchMove(event) {
|
|
51739
51819
|
if (!isMouseDown)
|
|
51740
51820
|
return;
|
|
51821
|
+
if (resetTimeout) {
|
|
51822
|
+
clearTimeout(resetTimeout);
|
|
51823
|
+
resetTimeout = null;
|
|
51824
|
+
}
|
|
51741
51825
|
const currentTime = Date.now();
|
|
51742
51826
|
const { clientX, clientY } = event.touches[0];
|
|
51743
51827
|
let deltaX = lastX - clientX;
|
|
@@ -51754,6 +51838,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
51754
51838
|
}
|
|
51755
51839
|
event.stopPropagation();
|
|
51756
51840
|
}
|
|
51841
|
+
resetTimeout = setTimeout(() => {
|
|
51842
|
+
velocityX = 0;
|
|
51843
|
+
velocityY = 0;
|
|
51844
|
+
}, resetTimeoutDuration);
|
|
51757
51845
|
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
51758
51846
|
}
|
|
51759
51847
|
function onTouchEnd(ev) {
|
|
@@ -76349,6 +76437,6 @@ exports.tokenColors = tokenColors;
|
|
|
76349
76437
|
exports.tokenize = tokenize;
|
|
76350
76438
|
|
|
76351
76439
|
|
|
76352
|
-
__info__.version = "18.1.
|
|
76353
|
-
__info__.date = "2025-05-
|
|
76354
|
-
__info__.hash = "
|
|
76440
|
+
__info__.version = "18.1.22";
|
|
76441
|
+
__info__.date = "2025-05-26T12:35:56.145Z";
|
|
76442
|
+
__info__.hash = "ff4b0ba";
|