@odoo/o-spreadsheet 18.4.8 → 18.4.9

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.4.8
6
- * @date 2025-08-26T10:14:08.954Z
7
- * @hash 746217a
5
+ * @version 18.4.9
6
+ * @date 2025-09-05T07:38:32.126Z
7
+ * @hash a261873
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2644,6 +2644,7 @@
2644
2644
  "AUTOFILL_CELL",
2645
2645
  "SET_BORDER",
2646
2646
  "SET_ZONE_BORDERS",
2647
+ "SET_BORDERS_ON_TARGET",
2647
2648
  ]);
2648
2649
  const readonlyAllowedCommands = new Set([
2649
2650
  "START",
@@ -3990,6 +3991,10 @@
3990
3991
  }
3991
3992
  return true;
3992
3993
  }
3994
+ const noValidInputErrorMessage = _t("[[FUNCTION_NAME]] has no valid input data.");
3995
+ function emptyDataErrorMessage(argName) {
3996
+ return _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", { argName });
3997
+ }
3993
3998
 
3994
3999
  function tokenizeFormat(str) {
3995
4000
  const chars = new TokenizingChars(str);
@@ -6591,40 +6596,44 @@
6591
6596
  };
6592
6597
  }
6593
6598
  function getRangeAdapter(cmd) {
6594
- switch (cmd.type) {
6595
- case "REMOVE_COLUMNS_ROWS":
6596
- return {
6597
- applyChange: getApplyRangeChangeRemoveColRow(cmd),
6598
- sheetId: cmd.sheetId,
6599
- sheetName: cmd.sheetName,
6600
- };
6601
- case "ADD_COLUMNS_ROWS":
6602
- return {
6603
- applyChange: getApplyRangeChangeAddColRow(cmd),
6604
- sheetId: cmd.sheetId,
6605
- sheetName: cmd.sheetName,
6606
- };
6607
- case "DELETE_SHEET":
6608
- return {
6609
- applyChange: getApplyRangeChangeDeleteSheet(cmd),
6610
- sheetId: cmd.sheetId,
6611
- sheetName: cmd.sheetName,
6612
- };
6613
- case "RENAME_SHEET":
6614
- return {
6615
- applyChange: getApplyRangeChangeRenameSheet(cmd),
6616
- sheetId: cmd.sheetId,
6617
- sheetName: cmd.oldName,
6618
- };
6619
- case "MOVE_RANGES":
6620
- return {
6621
- applyChange: getApplyRangeChangeMoveRange(cmd),
6622
- sheetId: cmd.sheetId,
6623
- sheetName: cmd.sheetName,
6624
- };
6599
+ return rangeAdapterRegistry.get(cmd.type)?.(cmd);
6600
+ }
6601
+ class RangeAdapterRegistry extends Registry {
6602
+ add(cmdType, fn) {
6603
+ super.add(cmdType, fn);
6604
+ return this;
6605
+ }
6606
+ get(cmdType) {
6607
+ return this.content[cmdType];
6625
6608
  }
6626
- return undefined;
6627
6609
  }
6610
+ const rangeAdapterRegistry = new RangeAdapterRegistry();
6611
+ rangeAdapterRegistry
6612
+ .add("REMOVE_COLUMNS_ROWS", (cmd) => ({
6613
+ applyChange: getApplyRangeChangeRemoveColRow(cmd),
6614
+ sheetId: cmd.sheetId,
6615
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6616
+ }))
6617
+ .add("ADD_COLUMNS_ROWS", (cmd) => ({
6618
+ applyChange: getApplyRangeChangeAddColRow(cmd),
6619
+ sheetId: cmd.sheetId,
6620
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6621
+ }))
6622
+ .add("DELETE_SHEET", (cmd) => ({
6623
+ applyChange: getApplyRangeChangeDeleteSheet(cmd),
6624
+ sheetId: cmd.sheetId,
6625
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6626
+ }))
6627
+ .add("RENAME_SHEET", (cmd) => ({
6628
+ applyChange: getApplyRangeChangeRenameSheet(cmd),
6629
+ sheetId: cmd.sheetId,
6630
+ sheetName: { old: cmd.oldName, current: cmd.newName },
6631
+ }))
6632
+ .add("MOVE_RANGES", (cmd) => ({
6633
+ applyChange: getApplyRangeChangeMoveRange(cmd),
6634
+ sheetId: cmd.sheetId,
6635
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6636
+ }));
6628
6637
  function getApplyRangeChangeRemoveColRow(cmd) {
6629
6638
  const start = cmd.dimension === "COL" ? "left" : "top";
6630
6639
  const end = cmd.dimension === "COL" ? "right" : "bottom";
@@ -8001,8 +8010,11 @@
8001
8010
  // (a) Swap 2 rows. This multiply the determinant by -1.
8002
8011
  // (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
8003
8012
  // (c) Add to a row a multiple of another row. This does not change the determinant.
8013
+ if (M.length < 1 || M[0].length < 1) {
8014
+ throw new Error("invertMatrix: an empty matrix cannot be inverted.");
8015
+ }
8004
8016
  if (M.length !== M[0].length) {
8005
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] invert matrix error, only square matrices are invertible"));
8017
+ throw new Error("invertMatrix: only square matrices are invertible");
8006
8018
  }
8007
8019
  let determinant = 1;
8008
8020
  const dim = M.length;
@@ -8071,8 +8083,11 @@
8071
8083
  * Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
8072
8084
  */
8073
8085
  function multiplyMatrices(matrix1, matrix2) {
8086
+ if (matrix1.length < 1 || matrix2.length < 1) {
8087
+ throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
8088
+ }
8074
8089
  if (matrix1.length !== matrix2[0].length) {
8075
- throw new EvaluationError(_t("Cannot multiply matrices : incompatible matrices size."));
8090
+ throw new Error("multiplyMatrices: incompatible matrices size.");
8076
8091
  }
8077
8092
  const rowsM1 = matrix1[0].length;
8078
8093
  const colsM2 = matrix2.length;
@@ -8098,7 +8113,7 @@
8098
8113
  return arg;
8099
8114
  }
8100
8115
  if (!isSingleElementMatrix(arg)) {
8101
- throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
8116
+ throw new Error("The value should be a scalar or a 1x1 matrix");
8102
8117
  }
8103
8118
  return arg[0][0];
8104
8119
  }
