@odoo/o-spreadsheet 18.0.29 → 18.0.31

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.
@@ -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.29
6
- * @date 2025-05-20T05:54:57.329Z
7
- * @hash 8213c0e
5
+ * @version 18.0.31
6
+ * @date 2025-05-30T08:43:10.315Z
7
+ * @hash d201086
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -3971,6 +3971,113 @@ function transposeMatrix(matrix) {
3971
3971
  }
3972
3972
  return generateMatrix(matrix[0].length, matrix.length, (i, j) => matrix[j][i]);
3973
3973
  }
3974
+ /**
3975
+ * Enables a formula function to accept matrix or vector inputs instead of simple value, computing results across multiple dimensions.
3976
+ *
3977
+ * ```
3978
+ * / |‾ ‾| \ |‾ ‾|
3979
+ * | | [A] | | | compute(A, D, E), compute(A, D, F), compute(A, D, G) |
3980
+ * applyVectorization| compute, | [B], D, [E, F, G] | | <=> | compute(B, D, E), compute(B, D, F), compute(B, D, G) |
3981
+ * | | [C] | | | compute(C, D, E), compute(C, D, F), compute(C, D, G) |
3982
+ * \ |_ _| / |_ _|
3983
+ * ```
3984
+ *
3985
+ * By default, all arguments are vectorized. To control which arguments are vectorized,
3986
+ * pass an `acceptToVectorize` boolean array of the same length as `args`:
3987
+ * - `true` enables vectorization for that argument
3988
+ * - `false` disables vectorization for that argument
3989
+ *
3990
+ * For example, with `[true, true, false]` on previous example you get:
3991
+ *
3992
+ * ```
3993
+ * |‾ ‾|
3994
+ * | compute(A, D, [E, F, G]) |
3995
+ * | compute(B, D, [E, F, G]) |
3996
+ * | compute(C, D, [E, F, G]) |
3997
+ * |_ _|
3998
+ * ```
3999
+ *
4000
+ * @remarks
4001
+ * This helper is automatically applied (by default) to **all** `compute` functions
4002
+ * across the various spreadsheet formula modules:
4003
+ * - If an argument is declared **scalar** (not `"range"`), it is vectorized.
4004
+ * - If **all** arguments are declared **ranges**, no vectorization occurs.
4005
+ * - e.g. `SUM(A1:B2)` returns a 1×1 sum over the range.
4006
+ * - e.g. `COS(A1:B2)` over `A1:B2` returns a 2×2 element-wise result.
4007
+ * - For special behaviors (e.g. the `IF` function), you may declare all arguments
4008
+ * as ranges and invoke this helper directly within your `compute` implementation.
4009
+ */
4010
+ function applyVectorization(formula, args, acceptToVectorize = undefined) {
4011
+ let countVectorizedCol = 1;
4012
+ let countVectorizedRow = 1;
4013
+ let vectorizedColLimit = Infinity;
4014
+ let vectorizedRowLimit = Infinity;
4015
+ let vectorArgsType = undefined;
4016
+ for (let i = 0; i < args.length; i++) {
4017
+ const arg = args[i];
4018
+ if (isMatrix(arg) && (acceptToVectorize === undefined || acceptToVectorize[i])) {
4019
+ const nColumns = arg.length;
4020
+ const nRows = arg[0].length;
4021
+ if (nColumns !== 1 || nRows !== 1) {
4022
+ vectorArgsType ??= new Array(args.length);
4023
+ if (nColumns !== 1 && nRows !== 1) {
4024
+ vectorArgsType[i] = "matrix";
4025
+ countVectorizedCol = Math.max(countVectorizedCol, nColumns);
4026
+ countVectorizedRow = Math.max(countVectorizedRow, nRows);
4027
+ vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
4028
+ vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
4029
+ }
4030
+ else if (nColumns !== 1) {
4031
+ vectorArgsType[i] = "horizontal";
4032
+ countVectorizedCol = Math.max(countVectorizedCol, nColumns);
4033
+ vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
4034
+ }
4035
+ else if (nRows !== 1) {
4036
+ vectorArgsType[i] = "vertical";
4037
+ countVectorizedRow = Math.max(countVectorizedRow, nRows);
4038
+ vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
4039
+ }
4040
+ }
4041
+ else {
4042
+ args[i] = arg[0][0];
4043
+ }
4044
+ }
4045
+ }
4046
+ if (countVectorizedCol === 1 && countVectorizedRow === 1) {
4047
+ // either this function is not vectorized or it ends up with a 1x1 dimension
4048
+ return formula(...args);
4049
+ }
4050
+ const getArgOffset = (i, j) => args.map((arg, index) => {
4051
+ switch (vectorArgsType?.[index]) {
4052
+ case "matrix":
4053
+ return arg[i][j];
4054
+ case "horizontal":
4055
+ return arg[i][0];
4056
+ case "vertical":
4057
+ return arg[0][j];
4058
+ case undefined:
4059
+ return arg;
4060
+ }
4061
+ });
4062
+ return generateMatrix(countVectorizedCol, countVectorizedRow, (col, row) => {
4063
+ if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
4064
+ return new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
4065
+ }
4066
+ const singleCellComputeResult = formula(...getArgOffset(col, row));
4067
+ // In the case where the user tries to vectorize arguments of an array formula, we will get an
4068
+ // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
4069
+ // we won't be able to return the values.
4070
+ // In this case, we keep the first element of each spreading part, just as Excel does, and
4071
+ // create an array with these parts.
4072
+ // For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
4073
+ // range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
4074
+ // for the value in A2). In this case, we will simply take the first value of each matrix and
4075
+ // return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
4076
+ return isMatrix(singleCellComputeResult)
4077
+ ? singleCellComputeResult[0][0]
4078
+ : singleCellComputeResult;
4079
+ });
4080
+ }
3974
4081
  // -----------------------------------------------------------------------------
