@odoo/o-spreadsheet 18.0.29 → 18.0.30
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 +352 -352
- 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.0.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.30
|
|
6
|
+
* @date 2025-05-26T12:35:05.184Z
|
|
7
|
+
* @hash 838c4f7
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3973,6 +3973,113 @@ function transposeMatrix(matrix) {
|
|
|
3973
3973
|
}
|
|
3974
3974
|
return generateMatrix(matrix[0].length, matrix.length, (i, j) => matrix[j][i]);
|
|
3975
3975
|
}
|
|
3976
|
+
/**
|
|
3977
|
+
* Enables a formula function to accept matrix or vector inputs instead of simple value, computing results across multiple dimensions.
|
|
3978
|
+
*
|
|
3979
|
+
* ```
|
|
3980
|
+
* / |‾ ‾| \ |‾ ‾|
|
|
3981
|
+
* | | [A] | | | compute(A, D, E), compute(A, D, F), compute(A, D, G) |
|
|
3982
|
+
* applyVectorization| compute, | [B], D, [E, F, G] | | <=> | compute(B, D, E), compute(B, D, F), compute(B, D, G) |
|
|
3983
|
+
* | | [C] | | | compute(C, D, E), compute(C, D, F), compute(C, D, G) |
|
|
3984
|
+
* \ |_ _| / |_ _|
|
|
3985
|
+
* ```
|
|
3986
|
+
*
|
|
3987
|
+
* By default, all arguments are vectorized. To control which arguments are vectorized,
|
|
3988
|
+
* pass an `acceptToVectorize` boolean array of the same length as `args`:
|
|
3989
|
+
* - `true` enables vectorization for that argument
|
|
3990
|
+
* - `false` disables vectorization for that argument
|
|
3991
|
+
*
|
|
3992
|
+
* For example, with `[true, true, false]` on previous example you get:
|
|
3993
|
+
*
|
|
3994
|
+
* ```
|
|
3995
|
+
* |‾ ‾|
|
|
3996
|
+
* | compute(A, D, [E, F, G]) |
|
|
3997
|
+
* | compute(B, D, [E, F, G]) |
|
|
3998
|
+
* | compute(C, D, [E, F, G]) |
|
|
3999
|
+
* |_ _|
|
|
4000
|
+
* ```
|
|
4001
|
+
*
|
|
4002
|
+
* @remarks
|
|
4003
|
+
* This helper is automatically applied (by default) to **all** `compute` functions
|
|
4004
|
+
* across the various spreadsheet formula modules:
|
|
4005
|
+
* - If an argument is declared **scalar** (not `"range"`), it is vectorized.
|
|
4006
|
+
* - If **all** arguments are declared **ranges**, no vectorization occurs.
|
|
4007
|
+
* - e.g. `SUM(A1:B2)` returns a 1×1 sum over the range.
|
|
4008
|
+
* - e.g. `COS(A1:B2)` over `A1:B2` returns a 2×2 element-wise result.
|
|
4009
|
+
* - For special behaviors (e.g. the `IF` function), you may declare all arguments
|
|
4010
|
+
* as ranges and invoke this helper directly within your `compute` implementation.
|
|
4011
|
+
*/
|
|
4012
|
+
function applyVectorization(formula, args, acceptToVectorize = undefined) {
|
|
4013
|
+
let countVectorizedCol = 1;
|
|
4014
|
+
let countVectorizedRow = 1;
|
|
4015
|
+
let vectorizedColLimit = Infinity;
|
|
4016
|
+
let vectorizedRowLimit = Infinity;
|
|
4017
|
+
let vectorArgsType = undefined;
|
|
4018
|
+
for (let i = 0; i < args.length; i++) {
|
|
4019
|
+
const arg = args[i];
|
|
4020
|
+
if (isMatrix(arg) && (acceptToVectorize === undefined || acceptToVectorize[i])) {
|
|
4021
|
+
const nColumns = arg.length;
|
|
4022
|
+
const nRows = arg[0].length;
|
|
4023
|
+
if (nColumns !== 1 || nRows !== 1) {
|
|
4024
|
+
vectorArgsType ??= new Array(args.length);
|
|
4025
|
+
if (nColumns !== 1 && nRows !== 1) {
|
|
4026
|
+
vectorArgsType[i] = "matrix";
|
|
4027
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4028
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4029
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4030
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4031
|
+
}
|
|
4032
|
+
else if (nColumns !== 1) {
|
|
4033
|
+
vectorArgsType[i] = "horizontal";
|
|
4034
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4035
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4036
|
+
}
|
|
4037
|
+
else if (nRows !== 1) {
|
|
4038
|
+
vectorArgsType[i] = "vertical";
|
|
4039
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4040
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
else {
|
|
4044
|
+
args[i] = arg[0][0];
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
if (countVectorizedCol === 1 && countVectorizedRow === 1) {
|
|
4049
|
+
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
4050
|
+
return formula(...args);
|
|
4051
|
+
}
|
|
4052
|
+
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
4053
|
+
switch (vectorArgsType?.[index]) {
|
|
4054
|
+
case "matrix":
|
|
4055
|
+
return arg[i][j];
|
|
4056
|
+
case "horizontal":
|
|
4057
|
+
return arg[i][0];
|
|
4058
|
+
case "vertical":
|
|
4059
|
+
return arg[0][j];
|
|
4060
|
+
case undefined:
|
|
4061
|
+
return arg;
|
|
4062
|
+
}
|
|
4063
|
+
});
|
|
4064
|
+
return generateMatrix(countVectorizedCol, countVectorizedRow, (col, row) => {
|
|
4065
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
4066
|
+
return new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
4067
|
+
}
|
|
4068
|
+
const singleCellComputeResult = formula(...getArgOffset(col, row));
|
|
4069
|
+
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
4070
|
+
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
4071
|
+
// we won't be able to return the values.
|
|
4072
|
+
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
4073
|
+
// create an array with these parts.
|
|
4074
|
+
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
4075
|
+
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
4076
|
+
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
4077
|
+
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
4078
|
+
return isMatrix(singleCellComputeResult)
|
|
4079
|
+
? singleCellComputeResult[0][0]
|
|
4080
|
+
: singleCellComputeResult;
|
|
4081
|
+
});
|
|
4082
|
+
}
|
|
3976
4083
|
// -----------------------------------------------------------------------------
|
|
3977
4084
|
// CONDITIONAL EXPLORE FUNCTIONS
|
|
3978
4085
|
// -----------------------------------------------------------------------------
|
|
@@ -7279,14 +7386,20 @@ function multiplyMatrices(matrix1, matrix2) {
|
|
|
7279
7386
|
/**
|
|
7280
7387
|
* Return the input if it's a scalar or the first element of the input if it's a matrix.
|
|
7281
7388
|
*/
|
|
7282
|
-
function toScalar(
|
|
7283
|
-
if (!isMatrix(
|
|
7284
|
-
return
|
|
7389
|
+
function toScalar(arg) {
|
|
7390
|
+
if (!isMatrix(arg)) {
|
|
7391
|
+
return arg;
|
|
7285
7392
|
}
|
|
7286
|
-
if (
|
|
7393
|
+
if (!isSingleElementMatrix(arg)) {
|
|
7287
7394
|
throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
|
|
7288
7395
|
}
|
|
7289
|
-
return
|
|
7396
|
+
return arg[0][0];
|
|
7397
|
+
}
|
|
7398
|
+
function isSingleElementMatrix(matrix) {
|
|
7399
|
+
return matrix.length === 1 && matrix[0].length === 1;
|
|
7400
|
+
}
|
|
7401
|
+
function isMultipleElementMatrix(arg) {
|
|
7402
|
+
return isMatrix(arg) && !isSingleElementMatrix(arg);
|
|
7290
7403
|
}
|
|
7291
7404
|
|
|
7292
7405
|
function assertSameNumberOfElements(...args) {
|
|
@@ -21487,7 +21600,7 @@ const FILTER = {
|
|
|
21487
21600
|
}
|
|
21488
21601
|
return mode === "row" ? transposeMatrix(result) : result;
|
|
21489
21602
|
},
|
|
21490
|
-
isExported:
|
|
21603
|
+
isExported: false,
|
|
21491
21604
|
};
|
|
21492
21605
|
// -----------------------------------------------------------------------------
|
|
21493
21606
|
// SORT
|
|
@@ -24455,16 +24568,23 @@ const FALSE = {
|
|
|
24455
24568
|
const IF = {
|
|
24456
24569
|
description: _t("Returns value depending on logical expression."),
|
|
24457
24570
|
args: [
|
|
24458
|
-
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.")),
|
|
24459
|
-
arg("value_if_true (any)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
24460
|
-
arg("value_if_false (any, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
24571
|
+
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.")),
|
|
24572
|
+
arg("value_if_true (any, range)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
24573
|
+
arg("value_if_false (any, range, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
24461
24574
|
],
|
|
24462
24575
|
compute: function (logicalExpression, valueIfTrue, valueIfFalse) {
|
|
24463
|
-
|
|
24576
|
+
if (isMultipleElementMatrix(logicalExpression)) {
|
|
24577
|
+
return applyVectorization(IF.compute, [logicalExpression, valueIfTrue, valueIfFalse]);
|
|
24578
|
+
}
|
|
24579
|
+
let result = toBoolean(toScalar(logicalExpression)) ? valueIfTrue : valueIfFalse;
|
|
24580
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24581
|
+
if (!isMultipleElementMatrix(result)) {
|
|
24582
|
+
result = toScalar(result);
|
|
24583
|
+
}
|
|
24464
24584
|
if (result === undefined) {
|
|
24465
24585
|
return { value: "" };
|
|
24466
24586
|
}
|
|
24467
|
-
if (result.value === null) {
|
|
24587
|
+
if (!isMatrix(result) && result.value === null) {
|
|
24468
24588
|
return { ...result, value: "" };
|
|
24469
24589
|
}
|
|
24470
24590
|
return result;
|
|
@@ -24477,15 +24597,22 @@ const IF = {
|
|
|
24477
24597
|
const IFERROR = {
|
|
24478
24598
|
description: _t("Value if it is not an error, otherwise 2nd argument."),
|
|
24479
24599
|
args: [
|
|
24480
|
-
arg("value (any)", _t("The value to return if value itself is not an error.")),
|
|
24481
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
24600
|
+
arg("value (any, range)", _t("The value to return if value itself is not an error.")),
|
|
24601
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
24482
24602
|
],
|
|
24483
|
-
compute: function (value, valueIfError
|
|
24484
|
-
|
|
24603
|
+
compute: function (value, valueIfError) {
|
|
24604
|
+
if (isMultipleElementMatrix(value)) {
|
|
24605
|
+
return applyVectorization(IFERROR.compute, [value, valueIfError]);
|
|
24606
|
+
}
|
|
24607
|
+
let result = isEvaluationError(toScalar(value)?.value) ? valueIfError : value;
|
|
24608
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24609
|
+
if (!isMultipleElementMatrix(result)) {
|
|
24610
|
+
result = toScalar(result);
|
|
24611
|
+
}
|
|
24485
24612
|
if (result === undefined) {
|
|
24486
24613
|
return { value: "" };
|
|
24487
24614
|
}
|
|
24488
|
-
if (result.value === null) {
|
|
24615
|
+
if (!isMatrix(result) && result.value === null) {
|
|
24489
24616
|
return { ...result, value: "" };
|
|
24490
24617
|
}
|
|
24491
24618
|
return result;
|
|
@@ -24498,15 +24625,22 @@ const IFERROR = {
|
|
|
24498
24625
|
const IFNA = {
|
|
24499
24626
|
description: _t("Value if it is not an #N/A error, otherwise 2nd argument."),
|
|
24500
24627
|
args: [
|
|
24501
|
-
arg("value (any)", _t("The value to return if value itself is not #N/A an error.")),
|
|
24502
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
24628
|
+
arg("value (any, range)", _t("The value to return if value itself is not #N/A an error.")),
|
|
24629
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
24503
24630
|
],
|
|
24504
|
-
compute: function (value, valueIfError
|
|
24505
|
-
|
|
24631
|
+
compute: function (value, valueIfError) {
|
|
24632
|
+
if (isMultipleElementMatrix(value)) {
|
|
24633
|
+
return applyVectorization(IFNA.compute, [value, valueIfError]);
|
|
24634
|
+
}
|
|
24635
|
+
let result = toScalar(value)?.value === CellErrorType.NotAvailable ? valueIfError : value;
|
|
24636
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24637
|
+
if (!isMultipleElementMatrix(result)) {
|
|
24638
|
+
result = toScalar(result);
|
|
24639
|
+
}
|
|
24506
24640
|
if (result === undefined) {
|
|
24507
24641
|
return { value: "" };
|
|
24508
24642
|
}
|
|
24509
|
-
if (result.value === null) {
|
|
24643
|
+
if (!isMatrix(result) && result.value === null) {
|
|
24510
24644
|
return { ...result, value: "" };
|
|
24511
24645
|
}
|
|
24512
24646
|
return result;
|
|
@@ -24519,23 +24653,31 @@ const IFNA = {
|
|
|
24519
24653
|
const IFS = {
|
|
24520
24654
|
description: _t("Returns a value depending on multiple logical expressions."),
|
|
24521
24655
|
args: [
|
|
24522
|
-
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.")),
|
|
24523
|
-
arg("value1 (any)", _t("The returned value if condition1 is TRUE.")),
|
|
24524
|
-
arg("condition2 (boolean, any, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
24525
|
-
arg("value2 (any, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
24656
|
+
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.")),
|
|
24657
|
+
arg("value1 (any, range)", _t("The returned value if condition1 is TRUE.")),
|
|
24658
|
+
arg("condition2 (boolean, any, range, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
24659
|
+
arg("value2 (any, range, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
24526
24660
|
],
|
|
24527
24661
|
compute: function (...values) {
|
|
24528
24662
|
assert(() => values.length % 2 === 0, _t("Wrong number of arguments. Expected an even number of arguments."));
|
|
24529
|
-
|
|
24530
|
-
if (
|
|
24531
|
-
|
|
24532
|
-
|
|
24663
|
+
while (values.length > 0) {
|
|
24664
|
+
if (isMultipleElementMatrix(values[0])) {
|
|
24665
|
+
return applyVectorization(IFS.compute, values);
|
|
24666
|
+
}
|
|
24667
|
+
const condition = toBoolean(toScalar(values.shift()));
|
|
24668
|
+
let valueIfTrue = values.shift();
|
|
24669
|
+
if (condition) {
|
|
24670
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24671
|
+
if (!isMultipleElementMatrix(valueIfTrue)) {
|
|
24672
|
+
valueIfTrue = toScalar(valueIfTrue);
|
|
24673
|
+
}
|
|
24674
|
+
if (valueIfTrue === undefined) {
|
|
24533
24675
|
return { value: "" };
|
|
24534
24676
|
}
|
|
24535
|
-
if (
|
|
24536
|
-
return { ...
|
|
24677
|
+
if (!isMatrix(valueIfTrue) && valueIfTrue.value === null) {
|
|
24678
|
+
return { ...valueIfTrue, value: "" };
|
|
24537
24679
|
}
|
|
24538
|
-
return
|
|
24680
|
+
return valueIfTrue;
|
|
24539
24681
|
}
|
|
24540
24682
|
}
|
|
24541
24683
|
return new EvaluationError(_t("No match."));
|
|
@@ -26179,7 +26321,7 @@ const SPLIT = {
|
|
|
26179
26321
|
}
|
|
26180
26322
|
return transposeMatrix([result]);
|
|
26181
26323
|
},
|
|
26182
|
-
isExported:
|
|
26324
|
+
isExported: false,
|
|
26183
26325
|
};
|
|
26184
26326
|
// -----------------------------------------------------------------------------
|
|
26185
26327
|
// SUBSTITUTE
|
|
@@ -26372,86 +26514,21 @@ for (let category of categories) {
|
|
|
26372
26514
|
functionRegistry.add(name, { isExported: false, ...addDescr });
|
|
26373
26515
|
}
|
|
26374
26516
|
}
|
|
26375
|
-
|
|
26517
|
+
//------------------------------------------------------------------------------
|
|
26518
|
+
// CREATE COMPUTE FUNCTION
|
|
26519
|
+
//------------------------------------------------------------------------------
|
|
26376
26520
|
function createComputeFunction(descr, functionName) {
|
|
26377
26521
|
function vectorizedCompute(...args) {
|
|
26378
|
-
|
|
26379
|
-
let countVectorizableRow = 1;
|
|
26380
|
-
let vectorizableColLimit = Infinity;
|
|
26381
|
-
let vectorizableRowLimit = Infinity;
|
|
26382
|
-
let vectorArgsType = undefined;
|
|
26383
|
-
//#region Compute vectorisation limits
|
|
26522
|
+
const acceptToVectorize = [];
|
|
26384
26523
|
for (let i = 0; i < args.length; i++) {
|
|
26385
26524
|
const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
|
|
26386
26525
|
const arg = args[i];
|
|
26387
|
-
if (isMatrix(arg) && !argDefinition.acceptMatrix) {
|
|
26388
|
-
// if argDefinition does not accept a matrix but arg is still a matrix
|
|
26389
|
-
// --> triggers the arguments vectorization
|
|
26390
|
-
const nColumns = arg.length;
|
|
26391
|
-
const nRows = arg[0].length;
|
|
26392
|
-
if (nColumns !== 1 || nRows !== 1) {
|
|
26393
|
-
vectorArgsType ??= new Array(args.length);
|
|
26394
|
-
if (nColumns !== 1 && nRows !== 1) {
|
|
26395
|
-
vectorArgsType[i] = "matrix";
|
|
26396
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
26397
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
26398
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
26399
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
26400
|
-
}
|
|
26401
|
-
else if (nColumns !== 1) {
|
|
26402
|
-
vectorArgsType[i] = "horizontal";
|
|
26403
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
26404
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
26405
|
-
}
|
|
26406
|
-
else if (nRows !== 1) {
|
|
26407
|
-
vectorArgsType[i] = "vertical";
|
|
26408
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
26409
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
26410
|
-
}
|
|
26411
|
-
}
|
|
26412
|
-
else {
|
|
26413
|
-
args[i] = arg[0][0];
|
|
26414
|
-
}
|
|
26415
|
-
}
|
|
26416
26526
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
26417
26527
|
throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
|
|
26418
26528
|
}
|
|
26529
|
+
acceptToVectorize.push(!argDefinition.acceptMatrix);
|
|
26419
26530
|
}
|
|
26420
|
-
|
|
26421
|
-
if (countVectorizableCol === 1 && countVectorizableRow === 1) {
|
|
26422
|
-
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
26423
|
-
return errorHandlingCompute.apply(this, args);
|
|
26424
|
-
}
|
|
26425
|
-
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
26426
|
-
switch (vectorArgsType?.[index]) {
|
|
26427
|
-
case "matrix":
|
|
26428
|
-
return arg[i][j];
|
|
26429
|
-
case "horizontal":
|
|
26430
|
-
return arg[i][0];
|
|
26431
|
-
case "vertical":
|
|
26432
|
-
return arg[0][j];
|
|
26433
|
-
case undefined:
|
|
26434
|
-
return arg;
|
|
26435
|
-
}
|
|
26436
|
-
});
|
|
26437
|
-
return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
|
|
26438
|
-
if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
|
|
26439
|
-
return notAvailableError;
|
|
26440
|
-
}
|
|
26441
|
-
const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
|
|
26442
|
-
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
26443
|
-
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
26444
|
-
// we won't be able to return the values.
|
|
26445
|
-
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
26446
|
-
// create an array with these parts.
|
|
26447
|
-
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
26448
|
-
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
26449
|
-
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
26450
|
-
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
26451
|
-
return isMatrix(singleCellComputeResult)
|
|
26452
|
-
? singleCellComputeResult[0][0]
|
|
26453
|
-
: singleCellComputeResult;
|
|
26454
|
-
});
|
|
26531
|
+
return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
|
|
26455
26532
|
}
|
|
26456
26533
|
function errorHandlingCompute(...args) {
|
|
26457
26534
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -39440,7 +39517,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
39440
39517
|
proposals &&
|
|
39441
39518
|
!["ARG_SEPARATOR", "LEFT_PAREN", "OPERATOR"].includes(tokenAtCursor.type)) {
|
|
39442
39519
|
const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
|
|
39443
|
-
if (!exactMatch || filteredProposals.length
|
|
39520
|
+
if (!exactMatch || filteredProposals.length) {
|
|
39444
39521
|
proposals = filteredProposals;
|
|
39445
39522
|
}
|
|
39446
39523
|
}
|
|
@@ -44049,7 +44126,9 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
44049
44126
|
return dimension.order === "asc" ? -1 : 1;
|
|
44050
44127
|
}
|
|
44051
44128
|
if (dimension.type === "integer" || dimension.type === "datetime") {
|
|
44052
|
-
return dimension.order === "asc"
|
|
44129
|
+
return dimension.order === "asc"
|
|
44130
|
+
? toNumber(a, DEFAULT_LOCALE) - toNumber(b, DEFAULT_LOCALE)
|
|
44131
|
+
: toNumber(b, DEFAULT_LOCALE) - toNumber(a, DEFAULT_LOCALE);
|
|
44053
44132
|
}
|
|
44054
44133
|
return dimension.order === "asc" ? a.localeCompare(b) : b.localeCompare(a);
|
|
44055
44134
|
}
|
|
@@ -46790,8 +46869,7 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
46790
46869
|
if (!spreader) {
|
|
46791
46870
|
return undefined;
|
|
46792
46871
|
}
|
|
46793
|
-
|
|
46794
|
-
return cell?.content;
|
|
46872
|
+
return this.getters.getCellText(spreader, { showFormula: true });
|
|
46795
46873
|
}
|
|
46796
46874
|
get currentEditedCell() {
|
|
46797
46875
|
return {
|
|
@@ -49594,6 +49672,7 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
49594
49672
|
const friction = 0.95;
|
|
49595
49673
|
const verticalScrollFactor = 1;
|
|
49596
49674
|
const horizontalScrollFactor = 1;
|
|
49675
|
+
const resetTimeoutDuration = 100;
|
|
49597
49676
|
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
49598
49677
|
let lastX = 0;
|
|
49599
49678
|
let lastY = 0;
|
|
@@ -49601,6 +49680,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
49601
49680
|
let velocityY = 0;
|
|
49602
49681
|
let isMouseDown = false;
|
|
49603
49682
|
let lastTime = 0;
|
|
49683
|
+
let resetTimeout = null;
|
|
49604
49684
|
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
49605
49685
|
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
49606
49686
|
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
@@ -49613,6 +49693,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
49613
49693
|
function onTouchMove(event) {
|
|
49614
49694
|
if (!isMouseDown)
|
|
49615
49695
|
return;
|
|
49696
|
+
if (resetTimeout) {
|
|
49697
|
+
clearTimeout(resetTimeout);
|
|
49698
|
+
resetTimeout = null;
|
|
49699
|
+
}
|
|
49616
49700
|
const currentTime = Date.now();
|
|
49617
49701
|
const { clientX, clientY } = event.touches[0];
|
|
49618
49702
|
let deltaX = lastX - clientX;
|
|
@@ -49629,6 +49713,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
49629
49713
|
}
|
|
49630
49714
|
event.stopPropagation();
|
|
49631
49715
|
}
|
|
49716
|
+
resetTimeout = setTimeout(() => {
|
|
49717
|
+
velocityX = 0;
|
|
49718
|
+
velocityY = 0;
|
|
49719
|
+
}, resetTimeoutDuration);
|
|
49632
49720
|
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
49633
49721
|
}
|
|
49634
49722
|
function onTouchEnd(ev) {
|
|
@@ -74316,6 +74404,6 @@ exports.tokenColors = tokenColors;
|
|
|
74316
74404
|
exports.tokenize = tokenize;
|
|
74317
74405
|
|
|
74318
74406
|
|
|
74319
|
-
__info__.version = "18.0.
|
|
74320
|
-
__info__.date = "2025-05-
|
|
74321
|
-
__info__.hash = "
|
|
74407
|
+
__info__.version = "18.0.30";
|
|
74408
|
+
__info__.date = "2025-05-26T12:35:05.184Z";
|
|
74409
|
+
__info__.hash = "838c4f7";
|