@@ -11237,6 +11252,9 @@ stores.inject(MyMetaStore, storeInstance);
11237
11252
  compute: function (matrix1, matrix2) {
11238
11253
  const _matrix1 = toNumberMatrix(matrix1, "matrix1");
11239
11254
  const _matrix2 = toNumberMatrix(matrix2, "matrix2");
11255
+ if (_matrix1.length === 0 || _matrix2.length === 0) {
11256
+ return new EvaluationError(_t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
11257
+ }
11240
11258
  if (_matrix1.length !== _matrix2[0].length) {
11241
11259
  return new EvaluationError(_t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
11242
11260
  number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
@@ -12849,7 +12867,7 @@ stores.inject(MyMetaStore, storeInstance);
12849
12867
  count++;
12850
12868
  }
12851
12869
  });
12852
- assert(count !== 0, _t("[[FUNCTION_NAME]] has no valid input data."));
12870
+ assert(count !== 0, noValidInputErrorMessage);
12853
12871
  if (!isInclusive) {
12854
12872
  // 2nd argument must be between 1/(n+1) and n/(n+1) with n the number of data
12855
12873
  assert(1 / (count + 1) <= _percent && _percent <= count / (count + 1), _t("Function [[FUNCTION_NAME]] parameter 2 value is out of range."));
@@ -13124,6 +13142,9 @@ stores.inject(MyMetaStore, storeInstance);
13124
13142
  ],
13125
13143
  compute: function (x, dataY, dataX) {
13126
13144
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13145
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13146
+ return new NotAvailableError(noValidInputErrorMessage);
13147
+ }
13127
13148
  return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
13128
13149
  },
13129
13150
  isExported: true,
@@ -13140,6 +13161,9 @@ stores.inject(MyMetaStore, storeInstance);
13140
13161
  arg("b (boolean, default=TRUE)", _t("Given a general exponential form of y = b*m^x for a curve fit, calculates b if TRUE or forces b to be 1 and only calculates the m values if FALSE.")),
13141
13162
  ],
13142
13163
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13164
+ if (knownDataY.length === 0 || knownDataY[0].length === 0) {
13165
+ return new EvaluationError(emptyDataErrorMessage("known_data_y"));
13166
+ }
13143
13167
  return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "the first argument (known_data_y)")), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