3975
4082
  // CONDITIONAL EXPLORE FUNCTIONS
3976
4083
  // -----------------------------------------------------------------------------
@@ -7277,14 +7384,20 @@ function multiplyMatrices(matrix1, matrix2) {
7277
7384
  /**
7278
7385
  * Return the input if it's a scalar or the first element of the input if it's a matrix.
7279
7386
  */
7280
- function toScalar(matrix) {
7281
- if (!isMatrix(matrix)) {
7282
- return matrix;
7387
+ function toScalar(arg) {
7388
+ if (!isMatrix(arg)) {
7389
+ return arg;
7283
7390
  }
7284
- if (matrix.length !== 1 || matrix[0].length !== 1) {
7391
+ if (!isSingleElementMatrix(arg)) {
7285
7392
  throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
7286
7393
  }
7287
- return matrix[0][0];
7394
+ return arg[0][0];
7395
+ }
7396
+ function isSingleElementMatrix(matrix) {
7397
+ return matrix.length === 1 && matrix[0].length === 1;
7398
+ }
7399
+ function isMultipleElementMatrix(arg) {
7400
+ return isMatrix(arg) && !isSingleElementMatrix(arg);
7288
7401
  }
7289
7402
 
7290
7403
  function assertSameNumberOfElements(...args) {
@@ -8001,9 +8114,10 @@ const AGGREGATOR_NAMES = {
8001
8114
  avg: _t("Average"),
8002
8115
  sum: _t("Sum"),
8003
8116
  };
8117
+ const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8004
8118
  const AGGREGATORS_BY_FIELD_TYPE = {
8005
- integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
8006
- char: ["count_distinct", "count"],
8119
+ integer: NUMBER_CHAR_AGGREGATORS,
8120
+ char: NUMBER_CHAR_AGGREGATORS,
8007
8121
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8008
8122
  };
8009
8123
  const AGGREGATORS = {};
@@ -21485,7 +21599,7 @@ const FILTER = {
21485
21599
  }
21486
21600
  return mode === "row" ? transposeMatrix(result) : result;
21487
21601
  },
21488
- isExported: true,
21602
+ isExported: false,
21489
21603
  };
21490
21604
  // -----------------------------------------------------------------------------
21491
21605
  // SORT
@@ -24453,16 +24567,23 @@ const FALSE = {
24453
24567
  const IF = {
24454
24568
  description: _t("Returns value depending on logical expression."),
24455
24569
  args: [
24456
- 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.")),
24457
- arg("value_if_true (any)", _t("The value the function returns if logical_expression is TRUE.")),
24458
- arg("value_if_false (any, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
24570
+ 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.")),
24571
+ arg("value_if_true (any, range)", _t("The value the function returns if logical_expression is TRUE.")),
24572
+ arg("value_if_false (any, range, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
24459
24573
  ],
24460
24574
  compute: function (logicalExpression, valueIfTrue, valueIfFalse) {
24461
- const result = toBoolean(logicalExpression?.value) ? valueIfTrue : valueIfFalse;
24575
+ if (isMultipleElementMatrix(logicalExpression)) {
24576
+ return applyVectorization(IF.compute, [logicalExpression, valueIfTrue, valueIfFalse]);
24577
+ }
24578
+ let result = toBoolean(toScalar(logicalExpression)) ? valueIfTrue : valueIfFalse;
24579
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
24580
+ if (!isMultipleElementMatrix(result)) {
24581
+ result = toScalar(result);
24582
+ }
24462
24583
  if (result === undefined) {
24463
24584
  return { value: "" };
24464
24585
  }
24465
- if (result.value === null) {
24586
+ if (!isMatrix(result) && result.value === null) {
24466
24587
  return { ...result, value: "" };
24467
24588
  }
24468
24589
  return result;
@@ -24475,15 +24596,22 @@ const IF = {
24475
24596
  const IFERROR = {
24476
24597
  description: _t("Value if it is not an error, otherwise 2nd argument."),
24477
24598
  args: [
24478
- arg("value (any)", _t("The value to return if value itself is not an error.")),
24479
- arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an error.")),
24599
+ arg("value (any, range)", _t("The value to return if value itself is not an error.")),
24600
+ arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an error.")),
24480
24601
  ],
24481
- compute: function (value, valueIfError = { value: "" }) {
24482
- const result = isEvaluationError(value?.value) ? valueIfError : value;
24602
+ compute: function (value, valueIfError) {
24603
+ if (isMultipleElementMatrix(value)) {
24604
+ return applyVectorization(IFERROR.compute, [value, valueIfError]);
24605
+ }
24606
+ let result = isEvaluationError(toScalar(value)?.value) ? valueIfError : value;
24607
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
24608
+ if (!isMultipleElementMatrix(result)) {
24609
+ result = toScalar(result);
24610
+ }
24483
24611
  if (result === undefined) {
24484
24612
  return { value: "" };
24485
24613
  }
24486
- if (result.value === null) {
24614
+ if (!isMatrix(result) && result.value === null) {
24487
24615
  return { ...result, value: "" };
24488
24616
  }
24489
24617
  return result;
@@ -24496,15 +24624,22 @@ const IFERROR = {
24496
24624
  const IFNA = {
24497
24625
  description: _t("Value if it is not an #N/A error, otherwise 2nd argument."),
24498
24626
  args: [
24499
- arg("value (any)", _t("The value to return if value itself is not #N/A an error.")),
24500
- arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
24627
+ arg("value (any, range)", _t("The value to return if value itself is not #N/A an error.")),
24628
+ arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
24501
24629
  ],
24502
- compute: function (value, valueIfError = { value: "" }) {
24503
- const result = value?.value === CellErrorType.NotAvailable ? valueIfError : value;
24630
+ compute: function (value, valueIfError) {
24631
+ if (isMultipleElementMatrix(value)) {
24632
+ return applyVectorization(IFNA.compute, [value, valueIfError]);
24633
+ }
24634
+ let result = toScalar(value)?.value === CellErrorType.NotAvailable ? valueIfError : value;
24635
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
24636
+ if (!isMultipleElementMatrix(result)) {
24637
+ result = toScalar(result);
24638
+ }
24504
24639
  if (result === undefined) {
24505
24640
  return { value: "" };
24506
24641
  }
24507
- if (result.value === null) {
24642
+ if (!isMatrix(result) && result.value === null) {
24508
24643
  return { ...result, value: "" };
24509
24644
  }
24510
24645
  return result;
@@ -24517,23 +24652,31 @@ const IFNA = {
24517
24652
  const IFS = {
24518
24653
  description: _t("Returns a value depending on multiple logical expressions."),
24519
24654
  args: [
24520
- 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.")),
24521
- arg("value1 (any)", _t("The returned value if condition1 is TRUE.")),
24522
- arg("condition2 (boolean, any, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
24523
- arg("value2 (any, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
24655
+ 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.")),
24656
+ arg("value1 (any, range)", _t("The returned value if condition1 is TRUE.")),
24657
+ arg("condition2 (boolean, any, range, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
24658
+ arg("value2 (any, range, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
24524
24659
  ],
24525
24660
  compute: function (...values) {
24526
24661
  assert(() => values.length % 2 === 0, _t("Wrong number of arguments. Expected an even number of arguments."));
24527
- for (let n = 0; n < values.length - 1; n += 2) {
24528
- if (toBoolean(values[n]?.value)) {
24529
- const result = values[n + 1];
24530
- if (result === undefined) {
24662
+ while (values.length > 0) {
24663
+ if (isMultipleElementMatrix(values[0])) {
24664
+ return applyVectorization(IFS.compute, values);
24665
+ }
24666
+ const condition = toBoolean(toScalar(values.shift()));
24667
+ let valueIfTrue = values.shift();
24668
+ if (condition) {
24669
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
24670
+ if (!isMultipleElementMatrix(valueIfTrue)) {
24671
+ valueIfTrue = toScalar(valueIfTrue);
24672
+ }
24673
+ if (valueIfTrue === undefined) {
24531
24674
  return { value: "" };
24532
24675
  }
24533
- if (result.value === null) {
24534
- return { ...result, value: "" };
24676
+ if (!isMatrix(valueIfTrue) && valueIfTrue.value === null) {
24677
+ return { ...valueIfTrue, value: "" };
24535
24678
  }
24536
- return result;
24679
+ return valueIfTrue;
24537
24680
  }
24538
24681
  }
24539
24682
  return new EvaluationError(_t("No match."));
@@ -26177,7 +26320,7 @@ const SPLIT = {
26177
26320
  }
26178
26321
  return transposeMatrix([result]);
26179
26322
  },
26180
- isExported: true,
26323
+ isExported: false,
26181
26324
  };
26182
26325
  // -----------------------------------------------------------------------------
26183
26326
  // SUBSTITUTE
@@ -26370,86 +26513,21 @@ for (let category of categories) {
26370
26513
  functionRegistry.add(name, { isExported: false, ...addDescr });
26371
26514
  }
26372
26515
  }
26373
- const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
26516
+ //------------------------------------------------------------------------------
26517
+ // CREATE COMPUTE FUNCTION
26518
+ //------------------------------------------------------------------------------
26374
26519
  function createComputeFunction(descr, functionName) {
26375
26520
  function vectorizedCompute(...args) {
26376
- let countVectorizableCol = 1;
26377
- let countVectorizableRow = 1;
26378
- let vectorizableColLimit = Infinity;
26379
- let vectorizableRowLimit = Infinity;
26380
- let vectorArgsType = undefined;
26381
- //#region Compute vectorisation limits
26521
+ const acceptToVectorize = [];
26382
26522
  for (let i = 0; i < args.length; i++) {
26383
26523
  const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
26384
26524
  const arg = args[i];
26385
- if (isMatrix(arg) && !argDefinition.acceptMatrix) {
26386
- // if argDefinition does not accept a matrix but arg is still a matrix
26387
- // --> triggers the arguments vectorization
26388
- const nColumns = arg.length;
26389
- const nRows = arg[0].length;
26390
- if (nColumns !== 1 || nRows !== 1) {
26391
- vectorArgsType ??= new Array(args.length);
26392
- if (nColumns !== 1 && nRows !== 1) {
26393
- vectorArgsType[i] = "matrix";
26394
- countVectorizableCol = Math.max(countVectorizableCol, nColumns);
26395
- countVectorizableRow = Math.max(countVectorizableRow, nRows);
26396
- vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
26397
- vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
26398
- }
26399
- else if (nColumns !== 1) {
26400
- vectorArgsType[i] = "horizontal";
26401
- countVectorizableCol = Math.max(countVectorizableCol, nColumns);
26402
- vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
26403
- }
26404
- else if (nRows !== 1) {
26405
- vectorArgsType[i] = "vertical";
26406
- countVectorizableRow = Math.max(countVectorizableRow, nRows);
26407
- vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
26408
- }
26409
- }
26410
- else {
26411
- args[i] = arg[0][0];
26412
- }
26413
- }
26414
26525
  if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
26415
26526
  throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
26416
26527
  }
26528
+ acceptToVectorize.push(!argDefinition.acceptMatrix);
26417
26529
  }
26418
- //#endregion
26419
- if (countVectorizableCol === 1 && countVectorizableRow === 1) {
26420
- // either this function is not vectorized or it ends up with a 1x1 dimension
26421
- return errorHandlingCompute.apply(this, args);
26422
- }
26423
- const getArgOffset = (i, j) => args.map((arg, index) => {
26424
- switch (vectorArgsType?.[index]) {
26425
- case "matrix":
26426
- return arg[i][j];
26427
- case "horizontal":
26428
- return arg[i][0];
26429
- case "vertical":
26430
- return arg[0][j];
26431
- case undefined:
26432
- return arg;
26433
- }
26434
- });
26435
- return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
26436
- if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
26437
- return notAvailableError;
26438
- }
26439
- const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
26440
- // In the case where the user tries to vectorize arguments of an array formula, we will get an
26441
- // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
26442
- // we won't be able to return the values.
26443
- // In this case, we keep the first element of each spreading part, just as Excel does, and
26444
- // create an array with these parts.
26445
- // For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
26446
- // range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
26447
- // for the value in A2). In this case, we will simply take the first value of each matrix and
26448
- // return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
26449
- return isMatrix(singleCellComputeResult)
26450
- ? singleCellComputeResult[0][0]
26451
- : singleCellComputeResult;
26452
- });
26530
+ return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
26453
26531
  }
26454
26532
  function errorHandlingCompute(...args) {
26455
26533
  for (let i = 0; i < args.length; i++) {
@@ -39438,7 +39516,7 @@ class AbstractComposerStore extends SpreadsheetStore {
39438
39516
  proposals &&
39439
39517
  !["ARG_SEPARATOR", "LEFT_PAREN", "OPERATOR"].includes(tokenAtCursor.type)) {
39440
39518
  const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
39441
- if (!exactMatch || filteredProposals.length > 1) {
39519
+ if (!exactMatch || filteredProposals.length) {
39442
39520
  proposals = filteredProposals;
39443
39521
  }
39444
39522
  }
@@ -44047,7 +44125,9 @@ function compareDimensionValues(dimension, a, b) {
44047
44125
  return dimension.order === "asc" ? -1 : 1;
44048
44126
  }
44049
44127
  if (dimension.type === "integer" || dimension.type === "datetime") {
44050
- return dimension.order === "asc" ? Number(a) - Number(b) : Number(b) - Number(a);
44128
+ return dimension.order === "asc"
44129
+ ? toNumber(a, DEFAULT_LOCALE) - toNumber(b, DEFAULT_LOCALE)
44130
+ : toNumber(b, DEFAULT_LOCALE) - toNumber(a, DEFAULT_LOCALE);
44051
44131
  }
44052
44132
  return dimension.order === "asc" ? a.localeCompare(b) : b.localeCompare(a);
44053
44133
  }
@@ -44583,12 +44663,7 @@ class SpreadsheetPivot {
44583
44663
  entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
44584
44664
  }
44585
44665
  else {
44586
- if (field.type === "char") {
44587
- entry[field.name] = { ...cell, value: cell.formattedValue || null };
44588
- }
44589
- else {
44590
- entry[field.name] = cell;
44591
- }
44666
+ entry[field.name] = cell;
44592
44667
  }
44593
44668
  }
44594
44669
  entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
@@ -46788,8 +46863,7 @@ class CellComposerStore extends AbstractComposerStore {
46788
46863
  if (!spreader) {
46789
46864
  return undefined;
46790
46865
  }
46791
- const cell = this.getters.getCell(spreader);
46792
- return cell?.content;
46866
+ return this.getters.getCellText(spreader, { showFormula: true });
46793
46867
  }
46794
46868
  get currentEditedCell() {
46795
46869
  return {
@@ -49592,6 +49666,7 @@ function useGridDrawing(refName, model, canvasSize) {
49592
49666
  const friction = 0.95;
49593
49667
  const verticalScrollFactor = 1;
49594
49668
  const horizontalScrollFactor = 1;
49669
+ const resetTimeoutDuration = 100;
49595
49670
  function useTouchScroll(ref, updateScroll, canMoveUp) {
49596
49671
  let lastX = 0;
49597
49672
  let lastY = 0;
@@ -49599,6 +49674,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
49599
49674
  let velocityY = 0;
49600
49675
  let isMouseDown = false;
49601
49676
  let lastTime = 0;
49677
+ let resetTimeout = null;
49602
49678
  useRefListener(ref, "touchstart", onTouchStart, { capture: false });
49603
49679
  useRefListener(ref, "touchmove", onTouchMove, { capture: false });
49604
49680
  useRefListener(ref, "touchend", onTouchEnd, { capture: false });
@@ -49611,6 +49687,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
49611
49687
  function onTouchMove(event) {
49612
49688
  if (!isMouseDown)
49613
49689
  return;
49690
+ if (resetTimeout) {
49691
+ clearTimeout(resetTimeout);
49692
+ resetTimeout = null;
49693
+ }
49614
49694
  const currentTime = Date.now();
49615
49695
  const { clientX, clientY } = event.touches[0];
49616
49696
  let deltaX = lastX - clientX;
@@ -49627,6 +49707,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
49627
49707
  }
49628
49708
  event.stopPropagation();
49629
49709
  }
49710
+ resetTimeout = setTimeout(() => {
49711
+ velocityX = 0;
49712
+ velocityY = 0;
49713
+ }, resetTimeoutDuration);
49630
49714
  updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49631
49715
  }
49632
49716
  function onTouchEnd(ev) {
@@ -74271,6 +74355,6 @@ const constants = {
74271
74355
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
74272
74356
 
74273
74357
 
74274
- __info__.version = "18.0.29";
74275
- __info__.date = "2025-05-20T05:54:57.329Z";
74276
- __info__.hash = "8213c0e";
74358
+ __info__.version = "18.0.31";
74359
+ __info__.date = "2025-05-30T08:43:10.315Z";
74360
+ __info__.hash = "d201086";