@odoo/o-spreadsheet 18.4.8 → 18.4.10

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.10
6
+ * @date 2025-09-11T08:45:39.178Z
7
+ * @hash 15a11a4
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";
@@ -7346,7 +7355,7 @@
7346
7355
  this.getters = getters;
7347
7356
  this.dispatch = dispatch;
7348
7357
  }
7349
- copy(data, isCutOperation) {
7358
+ copy(data, isCutOperation, mode = "copyPaste") {
7350
7359
  return;
7351
7360
  }
7352
7361
  paste(target, clippedContent, options) { }
@@ -7365,7 +7374,7 @@
7365
7374
  }
7366
7375
 
7367
7376
  class AbstractCellClipboardHandler extends ClipboardHandler {
7368
- copy(data) {
7377
+ copy(data, isCutOperation, mode = "copyPaste") {
7369
7378
  return;
7370
7379
  }
7371
7380
  pasteFromCopy(sheetId, target, content, options) {
@@ -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
  }
@@ -8889,7 +8904,7 @@
8889
8904
  }
8890
8905
  return "Success" /* CommandResult.Success */;
8891
8906
  }
8892
- copy(data) {
8907
+ copy(data, isCutOperation, mode = "copyPaste") {
8893
8908
  const sheetId = data.sheetId;
8894
8909
  const { clippedZones, rowsIndexes, columnsIndexes } = data;
8895
8910
  const clippedCells = [];
@@ -8902,7 +8917,7 @@
8902
8917
  const evaluatedCell = this.getters.getEvaluatedCell(position);
8903
8918
  const pivotId = this.getters.getPivotIdFromPosition(position);
8904
8919
  const spreader = this.getters.getArrayFormulaSpreadingOn(position);
8905
- if (pivotId && spreader) {
8920
+ if (mode !== "shiftCells" && pivotId && spreader) {
8906
8921
  const pivotZone = this.getters.getSpreadZone(spreader);
8907
8922
  if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
8908
8923
  pivotZone &&
@@ -8920,7 +8935,7 @@
8920
8935
  };
8921
8936
  }
8922
8937
  }
8923
- else {
8938
+ else if (mode !== "shiftCells") {
8924
8939
  if (spreader && !deepEquals(spreader, position)) {
8925
8940
  const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
8926
8941
  const content = isSpreaderCopied
@@ -9618,7 +9633,7 @@
9618
9633
  }
9619
9634
 
9620
9635
  class TableClipboardHandler extends AbstractCellClipboardHandler {
9621
- copy(data, isCutOperation) {
9636
+ copy(data, isCutOperation, mode = "copyPaste") {
9622
9637
  const sheetId = data.sheetId;
9623
9638
  const { rowsIndexes, columnsIndexes, zones } = data;
9624
9639
  const copiedTablesIds = new Set();
@@ -9656,11 +9671,13 @@
9656
9671
  type: coreTable.type,
9657
9672
  };
9658
9673
  }
9659
- tableCellsInRow.push({
9660
- table: copiedTable,
9661
- style: this.getTableStyleToCopy(position),
9662
- isWholeTableCopied: copiedTablesIds.has(table.id),
9663
- });
9674
+ if (mode !== "shiftCells") {
9675
+ tableCellsInRow.push({
9676
+ table: copiedTable,
9677
+ style: this.getTableStyleToCopy(position),
9678
+ isWholeTableCopied: copiedTablesIds.has(table.id),
9679
+ });
9680
+ }
9664
9681
  }
9665
9682
  }
9666
9683
  return {
@@ -11237,6 +11254,9 @@ stores.inject(MyMetaStore, storeInstance);
11237
11254
  compute: function (matrix1, matrix2) {
11238
11255
  const _matrix1 = toNumberMatrix(matrix1, "matrix1");
11239
11256
  const _matrix2 = toNumberMatrix(matrix2, "matrix2");
11257
+ if (_matrix1.length === 0 || _matrix2.length === 0) {
11258
+ return new EvaluationError(_t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
11259
+ }
11240
11260
  if (_matrix1.length !== _matrix2[0].length) {
11241
11261
  return new EvaluationError(_t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
11242
11262
  number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
@@ -12849,7 +12869,7 @@ stores.inject(MyMetaStore, storeInstance);
12849
12869
  count++;
12850
12870
  }
12851
12871
  });
12852
- assert(count !== 0, _t("[[FUNCTION_NAME]] has no valid input data."));
12872
+ assert(count !== 0, noValidInputErrorMessage);
12853
12873
  if (!isInclusive) {
12854
12874
  // 2nd argument must be between 1/(n+1) and n/(n+1) with n the number of data
12855
12875
  assert(1 / (count + 1) <= _percent && _percent <= count / (count + 1), _t("Function [[FUNCTION_NAME]] parameter 2 value is out of range."));
@@ -13124,6 +13144,9 @@ stores.inject(MyMetaStore, storeInstance);
13124
13144
  ],
13125
13145
  compute: function (x, dataY, dataX) {
13126
13146
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13147
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13148
+ return new NotAvailableError(noValidInputErrorMessage);
13149
+ }
13127
13150
  return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
13128
13151
  },
13129
13152
  isExported: true,
@@ -13140,6 +13163,9 @@ stores.inject(MyMetaStore, storeInstance);
13140
13163
  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
13164
  ],
13142
13165
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13166
+ if (knownDataY.length === 0 || knownDataY[0].length === 0) {
13167
+ return new EvaluationError(emptyDataErrorMessage("known_data_y"));
13168
+ }
13143
13169
  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
13170
  },
13145
13171
  };