13144
13168
  },
13145
13169
  };
@@ -13154,6 +13178,9 @@ stores.inject(MyMetaStore, storeInstance);
13154
13178
  ],
13155
13179
  compute: function (dataY, dataX) {
13156
13180
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13181
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13182
+ return new NotAvailableError(noValidInputErrorMessage);
13183
+ }
13157
13184
  const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
13158
13185
  return intercept;
13159
13186
  },
@@ -13186,7 +13213,7 @@ stores.inject(MyMetaStore, storeInstance);
13186
13213
  });
13187
13214
  const result = largests.shift();
13188
13215
  if (result === undefined) {
13189
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
13216
+ return new EvaluationError(noValidInputErrorMessage);
13190
13217
  }
13191
13218
  if (count < _n) {
13192
13219
  return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
@@ -13207,6 +13234,9 @@ stores.inject(MyMetaStore, storeInstance);
13207
13234
  arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
13208
13235
  ],
13209
13236
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13237
+ if (dataY.length === 0 || dataY[0].length === 0) {
13238
+ return new EvaluationError(emptyDataErrorMessage("data_y"));
13239
+ }
13210
13240
  return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13211
13241
  },
13212
13242
  isExported: true,
@@ -13223,6 +13253,9 @@ stores.inject(MyMetaStore, storeInstance);
13223
13253
  arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
13224
13254
  ],
13225
13255
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13256
+ if (dataY.length === 0 || dataY[0].length === 0) {
13257
+ return new EvaluationError(emptyDataErrorMessage("data_y"));
13258
+ }
13226
13259
  const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13227
13260
  for (let i = 0; i < coeffs.length; i++) {
13228
13261
  coeffs[i][0] = Math.exp(coeffs[i][0]);
@@ -13244,8 +13277,8 @@ stores.inject(MyMetaStore, storeInstance);
13244
13277
  const flatX = dataX.flat();
13245
13278
  const flatY = dataY.flat();
13246
13279
  assertSameNumberOfElements(flatX, flatY);
13247
- if (flatX.length === 0) {
13248
- return new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13280
+ if (flatX.length === 0 || flatY.length === 0) {
13281
+ return new NotAvailableError(noValidInputErrorMessage);
13249
13282
  }
13250
13283
  const n = flatX.length;
13251
13284
  let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
@@ -13410,11 +13443,8 @@ stores.inject(MyMetaStore, storeInstance);
13410
13443
  // -----------------------------------------------------------------------------
13411
13444
  function pearson(dataY, dataX) {
13412
13445
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13413
- if (flatDataX.length === 0) {
13414
- throw new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13415
- }
13416
- if (flatDataX.length < 2) {
13417
- throw new EvaluationError(_t("[[FUNCTION_NAME]] needs at least two values for both parameters."));
13446
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13447
+ return new NotAvailableError(noValidInputErrorMessage);
13418
13448
  }
13419
13449
  const n = flatDataX.length;
13420
13450
  let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
@@ -13504,6 +13534,9 @@ stores.inject(MyMetaStore, storeInstance);
13504
13534
  ],
13505
13535
  compute: function (dataY, dataX, order, intercept = { value: true }) {
13506
13536
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13537
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13538
+ return new NotAvailableError(noValidInputErrorMessage);
13539
+ }
13507
13540
  return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
13508
13541
  },
13509
13542
  isExported: false,
@@ -13523,6 +13556,9 @@ stores.inject(MyMetaStore, storeInstance);
13523
13556
  compute: function (x, dataY, dataX, order, intercept = { value: true }) {
13524
13557
  const _order = toNumber(order, this.locale);
13525
13558
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13559
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13560
+ return new NotAvailableError(noValidInputErrorMessage);
13561
+ }
13526
13562
  const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
13527
13563
  return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
13528
13564
  },
@@ -13624,7 +13660,11 @@ stores.inject(MyMetaStore, storeInstance);
13624
13660
  arg("data_x (range<number>)", _t("The range representing the array or matrix of independent data.")),
13625
13661
  ],
13626
13662
  compute: function (dataY, dataX) {
13627
- return Math.pow(pearson(dataX, dataY), 2.0);
13663
+ const value = pearson(dataY, dataX);
13664
+ if (value instanceof Error) {
13665
+ throw value;
13666
+ }
13667
+ return Math.pow(value, 2.0);
13628
13668
  },