@@ -13154,6 +13180,9 @@ stores.inject(MyMetaStore, storeInstance);
13154
13180
  ],
13155
13181
  compute: function (dataY, dataX) {
13156
13182
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13183
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13184
+ return new NotAvailableError(noValidInputErrorMessage);
13185
+ }
13157
13186
  const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
13158
13187
  return intercept;
13159
13188
  },
@@ -13186,7 +13215,7 @@ stores.inject(MyMetaStore, storeInstance);
13186
13215
  });
13187
13216
  const result = largests.shift();
13188
13217
  if (result === undefined) {
13189
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
13218
+ return new EvaluationError(noValidInputErrorMessage);
13190
13219
  }
13191
13220
  if (count < _n) {
13192
13221
  return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
@@ -13207,6 +13236,9 @@ stores.inject(MyMetaStore, storeInstance);
13207
13236
  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
13237
  ],
13209
13238
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13239
+ if (dataY.length === 0 || dataY[0].length === 0) {
13240
+ return new EvaluationError(emptyDataErrorMessage("data_y"));
13241
+ }
13210
13242
  return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13211
13243
  },
13212
13244
  isExported: true,
@@ -13223,6 +13255,9 @@ stores.inject(MyMetaStore, storeInstance);
13223
13255
  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
13256
  ],
13225
13257
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13258
+ if (dataY.length === 0 || dataY[0].length === 0) {
13259
+ return new EvaluationError(emptyDataErrorMessage("data_y"));
13260
+ }
13226
13261
  const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13227
13262
  for (let i = 0; i < coeffs.length; i++) {
13228
13263
  coeffs[i][0] = Math.exp(coeffs[i][0]);
@@ -13244,8 +13279,8 @@ stores.inject(MyMetaStore, storeInstance);
13244
13279
  const flatX = dataX.flat();
13245
13280
  const flatY = dataY.flat();
13246
13281
  assertSameNumberOfElements(flatX, flatY);
13247
- if (flatX.length === 0) {
13248
- return new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13282
+ if (flatX.length === 0 || flatY.length === 0) {
13283
+ return new NotAvailableError(noValidInputErrorMessage);
13249
13284
  }
13250
13285
  const n = flatX.length;
13251
13286
  let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
@@ -13410,11 +13445,8 @@ stores.inject(MyMetaStore, storeInstance);
13410
13445
  // -----------------------------------------------------------------------------
13411
13446
  function pearson(dataY, dataX) {
13412
13447
  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."));
13448
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13449
+ return new NotAvailableError(noValidInputErrorMessage);
13418
13450
  }
13419
13451
  const n = flatDataX.length;
13420
13452
  let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
@@ -13504,6 +13536,9 @@ stores.inject(MyMetaStore, storeInstance);
13504
13536
  ],
13505
13537
  compute: function (dataY, dataX, order, intercept = { value: true }) {
13506
13538
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13539
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13540
+ return new NotAvailableError(noValidInputErrorMessage);
13541
+ }
13507
13542
  return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
13508
13543
  },
13509
13544
  isExported: false,
@@ -13523,6 +13558,9 @@ stores.inject(MyMetaStore, storeInstance);
13523
13558
  compute: function (x, dataY, dataX, order, intercept = { value: true }) {
13524
13559
  const _order = toNumber(order, this.locale);
13525
13560
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13561
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13562
+ return new NotAvailableError(noValidInputErrorMessage);
13563
+ }
13526
13564
  const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
13527
13565
  return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
13528
13566
  },