13629
13669
  isExported: true,
13630
13670
  };
@@ -13639,6 +13679,9 @@ stores.inject(MyMetaStore, storeInstance);
13639
13679
  ],
13640
13680
  compute: function (dataY, dataX) {
13641
13681
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13682
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13683
+ return new NotAvailableError(noValidInputErrorMessage);
13684
+ }
13642
13685
  const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
13643
13686
  return slope;
13644
13687
  },
@@ -13671,7 +13714,7 @@ stores.inject(MyMetaStore, storeInstance);
13671
13714
  });
13672
13715
  const result = largests.pop();
13673
13716
  if (result === undefined) {
13674
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
13717
+ return new EvaluationError(noValidInputErrorMessage);
13675
13718
  }
13676
13719
  if (count < _n) {
13677
13720
  return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
@@ -13691,6 +13734,9 @@ stores.inject(MyMetaStore, storeInstance);
13691
13734
  ],
13692
13735
  compute: function (dataX, dataY) {
13693
13736
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13737
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13738
+ return new NotAvailableError(noValidInputErrorMessage);
13739
+ }
13694
13740
  const n = flatDataX.length;
13695
13741
  const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
13696
13742
  order.sort((a, b) => a[0] - b[0]);
@@ -13801,6 +13847,9 @@ stores.inject(MyMetaStore, storeInstance);
13801
13847
  ],
13802
13848
  compute: function (dataY, dataX) {
13803
13849
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13850
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13851
+ return new NotAvailableError(noValidInputErrorMessage);
13852
+ }
13804
13853
  const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
13805
13854
  return data[1][2];
13806
13855
  },
@@ -13818,6 +13867,9 @@ stores.inject(MyMetaStore, storeInstance);
13818
13867
  arg("b (boolean, optional, default=TRUE)", _t("Given a general linear form of y = m*x+b for a curve fit, calculates b if TRUE or forces b to be 0 and only calculates the m values if FALSE, i.e. forces the curve fit to pass through the origin.")),
13819
13868
  ],
13820
13869
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13870
+ if (knownDataY.length === 0 || knownDataY[0].length === 0) {
13871
+ return new EvaluationError(emptyDataErrorMessage("known_data_y"));
13872
+ }
13821
13873
  return predictLinearValues(toNumberMatrix(knownDataY, "the first argument (known_data_y)"), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
13822
13874
  },
13823
13875
  };
@@ -18733,7 +18785,7 @@ stores.inject(MyMetaStore, storeInstance);
18733
18785
  compute: function (...logicalExpressions) {
18734
18786
  const { result, foundBoolean } = boolAnd(logicalExpressions);
18735
18787
  if (!foundBoolean) {
18736
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
18788
+ return new EvaluationError(noValidInputErrorMessage);
18737
18789
  }
18738
18790
  return result;
18739
18791
  },
@@ -18859,7 +18911,7 @@ stores.inject(MyMetaStore, storeInstance);
18859
18911
  compute: function (...logicalExpressions) {
18860
18912
  const { result, foundBoolean } = boolOr(logicalExpressions);
18861
18913
  if (!foundBoolean) {
18862
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
18914
+ return new EvaluationError(noValidInputErrorMessage);
18863
18915
  }
18864
18916
  return result;
18865
18917
  },
@@ -18922,7 +18974,7 @@ stores.inject(MyMetaStore, storeInstance);
18922
18974
  return true; // no stop condition
18923
18975
  });
18924
18976
  if (!foundBoolean) {
18925
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
18977
+ return new EvaluationError(noValidInputErrorMessage);
18926
18978
  }
18927
18979
  return acc;
18928
18980
  },
@@ -21386,7 +21438,7 @@ stores.inject(MyMetaStore, storeInstance);
21386
21438
  function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
21387
21439
  const sheetName = splitReference(sheetXC).sheetName;
21388
21440
  if (sheetName
21389
- ? !isSheetNameEqual(sheetName, applyChange.sheetName)
21441
+ ? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
21390
21442
  : defaultSheetId !== applyChange.sheetId) {
21391
21443
  return sheetXC;
21392
21444
  }