@@ -13624,7 +13662,11 @@ stores.inject(MyMetaStore, storeInstance);
13624
13662
  arg("data_x (range<number>)", _t("The range representing the array or matrix of independent data.")),
13625
13663
  ],
13626
13664
  compute: function (dataY, dataX) {
13627
- return Math.pow(pearson(dataX, dataY), 2.0);
13665
+ const value = pearson(dataY, dataX);
13666
+ if (value instanceof Error) {
13667
+ throw value;
13668
+ }
13669
+ return Math.pow(value, 2.0);
13628
13670
  },
13629
13671
  isExported: true,
13630
13672
  };
@@ -13639,6 +13681,9 @@ stores.inject(MyMetaStore, storeInstance);
13639
13681
  ],
13640
13682
  compute: function (dataY, dataX) {
13641
13683
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13684
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13685
+ return new NotAvailableError(noValidInputErrorMessage);
13686
+ }
13642
13687
  const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
13643
13688
  return slope;
13644
13689
  },
@@ -13671,7 +13716,7 @@ stores.inject(MyMetaStore, storeInstance);
13671
13716
  });
13672
13717
  const result = largests.pop();
13673
13718
  if (result === undefined) {
13674
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
13719
+ return new EvaluationError(noValidInputErrorMessage);
13675
13720
  }
13676
13721
  if (count < _n) {
13677
13722
  return new EvaluationError(_t("Function [[FUNCTION_NAME]] parameter 2 value (%s) is out of range.", _n));
@@ -13691,6 +13736,9 @@ stores.inject(MyMetaStore, storeInstance);
13691
13736
  ],
13692
13737
  compute: function (dataX, dataY) {
13693
13738
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13739
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13740
+ return new NotAvailableError(noValidInputErrorMessage);
13741
+ }
13694
13742
  const n = flatDataX.length;
13695
13743
  const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
13696
13744
  order.sort((a, b) => a[0] - b[0]);
@@ -13801,6 +13849,9 @@ stores.inject(MyMetaStore, storeInstance);
13801
13849
  ],
13802
13850
  compute: function (dataY, dataX) {
13803
13851
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13852
+ if (flatDataX.length === 0 || flatDataY.length === 0) {
13853
+ return new NotAvailableError(noValidInputErrorMessage);
13854
+ }
13804
13855
  const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
13805
13856
  return data[1][2];
13806
13857
  },
@@ -13818,6 +13869,9 @@ stores.inject(MyMetaStore, storeInstance);
13818
13869
  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
13870
  ],
13820
13871
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13872
+ if (knownDataY.length === 0 || knownDataY[0].length === 0) {
13873
+ return new EvaluationError(emptyDataErrorMessage("known_data_y"));
13874
+ }
13821
13875
  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
13876
  },
13823
13877
  };
@@ -18733,7 +18787,7 @@ stores.inject(MyMetaStore, storeInstance);
18733
18787
  compute: function (...logicalExpressions) {
18734
18788
  const { result, foundBoolean } = boolAnd(logicalExpressions);
18735
18789
  if (!foundBoolean) {
18736
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
18790
+ return new EvaluationError(noValidInputErrorMessage);
18737
18791
  }
18738
18792
  return result;
18739
18793
  },
@@ -18859,7 +18913,7 @@ stores.inject(MyMetaStore, storeInstance);
18859
18913
  compute: function (...logicalExpressions) {
18860
18914
  const { result, foundBoolean } = boolOr(logicalExpressions);
18861
18915
  if (!foundBoolean) {
18862
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
18916
+ return new EvaluationError(noValidInputErrorMessage);
18863
18917
  }
18864
18918
  return result;
18865
18919
  },
@@ -18922,7 +18976,7 @@ stores.inject(MyMetaStore, storeInstance);
18922
18976
  return true; // no stop condition
18923
18977
  });
18924
18978
  if (!foundBoolean) {
18925
- return new EvaluationError(_t("[[FUNCTION_NAME]] has no valid input data."));
18979
+ return new EvaluationError(noValidInputErrorMessage);
18926
18980
  }
18927
18981
  return acc;
18928
18982
  },
@@ -21386,7 +21440,7 @@ stores.inject(MyMetaStore, storeInstance);
21386
21440
  function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
21387
21441
  const sheetName = splitReference(sheetXC).sheetName;
21388
21442
  if (sheetName
21389
- ? !isSheetNameEqual(sheetName, applyChange.sheetName)
21443
+ ? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
21390
21444
  : defaultSheetId !== applyChange.sheetId) {
21391
21445
  return sheetXC;
21392
21446
  }
@@ -21403,7 +21457,7 @@ stores.inject(MyMetaStore, storeInstance);
21403
21457
  }
21404
21458
  function getSheetNameGetter(applyChange) {
21405
21459
  return (sheetId) => {
21406
- return sheetId === applyChange.sheetId ? applyChange.sheetName : "";
21460
+ return sheetId === applyChange.sheetId ? applyChange.sheetName.current : "";
21407
21461
  };
21408
21462
  }
21409
21463
  function defaultGetSheetSize(sheetId) {
@@ -27394,9 +27448,13 @@ stores.inject(MyMetaStore, storeInstance);
27394
27448
  : undefined,
27395
27449
  };
27396
27450
  }
27397
- updateRanges(applyChange) {
27451
+ updateRanges(applyChange, sheetId, adaptSheetName) {
27398
27452
  const dataRange = adaptChartRange(this.dataRange, applyChange);
27399
- const adaptFormula = (formula) => this.getters.adaptFormulaStringDependencies(this.sheetId, formula, applyChange);
27453
+ const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
27454
+ applyChange,
27455
+ sheetId,
27456
+ sheetName: adaptSheetName,
27457
+ });
27400
27458
  const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
27401
27459
  const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
27402
27460
  return new GaugeChart(definition, this.sheetId, this.getters);
@@ -33719,6 +33777,9 @@ stores.inject(MyMetaStore, storeInstance);
33719
33777
  this.contentHelper.removeSelection();
33720
33778
  }
33721
33779
  onMouseup() {
33780
+ if (this.env.model.getters.isReadonly()) {
33781
+ return;
33782
+ }
33722
33783
  const selection = this.contentHelper.getCurrentSelection();
33723
33784
  if (selection.start !== selection.end) {
33724
33785
  this.props.composerStore.hoverToken(undefined);
@@ -37454,7 +37515,7 @@ stores.inject(MyMetaStore, storeInstance);
37454
37515
  ];
37455
37516
  const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
37456
37517
  const SUPPORTED_FONTS = ["Arial"];
37457
- const SUPPORTED_FILL_PATTERNS = ["solid"];
37518
+ const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
37458
37519
  const SUPPORTED_CF_TYPES = [
37459
37520
  "expression",
37460
37521
  "cellIs",
@@ -37654,7 +37715,7 @@ stores.inject(MyMetaStore, storeInstance);
37654
37715
  };
37655
37716
  /** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
37656
37717
  const XLSX_FORMATS_CONVERSION_MAP = {
37657
- 0: "",
37718
+ 0: "General",
37658
37719
  1: "0",
37659
37720
  2: "0.00",
37660
37721
  3: "#,#00",
@@ -37980,11 +38041,11 @@ stores.inject(MyMetaStore, storeInstance);
37980
38041
  * Excel format are defined in openXML §18.8.31
37981
38042
  */
37982
38043
  function convertXlsxFormat(numFmtId, formats, warningManager) {
37983
- if (numFmtId === 0) {
37984
- return undefined;
37985
- }
37986
38044
  // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
37987
38045
  const format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
38046
+ if (format === "General") {
38047
+ return undefined;
38048
+ }
37988
38049
  if (format) {
37989
38050
  try {
37990
38051
  let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
@@ -38182,9 +38243,9 @@ stores.inject(MyMetaStore, storeInstance);
38182
38243
  if (!rule.operator || !rule.formula || rule.formula.length === 0)
38183
38244
  continue;
38184
38245
  operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
38185
- values.push(rule.formula[0]);
38246
+ values.push(prefixFormula(rule.formula[0]));
38186
38247
  if (rule.formula.length === 2) {
38187
- values.push(rule.formula[1]);
38248
+ values.push(prefixFormula(rule.formula[1]));
38188
38249
  }
38189
38250
  break;
38190
38251
  }
@@ -38342,6 +38403,11 @@ stores.inject(MyMetaStore, storeInstance);
38342
38403
  ? ICON_SETS[iconSet].neutral
38343
38404
  : ICON_SETS[iconSet].good;
38344
38405
  }
38406
+ /** Prefix the string by "=" if the string looks like a formula */
38407
+ function prefixFormula(formula) {
38408
+ const tokens = tokenize(formula);
38409
+ return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
38410
+ }
38345
38411
  // ---------------------------------------------------------------------------
38346
38412
  // Warnings
38347
38413
  // ---------------------------------------------------------------------------
@@ -38624,7 +38690,7 @@ stores.inject(MyMetaStore, storeInstance);
38624
38690
  function getRowPosition(rowIndex, sheetData) {
38625
38691
  let position = 0;
38626
38692
  for (let i = 0; i < rowIndex; i++) {
38627
- const rowAtIndex = sheetData.rows[i];
38693
+ const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
38628
38694
  if (rowAtIndex?.height) {
38629
38695
  position += rowAtIndex.height;
38630
38696
  }
@@ -38779,8 +38845,8 @@ stores.inject(MyMetaStore, storeInstance);
38779
38845
  }
38780
38846
  function convertAnchor(XLSXanchor) {
38781
38847
  const offset = {
38782
- x: convertEMUToDotValue(XLSXanchor.colOffset),
38783
- y: convertEMUToDotValue(XLSXanchor.rowOffset),
38848
+ x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
38849
+ y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
38784
38850
  };
38785
38851
  return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
38786
38852
  }
@@ -39163,8 +39229,12 @@ stores.inject(MyMetaStore, storeInstance);
39163
39229
  dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
39164
39230
  dims[1] = Math.max(dims[1], row.index);
39165
39231
  }
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);
39232
+ for (const fig of sheet.figures) {
39233
+ dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
39234
+ dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
39235
+ }
39236
+ dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
39237
+ dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
39168
39238
  return dims;
39169
39239
  }