@@ -21403,7 +21455,7 @@ stores.inject(MyMetaStore, storeInstance);
21403
21455
  }
21404
21456
  function getSheetNameGetter(applyChange) {
21405
21457
  return (sheetId) => {
21406
- return sheetId === applyChange.sheetId ? applyChange.sheetName : "";
21458
+ return sheetId === applyChange.sheetId ? applyChange.sheetName.current : "";
21407
21459
  };
21408
21460
  }
21409
21461
  function defaultGetSheetSize(sheetId) {
@@ -27394,9 +27446,13 @@ stores.inject(MyMetaStore, storeInstance);
27394
27446
  : undefined,
27395
27447
  };
27396
27448
  }
27397
- updateRanges(applyChange) {
27449
+ updateRanges(applyChange, sheetId, adaptSheetName) {
27398
27450
  const dataRange = adaptChartRange(this.dataRange, applyChange);
27399
- const adaptFormula = (formula) => this.getters.adaptFormulaStringDependencies(this.sheetId, formula, applyChange);
27451
+ const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
27452
+ applyChange,
27453
+ sheetId,
27454
+ sheetName: adaptSheetName,
27455
+ });
27400
27456
  const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
27401
27457
  const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
27402
27458
  return new GaugeChart(definition, this.sheetId, this.getters);
@@ -33719,6 +33775,9 @@ stores.inject(MyMetaStore, storeInstance);
33719
33775
  this.contentHelper.removeSelection();
33720
33776
  }
33721
33777
  onMouseup() {
33778
+ if (this.env.model.getters.isReadonly()) {
33779
+ return;
33780
+ }
33722
33781
  const selection = this.contentHelper.getCurrentSelection();
33723
33782
  if (selection.start !== selection.end) {
33724
33783
  this.props.composerStore.hoverToken(undefined);
@@ -38182,9 +38241,9 @@ stores.inject(MyMetaStore, storeInstance);
38182
38241
  if (!rule.operator || !rule.formula || rule.formula.length === 0)
38183
38242
  continue;
38184
38243
  operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
38185
- values.push(rule.formula[0]);
38244
+ values.push(prefixFormula(rule.formula[0]));
38186
38245
  if (rule.formula.length === 2) {
38187
- values.push(rule.formula[1]);
38246
+ values.push(prefixFormula(rule.formula[1]));
38188
38247
  }
38189
38248
  break;
38190
38249
  }
@@ -38342,6 +38401,11 @@ stores.inject(MyMetaStore, storeInstance);
38342
38401
  ? ICON_SETS[iconSet].neutral
38343
38402
  : ICON_SETS[iconSet].good;
38344
38403
  }
38404
+ /** Prefix the string by "=" if the string looks like a formula */
38405
+ function prefixFormula(formula) {
38406
+ const tokens = tokenize(formula);
38407
+ return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
38408
+ }
38345
38409
  // ---------------------------------------------------------------------------
38346
38410
  // Warnings
38347
38411
  // ---------------------------------------------------------------------------
@@ -38624,7 +38688,7 @@ stores.inject(MyMetaStore, storeInstance);
38624
38688
  function getRowPosition(rowIndex, sheetData) {
38625
38689
  let position = 0;
38626
38690
  for (let i = 0; i < rowIndex; i++) {
38627
- const rowAtIndex = sheetData.rows[i];
38691
+ const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
38628
38692
  if (rowAtIndex?.height) {
38629
38693
  position += rowAtIndex.height;
38630
38694
  }
@@ -38779,8 +38843,8 @@ stores.inject(MyMetaStore, storeInstance);
38779
38843
  }
38780
38844
  function convertAnchor(XLSXanchor) {
38781
38845
  const offset = {
38782
- x: convertEMUToDotValue(XLSXanchor.colOffset),
38783
- y: convertEMUToDotValue(XLSXanchor.rowOffset),
38846
+ x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
38847
+ y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
38784
38848
  };
38785
38849
  return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
38786
38850
  }
@@ -39163,8 +39227,12 @@ stores.inject(MyMetaStore, storeInstance);
39163
39227
  dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
39164
39228
  dims[1] = Math.max(dims[1], row.index);
39165
39229
  }