39170
39240
  /**
@@ -40553,10 +40623,11 @@ stores.inject(MyMetaStore, storeInstance);
40553
40623
  });
40554
40624
  }
40555
40625
  extractRows(worksheet) {
40626
+ const spilledCells = new Set();
40556
40627
  return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
40557
40628
  return {
40558
40629
  index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
40559
- cells: this.extractCells(rowElement),
40630
+ cells: this.extractCells(rowElement, spilledCells),
40560
40631
  height: this.extractAttr(rowElement, "ht")?.asNum(),
40561
40632
  customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
40562
40633
  hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
@@ -40566,14 +40637,26 @@ stores.inject(MyMetaStore, storeInstance);
40566
40637
  };
40567
40638
  });
40568
40639
  }
40569
- extractCells(row) {
40640
+ extractCells(row, spilledCells) {
40570
40641
  return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
40642
+ const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
40643
+ const formula = this.extractCellFormula(cellElement);
40644
+ if (formula?.ref && formula.sharedIndex === undefined) {
40645
+ const zone = toZone(formula.ref);
40646
+ for (const { col, row } of positions(zone)) {
40647
+ const followerXc = toXC(col, row);
40648
+ if (followerXc !== xc) {
40649
+ spilledCells.add(followerXc);
40650
+ }
40651
+ }
40652
+ }
40653
+ const isSpilled = spilledCells.has(xc);
40571
40654
  return {
40572
- xc: this.extractAttr(cellElement, "r", { required: true })?.asString(),
40655
+ xc,
40573
40656
  styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
40574
40657
  type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
40575
- value: this.extractChildTextContent(cellElement, "v"),
40576
- formula: this.extractCellFormula(cellElement),
40658
+ value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
40659
+ formula: isSpilled ? undefined : formula,
40577
40660
  };
40578
40661
  });
40579
40662
  }
@@ -40581,11 +40664,14 @@ stores.inject(MyMetaStore, storeInstance);
40581
40664
  const formulaElement = this.querySelector(cellElement, "f");
40582
40665
  if (!formulaElement)
40583
40666
  return undefined;
40584
- return {
40585
- content: this.extractTextContent(formulaElement),
40586
- sharedIndex: this.extractAttr(formulaElement, "si")?.asNum(),
40587
- ref: this.extractAttr(formulaElement, "ref")?.asString(),
40588
- };
40667
+ const content = this.extractTextContent(formulaElement);
40668
+ const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
40669
+ const ref = this.extractAttr(formulaElement, "ref")?.asString();
40670
+ // This is the case of spilled cells of array formulas where <f> is empty
40671
+ if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
40672
+ return undefined;
40673
+ }
40674
+ return { content, sharedIndex, ref };
40589
40675
  }
40590
40676
  extractHyperLinks(worksheet) {
40591
40677
  return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
@@ -40867,7 +40953,7 @@ stores.inject(MyMetaStore, storeInstance);
40867
40953
  return relsFile;
40868
40954
  }
40869
40955
 
40870
- const EXCEL_IMPORT_VERSION = "18.4.1";
40956
+ const EXCEL_IMPORT_VERSION = "18.4.2";
40871
40957
  class XlsxReader {
40872
40958
  warningManager;
40873
40959
  xmls;
@@ -44412,7 +44498,7 @@ stores.inject(MyMetaStore, storeInstance);
44412
44498
  const reinsertDynamicPivotMenu = {
44413
44499
  id: "reinsert_dynamic_pivot",
44414
44500
  name: _t("Re-insert dynamic pivot"),
44415
- sequence: 1020,
44501
+ sequence: 60,
44416
44502
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
44417
44503
  children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
44418
44504
  isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
@@ -44420,7 +44506,7 @@ stores.inject(MyMetaStore, storeInstance);
44420
44506
  const reinsertStaticPivotMenu = {
44421
44507
  id: "reinsert_static_pivot",
44422
44508
  name: _t("Re-insert static pivot"),
44423
- sequence: 1020,
44509
+ sequence: 70,
44424
44510
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
44425
44511
  children: [REINSERT_STATIC_PIVOT_CHILDREN],
44426
44512
  isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
@@ -58691,7 +58777,8 @@ stores.inject(MyMetaStore, storeInstance);
58691
58777
  * the type of change that occurred.
58692
58778
  *
58693
58779
  * @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
58780
+ * @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
58781
+ * @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
58695
58782
  */
58696
58783
  adaptRanges(applyChange, sheetId, sheetName) { }
58697
58784
  /**
@@ -59294,9 +59381,7 @@ stores.inject(MyMetaStore, storeInstance);
59294
59381
  for (const cell of Object.values(this.cells[sheet] || {})) {
59295
59382
  if (cell.isFormula) {
59296
59383
  for (const range of cell.compiledFormula.dependencies) {
59297
- if (!sheetId ||
59298
- range.sheetId === sheetId ||
59299
- (sheetName && range.invalidSheetName === sheetName)) {
59384
+ if (range.sheetId === sheetId || range.invalidSheetName === sheetName.old) {
59300
59385
  const change = applyChange(range);
59301
59386
  if (change.changeType !== "NONE") {
59302
59387
  this.history.update("cells", sheet, cell.id, "compiledFormula", "dependencies", cell.compiledFormula.dependencies.indexOf(range), change.range);
@@ -59912,9 +59997,9 @@ stores.inject(MyMetaStore, storeInstance);
59912
59997
  charts = {};
59913
59998
  createChart = chartFactory(this.getters);
59914
59999
  validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
59915
- adaptRanges(applyChange) {
60000
+ adaptRanges(applyChange, sheetId, adaptSheetName) {
59916
60001
  for (const [chartId, chart] of Object.entries(this.charts)) {
59917
- this.history.update("charts", chartId, chart?.updateRanges(applyChange));
60002
+ this.history.update("charts", chartId, chart?.updateRanges(applyChange, sheetId, adaptSheetName));
59918
60003
  }
59919
60004
  }
59920
60005
  // ---------------------------------------------------------------------------
@@ -60177,7 +60262,7 @@ stores.inject(MyMetaStore, storeInstance);
60177
60262
  }
60178
60263
  }
60179
60264
  }
60180
- adaptRanges(applyChange, sheetId, sheetName) {
60265
+ adaptRanges(applyChange, sheetId) {
60181
60266
  const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
60182
60267
  for (const sheetId of sheetIds) {
60183
60268
  this.adaptCFRanges(sheetId, applyChange);
@@ -60559,11 +60644,8 @@ stores.inject(MyMetaStore, storeInstance);
60559
60644
  "getValidationRuleForCell",
60560
60645
  ];
60561
60646
  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
- }
60647
+ adaptRanges(applyChange, sheetId) {
60648
+ this.adaptDVRanges(sheetId, applyChange);
60567
60649
  this.adaptDVFormulas(applyChange);
60568
60650
  }
60569
60651
  adaptDVFormulas(applyChange) {
@@ -60853,9 +60935,6 @@ stores.inject(MyMetaStore, storeInstance);
60853
60935
  // Command Handling
60854
60936
  // ---------------------------------------------------------------------------
60855
60937
  adaptRanges(applyChange, sheetId) {
60856
- if (!sheetId) {
60857
- return;
60858
- }
60859
60938
  for (const figure of this.getFigures(sheetId)) {
60860
60939
  const change = applyChange(this.getters.getRangeFromZone(sheetId, {
60861
60940
  left: figure.col,
@@ -61664,11 +61743,8 @@ stores.inject(MyMetaStore, storeInstance);
61664
61743
  break;
61665
61744
  }
61666
61745
  }
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
- }
61746
+ adaptRanges(applyChange, sheetId) {
61747
+ this.applyRangeChangeOnSheet(sheetId, applyChange);
61672
61748
  }
61673
61749
  // ---------------------------------------------------------------------------
61674
61750
  // Getters
@@ -63173,12 +63249,9 @@ stores.inject(MyMetaStore, storeInstance);
63173
63249
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
63174
63250
  tables = {};
63175
63251
  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
- }
63252
+ adaptRanges(applyChange, sheetId) {
63253
+ for (const table of this.getCoreTables(sheetId)) {
63254
+ this.applyRangeChangeOnTable(sheetId, table, applyChange);
63182
63255
  }
63183
63256
  }
63184
63257
  allowDispatch(cmd) {
@@ -64141,7 +64214,7 @@ stores.inject(MyMetaStore, storeInstance);
64141
64214
  }
64142
64215
  }
64143
64216
  }
64144
- adaptRanges(applyChange, sheetId, sheetName) {
64217
+ adaptRanges(applyChange) {
64145
64218
  for (const sheetId in this.compiledMeasureFormulas) {
64146
64219
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
64147
64220
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -68542,7 +68615,7 @@ stores.inject(MyMetaStore, storeInstance);
68542
68615
  if (!result) {
68543
68616
  return EMPTY_PIVOT_CELL;
68544
68617
  }
68545
- const { functionName, args } = result;
68618
+ let { functionName, args } = result;
68546
68619
  const formulaId = args[0];
68547
68620
  if (!formulaId) {
68548
68621
  return EMPTY_PIVOT_CELL;
@@ -68577,6 +68650,9 @@ stores.inject(MyMetaStore, storeInstance);
68577
68650
  return pivotCells[pivotCol][pivotRow];
68578
68651
  }
68579
68652
  try {
68653
+ const offsetRow = position.row - mainPosition.row;
68654
+ const offsetCol = position.col - mainPosition.col;
68655
+ args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
68580
68656
  if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
68581
68657
  const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
68582
68658
  return {
@@ -70185,7 +70261,8 @@ stores.inject(MyMetaStore, storeInstance);
70185
70261
  // If the executed command is not in the registry, we skip it
70186
70262
  // because we know there won't be any transformation impacting the
70187
70263
  // commands to transform.
70188
- if (possibleTransformations.has(executedCommand.type)) {
70264
+ if (possibleTransformations.has(executedCommand.type) ||
70265
+ rangeAdapterRegistry.contains(executedCommand.type)) {
70189
70266
  transformedCommands = transformedCommands.reduce((acc, cmd) => {
70190
70267
  const transformed = transform(cmd, executedCommand);
70191
70268
  if (transformed) {
@@ -70932,7 +71009,7 @@ stores.inject(MyMetaStore, storeInstance);
70932
71009
  bottom: rowIndex,
70933
71010
  }));
70934
71011
  const handler = new CellClipboardHandler(this.getters, this.dispatch);
70935
- const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep));
71012
+ const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep), false);
70936
71013
  if (!data) {
70937
71014
  return;
70938
71015
  }
@@ -73017,12 +73094,12 @@ stores.inject(MyMetaStore, storeInstance);
73017
73094
  }
73018
73095
  case "INSERT_CELL": {
73019
73096
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
73020
- const copiedData = this.copy(cut);
73097
+ const copiedData = this.copy(cut, "shiftCells");
73021
73098
  return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
73022
73099
  }
73023
73100
  case "DELETE_CELL": {
73024
73101
  const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
73025
- const copiedData = this.copy(cut);
73102
+ const copiedData = this.copy(cut, "shiftCells");
73026
73103
  return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
73027
73104
  }
73028
73105
  }
@@ -73133,13 +73210,13 @@ stores.inject(MyMetaStore, storeInstance);
73133
73210
  });
73134
73211
  break;
73135
73212
  }
73136
- const copiedData = this.copy(cut);
73213
+ const copiedData = this.copy(cut, "shiftCells");
73137
73214
  this.paste(paste, copiedData, { isCutOperation: true });
73138
73215
  break;
73139
73216
  }
73140
73217
  case "INSERT_CELL": {
73141
73218
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
73142
- const copiedData = this.copy(cut);
73219
+ const copiedData = this.copy(cut, "shiftCells");
73143
73220
  this.paste(paste, copiedData, { isCutOperation: true });
73144
73221
  break;
73145
73222
  }
@@ -73254,11 +73331,11 @@ stores.inject(MyMetaStore, storeInstance);
73254
73331
  }
73255
73332
  return false;
73256
73333
  }
73257
- copy(zones) {
73334
+ copy(zones, mode = "copyPaste") {
73258
73335
  const copiedData = {};
73259
73336
  const clipboardData = this.getClipboardData(zones);
73260
73337
  for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
73261
- const data = handler.copy(clipboardData, this._isCutOperation);
73338
+ const data = handler.copy(clipboardData, this._isCutOperation, mode);
73262
73339
  copiedData[handlerName] = data;
73263
73340
  const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
73264
73341
  for (const key of minimalKeys) {
@@ -74272,7 +74349,7 @@ stores.inject(MyMetaStore, storeInstance);
74272
74349
  ];
74273
74350
  for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
74274
74351
  const handler = new Handler(this.getters, this.dispatch);
74275
- const data = handler.copy(getClipboardDataPositions(sheetId, target));
74352
+ const data = handler.copy(getClipboardDataPositions(sheetId, target), false, "shiftCells");
74276
74353
  if (!data) {
74277
74354
  continue;
74278
74355
  }
@@ -76177,7 +76254,8 @@ stores.inject(MyMetaStore, storeInstance);
76177
76254
  .add("HIDE_COLUMNS_ROWS", inverseHideColumnsRows)
76178
76255
  .add("UNHIDE_COLUMNS_ROWS", inverseUnhideColumnsRows)
76179
76256
  .add("CREATE_TABLE_STYLE", inverseCreateTableStyle)
76180
- .add("ADD_PIVOT", inverseAddPivot);
76257
+ .add("ADD_PIVOT", inverseAddPivot)
76258
+ .add("RENAME_SHEET", inverseRenameSheet);
76181
76259
  for (const cmd of coreTypes.values()) {
76182
76260
  if (!inverseCommandRegistry.contains(cmd)) {
76183
76261
  inverseCommandRegistry.add(cmd, identity);
@@ -76275,6 +76353,16 @@ stores.inject(MyMetaStore, storeInstance);
76275
76353
  function inverseCreateTableStyle(cmd) {
76276
76354
  return [{ type: "REMOVE_TABLE_STYLE", tableStyleId: cmd.tableStyleId }];
76277
76355
  }
76356
+ function inverseRenameSheet(cmd) {
76357
+ return [
76358
+ {
76359
+ type: "RENAME_SHEET",
76360
+ sheetId: cmd.sheetId,
76361
+ oldName: cmd.newName,
76362
+ newName: cmd.oldName,
76363
+ },
76364
+ ];
76365
+ }
76278
76366
 
76279
76367
  const numberFormatMenuRegistry = new Registry();
76280
76368
  numberFormatMenuRegistry
@@ -76873,8 +76961,9 @@ stores.inject(MyMetaStore, storeInstance);
76873
76961
  sequence: 40,
76874
76962
  separator: true,
76875
76963
  })
76876
- .addChild("data_sources_data", ["data"], (env) => {
76964
+ .addChild("pivot_data_sources", ["data"], (env) => {
76877
76965
  const sequence = 50;
76966
+ const numberOfPivots = env.model.getters.getPivotIds().length;
76878
76967
  return env.model.getters.getPivotIds().map((pivotId, index) => {
76879
76968
  const highlightProvider = {
76880
76969
  get highlights() {
@@ -76884,7 +76973,7 @@ stores.inject(MyMetaStore, storeInstance);
76884
76973
  return {
76885
76974
  id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
76886
76975
  name: env.model.getters.getPivotDisplayName(pivotId),
76887
- sequence: sequence + index,
76976
+ sequence: sequence + index / numberOfPivots,
76888
76977
  isReadonlyAllowed: true,
76889
76978
  execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
76890
76979
  isEnabled: (env) => !env.isSmall,
@@ -83004,7 +83093,7 @@ stores.inject(MyMetaStore, storeInstance);
83004
83093
  for (const [headerIndex, header] of headers.slice(anchor).entries()) {
83005
83094
  if (currentPosition <= offset && offset < currentPosition + header.size) {
83006
83095
  return {
83007
- index: headerIndex,
83096
+ index: anchor + headerIndex,
83008
83097
  offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
83009
83098
  };
83010
83099
  }
@@ -84750,9 +84839,9 @@ stores.inject(MyMetaStore, storeInstance);
84750
84839
  exports.tokenize = tokenize;
84751
84840
 
84752
84841
 
84753
- __info__.version = "18.4.8";
84754
- __info__.date = "2025-08-26T10:14:08.954Z";
84755
- __info__.hash = "746217a";
84842
+ __info__.version = "18.4.10";
84843
+ __info__.date = "2025-09-11T08:45:39.178Z";
84844
+ __info__.hash = "15a11a4";
84756
84845
 
84757
84846
 
84758
84847
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);