39166
- dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
39167
- dims[1] = Math.max(dims[1], EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
39230
+ for (const fig of sheet.figures) {
39231
+ dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
39232
+ dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
39233
+ }
39234
+ dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
39235
+ dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
39168
39236
  return dims;
39169
39237
  }
39170
39238
  /**
@@ -40867,7 +40935,7 @@ stores.inject(MyMetaStore, storeInstance);
40867
40935
  return relsFile;
40868
40936
  }
40869
40937
 
40870
- const EXCEL_IMPORT_VERSION = "18.4.1";
40938
+ const EXCEL_IMPORT_VERSION = "18.4.2";
40871
40939
  class XlsxReader {
40872
40940
  warningManager;
40873
40941
  xmls;
@@ -44412,7 +44480,7 @@ stores.inject(MyMetaStore, storeInstance);
44412
44480
  const reinsertDynamicPivotMenu = {
44413
44481
  id: "reinsert_dynamic_pivot",
44414
44482
  name: _t("Re-insert dynamic pivot"),
44415
- sequence: 1020,
44483
+ sequence: 60,
44416
44484
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
44417
44485
  children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
44418
44486
  isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
@@ -44420,7 +44488,7 @@ stores.inject(MyMetaStore, storeInstance);
44420
44488
  const reinsertStaticPivotMenu = {
44421
44489
  id: "reinsert_static_pivot",
44422
44490
  name: _t("Re-insert static pivot"),
44423
- sequence: 1020,
44491
+ sequence: 70,
44424
44492
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
44425
44493
  children: [REINSERT_STATIC_PIVOT_CHILDREN],
44426
44494
  isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
@@ -58691,7 +58759,8 @@ stores.inject(MyMetaStore, storeInstance);
58691
58759
  * the type of change that occurred.
58692
58760
  *
58693
58761
  * @param applyChange a function that, when called, will adapt the range according to the change on the grid
58694
- * @param sheetId an optional sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
58762
+ * @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
58763
+ * @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
58695
58764
  */
58696
58765
  adaptRanges(applyChange, sheetId, sheetName) { }
58697
58766
  /**
@@ -59294,9 +59363,7 @@ stores.inject(MyMetaStore, storeInstance);
59294
59363
  for (const cell of Object.values(this.cells[sheet] || {})) {
59295
59364
  if (cell.isFormula) {
59296
59365
  for (const range of cell.compiledFormula.dependencies) {
59297
- if (!sheetId ||
59298
- range.sheetId === sheetId ||
59299
- (sheetName && range.invalidSheetName === sheetName)) {
59366
+ if (range.sheetId === sheetId || range.invalidSheetName === sheetName.old) {
59300
59367
  const change = applyChange(range);
59301
59368
  if (change.changeType !== "NONE") {
59302
59369
  this.history.update("cells", sheet, cell.id, "compiledFormula", "dependencies", cell.compiledFormula.dependencies.indexOf(range), change.range);
@@ -59912,9 +59979,9 @@ stores.inject(MyMetaStore, storeInstance);
59912
59979
  charts = {};
59913
59980
  createChart = chartFactory(this.getters);
59914
59981
  validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
59915
- adaptRanges(applyChange) {
59982
+ adaptRanges(applyChange, sheetId, adaptSheetName) {
59916
59983
  for (const [chartId, chart] of Object.entries(this.charts)) {
59917
- this.history.update("charts", chartId, chart?.updateRanges(applyChange));
59984
+ this.history.update("charts", chartId, chart?.updateRanges(applyChange, sheetId, adaptSheetName));
59918
59985
  }
59919
59986
  }
59920
59987
  // ---------------------------------------------------------------------------
@@ -60177,7 +60244,7 @@ stores.inject(MyMetaStore, storeInstance);
60177
60244
  }
60178
60245
  }
60179
60246
  }
60180
- adaptRanges(applyChange, sheetId, sheetName) {
60247
+ adaptRanges(applyChange, sheetId) {
60181
60248
  const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
60182
60249
  for (const sheetId of sheetIds) {
60183
60250
  this.adaptCFRanges(sheetId, applyChange);
@@ -60559,11 +60626,8 @@ stores.inject(MyMetaStore, storeInstance);
60559
60626
  "getValidationRuleForCell",
60560
60627
  ];
60561
60628
  rules = {};
60562
- adaptRanges(applyChange, sheetId, sheetName) {
60563
- const sheetIds = sheetId ? [sheetId] : Object.keys(this.rules);
60564
- for (const sheetId of sheetIds) {
60565
- this.adaptDVRanges(sheetId, applyChange);
60566
- }
60629
+ adaptRanges(applyChange, sheetId) {
60630
+ this.adaptDVRanges(sheetId, applyChange);
60567
60631
  this.adaptDVFormulas(applyChange);
60568
60632
  }
60569
60633
  adaptDVFormulas(applyChange) {
@@ -60853,9 +60917,6 @@ stores.inject(MyMetaStore, storeInstance);
60853
60917
  // Command Handling
60854
60918
  // ---------------------------------------------------------------------------
60855
60919
  adaptRanges(applyChange, sheetId) {
60856
- if (!sheetId) {
60857
- return;
60858
- }
60859
60920
  for (const figure of this.getFigures(sheetId)) {
60860
60921
  const change = applyChange(this.getters.getRangeFromZone(sheetId, {
60861
60922
  left: figure.col,
@@ -61664,11 +61725,8 @@ stores.inject(MyMetaStore, storeInstance);
61664
61725
  break;
61665
61726
  }
61666
61727
  }
61667
- adaptRanges(applyChange, sheetId, sheetName) {
61668
- const sheetIds = sheetId ? [sheetId] : Object.keys(this.merges);
61669
- for (const sheetId of sheetIds) {
61670
- this.applyRangeChangeOnSheet(sheetId, applyChange);
61671
- }
61728
+ adaptRanges(applyChange, sheetId) {
61729
+ this.applyRangeChangeOnSheet(sheetId, applyChange);
61672
61730
  }
61673
61731
  // ---------------------------------------------------------------------------
61674
61732
  // Getters
@@ -63173,12 +63231,9 @@ stores.inject(MyMetaStore, storeInstance);
63173
63231
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
63174
63232
  tables = {};
63175
63233
  nextTableId = 1;
63176
- adaptRanges(applyChange, sheetId, sheetName) {
63177
- const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
63178
- for (const sheetId of sheetIds) {
63179
- for (const table of this.getCoreTables(sheetId)) {
63180
- this.applyRangeChangeOnTable(sheetId, table, applyChange);
63181
- }
63234
+ adaptRanges(applyChange, sheetId) {
63235
+ for (const table of this.getCoreTables(sheetId)) {
63236
+ this.applyRangeChangeOnTable(sheetId, table, applyChange);
63182
63237
  }
63183
63238
  }
63184
63239
  allowDispatch(cmd) {
@@ -64141,7 +64196,7 @@ stores.inject(MyMetaStore, storeInstance);
64141
64196
  }
64142
64197
  }
64143
64198
  }
64144
- adaptRanges(applyChange, sheetId, sheetName) {
64199
+ adaptRanges(applyChange) {
64145
64200
  for (const sheetId in this.compiledMeasureFormulas) {
64146
64201
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
64147
64202
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -68542,7 +68597,7 @@ stores.inject(MyMetaStore, storeInstance);
68542
68597
  if (!result) {
68543
68598
  return EMPTY_PIVOT_CELL;
68544
68599
  }
68545
- const { functionName, args } = result;
68600
+ let { functionName, args } = result;
68546
68601
  const formulaId = args[0];
68547
68602
  if (!formulaId) {
68548
68603
  return EMPTY_PIVOT_CELL;
@@ -68577,6 +68632,9 @@ stores.inject(MyMetaStore, storeInstance);
68577
68632
  return pivotCells[pivotCol][pivotRow];
68578
68633
  }
68579
68634
  try {
68635
+ const offsetRow = position.row - mainPosition.row;
68636
+ const offsetCol = position.col - mainPosition.col;
68637
+ args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
68580
68638
  if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
68581
68639
  const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
68582
68640
  return {
@@ -70185,7 +70243,8 @@ stores.inject(MyMetaStore, storeInstance);
70185
70243
  // If the executed command is not in the registry, we skip it
70186
70244
  // because we know there won't be any transformation impacting the
70187
70245
  // commands to transform.
70188
- if (possibleTransformations.has(executedCommand.type)) {
70246
+ if (possibleTransformations.has(executedCommand.type) ||
70247
+ rangeAdapterRegistry.contains(executedCommand.type)) {
70189
70248
  transformedCommands = transformedCommands.reduce((acc, cmd) => {
70190
70249
  const transformed = transform(cmd, executedCommand);
70191
70250
  if (transformed) {
@@ -76177,7 +76236,8 @@ stores.inject(MyMetaStore, storeInstance);
76177
76236
  .add("HIDE_COLUMNS_ROWS", inverseHideColumnsRows)
76178
76237
  .add("UNHIDE_COLUMNS_ROWS", inverseUnhideColumnsRows)
76179
76238
  .add("CREATE_TABLE_STYLE", inverseCreateTableStyle)
76180
- .add("ADD_PIVOT", inverseAddPivot);
76239
+ .add("ADD_PIVOT", inverseAddPivot)
76240
+ .add("RENAME_SHEET", inverseRenameSheet);
76181
76241
  for (const cmd of coreTypes.values()) {
76182
76242
  if (!inverseCommandRegistry.contains(cmd)) {
76183
76243
  inverseCommandRegistry.add(cmd, identity);
@@ -76275,6 +76335,16 @@ stores.inject(MyMetaStore, storeInstance);
76275
76335
  function inverseCreateTableStyle(cmd) {
76276
76336
  return [{ type: "REMOVE_TABLE_STYLE", tableStyleId: cmd.tableStyleId }];
76277
76337
  }
76338
+ function inverseRenameSheet(cmd) {
76339
+ return [
76340
+ {
76341
+ type: "RENAME_SHEET",
76342
+ sheetId: cmd.sheetId,
76343
+ oldName: cmd.newName,
76344
+ newName: cmd.oldName,
76345
+ },
76346
+ ];
76347
+ }
76278
76348
 
76279
76349
  const numberFormatMenuRegistry = new Registry();
76280
76350
  numberFormatMenuRegistry
@@ -76873,8 +76943,9 @@ stores.inject(MyMetaStore, storeInstance);
76873
76943
  sequence: 40,
76874
76944
  separator: true,
76875
76945
  })
76876
- .addChild("data_sources_data", ["data"], (env) => {
76946
+ .addChild("pivot_data_sources", ["data"], (env) => {
76877
76947
  const sequence = 50;
76948
+ const numberOfPivots = env.model.getters.getPivotIds().length;
76878
76949
  return env.model.getters.getPivotIds().map((pivotId, index) => {
76879
76950
  const highlightProvider = {
76880
76951
  get highlights() {
@@ -76884,7 +76955,7 @@ stores.inject(MyMetaStore, storeInstance);
76884
76955
  return {
76885
76956
  id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
76886
76957
  name: env.model.getters.getPivotDisplayName(pivotId),
76887
- sequence: sequence + index,
76958
+ sequence: sequence + index / numberOfPivots,
76888
76959
  isReadonlyAllowed: true,
76889
76960
  execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
76890
76961
  isEnabled: (env) => !env.isSmall,
@@ -83004,7 +83075,7 @@ stores.inject(MyMetaStore, storeInstance);
83004
83075
  for (const [headerIndex, header] of headers.slice(anchor).entries()) {
83005
83076
  if (currentPosition <= offset && offset < currentPosition + header.size) {
83006
83077
  return {
83007
- index: headerIndex,
83078
+ index: anchor + headerIndex,
83008
83079
  offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
83009
83080
  };
83010
83081
  }
@@ -84000,7 +84071,7 @@ stores.inject(MyMetaStore, storeInstance);
84000
84071
  handlers = [];
84001
84072
  uiHandlers = [];
84002
84073
  coreHandlers = [];
84003
- constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = false) {
84074
+ constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
84004
84075
  const start = performance.now();
84005
84076
  console.debug("##### Model creation #####");
84006
84077
  super();
@@ -84750,9 +84821,9 @@ stores.inject(MyMetaStore, storeInstance);
84750
84821
  exports.tokenize = tokenize;
84751
84822
 
84752
84823
 
84753
- __info__.version = "18.4.8";
84754
- __info__.date = "2025-08-26T10:14:08.954Z";
84755
- __info__.hash = "746217a";
84824
+ __info__.version = "18.4.9";
84825
+ __info__.date = "2025-09-05T07:38:32.126Z";
84826
+ __info__.hash = "a261873";
84756
84827
 
84757
84828
 
84758
84829
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);