@odoo/o-spreadsheet 18.0.46 → 18.0.48

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.46
6
- * @date 2025-10-07T10:00:44.707Z
7
- * @hash 67a1b4a
5
+ * @version 18.0.48
6
+ * @date 2025-11-12T14:15:38.406Z
7
+ * @hash d1efb0b
8
8
  */
9
9
 
10
10
  'use strict';
@@ -3738,7 +3738,17 @@ function toNumberMatrix(data, argName) {
3738
3738
  return toMatrix(data).map((row) => {
3739
3739
  return row.map((cell) => {
3740
3740
  if (typeof cell.value !== "number") {
3741
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects number values for %s, but got a %s.", argName, typeof cell.value));
3741
+ let message = "";
3742
+ if (typeof cell === "object") {
3743
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
3744
+ }
3745
+ else if (typeof cell === "string") {
3746
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
3747
+ }
3748
+ else if (typeof cell === "boolean") {
3749
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
3750
+ }
3751
+ throw new EvaluationError(message);
3742
3752
  }
3743
3753
  return cell.value;
3744
3754
  });
@@ -8606,7 +8616,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
8606
8616
  pasteCell(origin, target, clipboardOption) {
8607
8617
  const { sheetId, col, row } = target;
8608
8618
  const targetCell = this.getters.getEvaluatedCell(target);
8609
- const originFormat = origin?.format ?? origin.evaluatedCell.format;
8619
+ const originFormat = origin?.format || origin.evaluatedCell.format;
8610
8620
  if (clipboardOption?.pasteOption === "asValue") {
8611
8621
  this.dispatch("UPDATE_CELL", {
8612
8622
  ...target,
@@ -10171,6 +10181,10 @@ const chartShowValuesPlugin = {
10171
10181
  }
10172
10182
  const ctx = chart.ctx;
10173
10183
  ctx.save();
10184
+ const { left, top, height, width } = chart.chartArea;
10185
+ ctx.beginPath();
10186
+ ctx.rect(left, top, width, height);
10187
+ ctx.clip();
10174
10188
  ctx.textAlign = "center";
10175
10189
  ctx.textBaseline = "middle";
10176
10190
  ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
@@ -13109,7 +13123,7 @@ const GROWTH = {
13109
13123
  ],
13110
13124
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13111
13125
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13112
- 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)));
13126
+ return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
13113
13127
  },
13114
13128
  };
13115
13129
  // -----------------------------------------------------------------------------
@@ -13174,7 +13188,7 @@ const LINEST = {
13174
13188
  ],
13175
13189
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13176
13190
  assertNonEmptyMatrix(dataY, "data_y");
13177
- return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13191
+ return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
13178
13192
  },
13179
13193
  isExported: true,
13180
13194
  };
@@ -13191,7 +13205,7 @@ const LOGEST = {
13191
13205
  ],
13192
13206
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13193
13207
  assertNonEmptyMatrix(dataY, "data_y");
13194
- const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13208
+ const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
13195
13209
  for (let i = 0; i < coeffs.length; i++) {
13196
13210
  coeffs[i][0] = Math.exp(coeffs[i][0]);
13197
13211
  }
@@ -13781,7 +13795,7 @@ const TREND = {
13781
13795
  ],
13782
13796
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13783
13797
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13784
- 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));
13798
+ return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
13785
13799
  },
13786
13800
  };
13787
13801
  // -----------------------------------------------------------------------------
@@ -26312,7 +26326,7 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
26312
26326
  return {
26313
26327
  background: context.background,
26314
26328
  type: "scorecard",
26315
- keyValue: context.range ? context.range[0].dataRange : undefined,
26329
+ keyValue: context.range?.[0]?.dataRange,
26316
26330
  title: context.title || { text: "" },
26317
26331
  baselineMode: DEFAULT_SCORECARD_BASELINE_MODE,
26318
26332
  baselineColorUp: DEFAULT_SCORECARD_BASELINE_COLOR_UP,
@@ -29725,6 +29739,7 @@ function getChartTimeOptions(labels, labelFormat, locale) {
29725
29739
  parser: luxonFormat,
29726
29740
  displayFormats,
29727
29741
  unit: timeUnit ?? false,
29742
+ tooltipFormat: luxonFormat,
29728
29743
  };
29729
29744
  }
29730
29745
  /**
@@ -30501,7 +30516,7 @@ class GaugeChart extends AbstractChart {
30501
30516
  background: context.background,
30502
30517
  title: context.title || { text: "" },
30503
30518
  type: "gauge",
30504
- dataRange: context.range ? context.range[0].dataRange : undefined,
30519
+ dataRange: context.range?.[0]?.dataRange,
30505
30520
  sectionRule: {
30506
30521
  colors: {
30507
30522
  lowerColor: DEFAULT_GAUGE_LOWER_COLOR,
@@ -42177,12 +42192,13 @@ class DataValidationEditor extends owl.Component {
42177
42192
  onCloseSidePanel: { type: Function, optional: true },
42178
42193
  };
42179
42194
  state = owl.useState({ rule: this.defaultDataValidationRule });
42195
+ editingSheetId;
42180
42196
  setup() {
42197
+ this.editingSheetId = this.env.model.getters.getActiveSheetId();
42181
42198
  if (this.props.rule) {
42182
- const sheetId = this.env.model.getters.getActiveSheetId();
42183
42199
  this.state.rule = {
42184
42200
  ...this.props.rule,
42185
- ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, sheetId)),
42201
+ ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
42186
42202
  };
42187
42203
  this.state.rule.criterion.type = this.props.rule.criterion.type;
42188
42204
  }
@@ -42216,7 +42232,6 @@ class DataValidationEditor extends owl.Component {
42216
42232
  const locale = this.env.model.getters.getLocale();
42217
42233
  const criterion = rule.criterion;
42218
42234
  const criterionEvaluator = dataValidationEvaluatorRegistry.get(criterion.type);
42219
- const sheetId = this.env.model.getters.getActiveSheetId();
42220
42235
  const values = criterion.values
42221
42236
  .slice(0, criterionEvaluator.numberOfValues(criterion))
42222
42237
  .map((value) => value?.trim())
@@ -42224,8 +42239,8 @@ class DataValidationEditor extends owl.Component {
42224
42239
  .map((value) => canonicalizeContent(value, locale));
42225
42240
  rule.criterion = { ...criterion, values };
42226
42241
  return {
42227
- sheetId,
42228
- ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
42242
+ sheetId: this.editingSheetId,
42243
+ ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
42229
42244
  rule,
42230
42245
  };
42231
42246
  }
@@ -55258,7 +55273,7 @@ class RangeAdapter {
55258
55273
  let sheetName = "";
55259
55274
  if (prefixSheet) {
55260
55275
  if (rangeImpl.invalidSheetName) {
55261
- sheetName = rangeImpl.invalidSheetName;
55276
+ sheetName = getCanonicalSymbolName(rangeImpl.invalidSheetName);
55262
55277
  }
55263
55278
  else {
55264
55279
  sheetName = getCanonicalSymbolName(this.getters.getSheetName(rangeImpl.sheetId));
@@ -58539,7 +58554,7 @@ class FormulaDependencyGraph {
58539
58554
  * in the correct order they should be evaluated.
58540
58555
  * This is called a topological ordering (excluding cycles)
58541
58556
  */
58542
- getCellsDependingOn(ranges) {
58557
+ getCellsDependingOn(ranges, ignore) {
58543
58558
  const visited = this.createEmptyPositionSet();
58544
58559
  const queue = Array.from(ranges).reverse();
58545
58560
  while (queue.length > 0) {
@@ -58554,7 +58569,7 @@ class FormulaDependencyGraph {
58554
58569
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
58555
58570
  const nextInQueue = {};
58556
58571
  for (const position of impactedPositions) {
58557
- if (!visited.has(position)) {
58572
+ if (!visited.has(position) && !ignore.has(position)) {
58558
58573
  if (!nextInQueue[position.sheetId]) {
58559
58574
  nextInQueue[position.sheetId] = [];
58560
58575
  }
@@ -59107,7 +59122,7 @@ class Evaluator {
59107
59122
  }
59108
59123
  invalidatePositionsDependingOnSpread(sheetId, resultZone) {
59109
59124
  // the result matrix is split in 2 zones to exclude the array formula position
59110
- const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
59125
+ const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
59111
59126
  invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
59112
59127
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
59113
59128
  }
@@ -59222,7 +59237,7 @@ class Evaluator {
59222
59237
  for (const sheetId in zonesBySheetIds) {
59223
59238
  ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
59224
59239
  }
59225
- return this.formulaDependencies().getCellsDependingOn(ranges);
59240
+ return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
59226
59241
  }
59227
59242
  }
59228
59243
  function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
@@ -74748,6 +74763,6 @@ exports.tokenColors = tokenColors;
74748
74763
  exports.tokenize = tokenize;
74749
74764
 
74750
74765
 
74751
- __info__.version = "18.0.46";
74752
- __info__.date = "2025-10-07T10:00:44.707Z";
74753
- __info__.hash = "67a1b4a";
74766
+ __info__.version = "18.0.48";
74767
+ __info__.date = "2025-11-12T14:15:38.406Z";
74768
+ __info__.hash = "d1efb0b";
@@ -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.46
6
- * @date 2025-10-07T10:00:44.707Z
7
- * @hash 67a1b4a
5
+ * @version 18.0.48
6
+ * @date 2025-11-12T14:15:38.406Z
7
+ * @hash d1efb0b
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';
@@ -3736,7 +3736,17 @@ function toNumberMatrix(data, argName) {
3736
3736
  return toMatrix(data).map((row) => {
3737
3737
  return row.map((cell) => {
3738
3738
  if (typeof cell.value !== "number") {
3739
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects number values for %s, but got a %s.", argName, typeof cell.value));
3739
+ let message = "";
3740
+ if (typeof cell === "object") {
3741
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
3742
+ }
3743
+ else if (typeof cell === "string") {
3744
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
3745
+ }
3746
+ else if (typeof cell === "boolean") {
3747
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
3748
+ }
3749
+ throw new EvaluationError(message);
3740
3750
  }
3741
3751
  return cell.value;
3742
3752
  });
@@ -8604,7 +8614,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
8604
8614
  pasteCell(origin, target, clipboardOption) {
8605
8615
  const { sheetId, col, row } = target;
8606
8616
  const targetCell = this.getters.getEvaluatedCell(target);
8607
- const originFormat = origin?.format ?? origin.evaluatedCell.format;
8617
+ const originFormat = origin?.format || origin.evaluatedCell.format;
8608
8618
  if (clipboardOption?.pasteOption === "asValue") {
8609
8619
  this.dispatch("UPDATE_CELL", {
8610
8620
  ...target,
@@ -10169,6 +10179,10 @@ const chartShowValuesPlugin = {
10169
10179
  }
10170
10180
  const ctx = chart.ctx;
10171
10181
  ctx.save();
10182
+ const { left, top, height, width } = chart.chartArea;
10183
+ ctx.beginPath();
10184
+ ctx.rect(left, top, width, height);
10185
+ ctx.clip();
10172
10186
  ctx.textAlign = "center";
10173
10187
  ctx.textBaseline = "middle";
10174
10188
  ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
@@ -13107,7 +13121,7 @@ const GROWTH = {
13107
13121
  ],
13108
13122
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13109
13123
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13110
- 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)));
13124
+ return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
13111
13125
  },
13112
13126
  };
13113
13127
  // -----------------------------------------------------------------------------
@@ -13172,7 +13186,7 @@ const LINEST = {
13172
13186
  ],
13173
13187
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13174
13188
  assertNonEmptyMatrix(dataY, "data_y");
13175
- return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13189
+ return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
13176
13190
  },
13177
13191
  isExported: true,
13178
13192
  };
@@ -13189,7 +13203,7 @@ const LOGEST = {
13189
13203
  ],
13190
13204
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13191
13205
  assertNonEmptyMatrix(dataY, "data_y");
13192
- const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13206
+ const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
13193
13207
  for (let i = 0; i < coeffs.length; i++) {
13194
13208
  coeffs[i][0] = Math.exp(coeffs[i][0]);
13195
13209
  }
@@ -13779,7 +13793,7 @@ const TREND = {
13779
13793
  ],
13780
13794
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13781
13795
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13782
- 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));
13796
+ return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
13783
13797
  },
13784
13798
  };
13785
13799
  // -----------------------------------------------------------------------------
@@ -26310,7 +26324,7 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
26310
26324
  return {
26311
26325
  background: context.background,
26312
26326
  type: "scorecard",
26313
- keyValue: context.range ? context.range[0].dataRange : undefined,
26327
+ keyValue: context.range?.[0]?.dataRange,
26314
26328
  title: context.title || { text: "" },
26315
26329
  baselineMode: DEFAULT_SCORECARD_BASELINE_MODE,
26316
26330
  baselineColorUp: DEFAULT_SCORECARD_BASELINE_COLOR_UP,
@@ -29723,6 +29737,7 @@ function getChartTimeOptions(labels, labelFormat, locale) {
29723
29737
  parser: luxonFormat,
29724
29738
  displayFormats,
29725
29739
  unit: timeUnit ?? false,
29740
+ tooltipFormat: luxonFormat,
29726
29741
  };
29727
29742
  }
29728
29743
  /**
@@ -30499,7 +30514,7 @@ class GaugeChart extends AbstractChart {
30499
30514
  background: context.background,
30500
30515
  title: context.title || { text: "" },
30501
30516
  type: "gauge",
30502
- dataRange: context.range ? context.range[0].dataRange : undefined,
30517
+ dataRange: context.range?.[0]?.dataRange,
30503
30518
  sectionRule: {
30504
30519
  colors: {
30505
30520
  lowerColor: DEFAULT_GAUGE_LOWER_COLOR,
@@ -42175,12 +42190,13 @@ class DataValidationEditor extends Component {
42175
42190
  onCloseSidePanel: { type: Function, optional: true },
42176
42191
  };
42177
42192
  state = useState({ rule: this.defaultDataValidationRule });
42193
+ editingSheetId;
42178
42194
  setup() {
42195
+ this.editingSheetId = this.env.model.getters.getActiveSheetId();
42179
42196
  if (this.props.rule) {
42180
- const sheetId = this.env.model.getters.getActiveSheetId();
42181
42197
  this.state.rule = {
42182
42198
  ...this.props.rule,
42183
- ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, sheetId)),
42199
+ ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
42184
42200
  };
42185
42201
  this.state.rule.criterion.type = this.props.rule.criterion.type;
42186
42202
  }
@@ -42214,7 +42230,6 @@ class DataValidationEditor extends Component {
42214
42230
  const locale = this.env.model.getters.getLocale();
42215
42231
  const criterion = rule.criterion;
42216
42232
  const criterionEvaluator = dataValidationEvaluatorRegistry.get(criterion.type);
42217
- const sheetId = this.env.model.getters.getActiveSheetId();
42218
42233
  const values = criterion.values
42219
42234
  .slice(0, criterionEvaluator.numberOfValues(criterion))
42220
42235
  .map((value) => value?.trim())
@@ -42222,8 +42237,8 @@ class DataValidationEditor extends Component {
42222
42237
  .map((value) => canonicalizeContent(value, locale));
42223
42238
  rule.criterion = { ...criterion, values };
42224
42239
  return {
42225
- sheetId,
42226
- ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
42240
+ sheetId: this.editingSheetId,
42241
+ ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
42227
42242
  rule,
42228
42243
  };
42229
42244
  }
@@ -55256,7 +55271,7 @@ class RangeAdapter {
55256
55271
  let sheetName = "";
55257
55272
  if (prefixSheet) {
55258
55273
  if (rangeImpl.invalidSheetName) {
55259
- sheetName = rangeImpl.invalidSheetName;
55274
+ sheetName = getCanonicalSymbolName(rangeImpl.invalidSheetName);
55260
55275
  }
55261
55276
  else {
55262
55277
  sheetName = getCanonicalSymbolName(this.getters.getSheetName(rangeImpl.sheetId));
@@ -58537,7 +58552,7 @@ class FormulaDependencyGraph {
58537
58552
  * in the correct order they should be evaluated.
58538
58553
  * This is called a topological ordering (excluding cycles)
58539
58554
  */
58540
- getCellsDependingOn(ranges) {
58555
+ getCellsDependingOn(ranges, ignore) {
58541
58556
  const visited = this.createEmptyPositionSet();
58542
58557
  const queue = Array.from(ranges).reverse();
58543
58558
  while (queue.length > 0) {
@@ -58552,7 +58567,7 @@ class FormulaDependencyGraph {
58552
58567
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
58553
58568
  const nextInQueue = {};
58554
58569
  for (const position of impactedPositions) {
58555
- if (!visited.has(position)) {
58570
+ if (!visited.has(position) && !ignore.has(position)) {
58556
58571
  if (!nextInQueue[position.sheetId]) {
58557
58572
  nextInQueue[position.sheetId] = [];
58558
58573
  }
@@ -59105,7 +59120,7 @@ class Evaluator {
59105
59120
  }
59106
59121
  invalidatePositionsDependingOnSpread(sheetId, resultZone) {
59107
59122
  // the result matrix is split in 2 zones to exclude the array formula position
59108
- const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
59123
+ const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
59109
59124
  invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
59110
59125
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
59111
59126
  }
@@ -59220,7 +59235,7 @@ class Evaluator {
59220
59235
  for (const sheetId in zonesBySheetIds) {
59221
59236
  ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
59222
59237
  }
59223
- return this.formulaDependencies().getCellsDependingOn(ranges);
59238
+ return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
59224
59239
  }
59225
59240
  }
59226
59241
  function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
@@ -74703,6 +74718,6 @@ const constants = {
74703
74718
  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 };
74704
74719
 
74705
74720
 
74706
- __info__.version = "18.0.46";
74707
- __info__.date = "2025-10-07T10:00:44.707Z";
74708
- __info__.hash = "67a1b4a";
74721
+ __info__.version = "18.0.48";
74722
+ __info__.date = "2025-11-12T14:15:38.406Z";
74723
+ __info__.hash = "d1efb0b";
@@ -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.46
6
- * @date 2025-10-07T10:00:44.707Z
7
- * @hash 67a1b4a
5
+ * @version 18.0.48
6
+ * @date 2025-11-12T14:15:38.406Z
7
+ * @hash d1efb0b
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -3737,7 +3737,17 @@
3737
3737
  return toMatrix(data).map((row) => {
3738
3738
  return row.map((cell) => {
3739
3739
  if (typeof cell.value !== "number") {
3740
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects number values for %s, but got a %s.", argName, typeof cell.value));
3740
+ let message = "";
3741
+ if (typeof cell === "object") {
3742
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
3743
+ }
3744
+ else if (typeof cell === "string") {
3745
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
3746
+ }
3747
+ else if (typeof cell === "boolean") {
3748
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
3749
+ }
3750
+ throw new EvaluationError(message);
3741
3751
  }
3742
3752
  return cell.value;
3743
3753
  });
@@ -8605,7 +8615,7 @@
8605
8615
  pasteCell(origin, target, clipboardOption) {
8606
8616
  const { sheetId, col, row } = target;
8607
8617
  const targetCell = this.getters.getEvaluatedCell(target);
8608
- const originFormat = origin?.format ?? origin.evaluatedCell.format;
8618
+ const originFormat = origin?.format || origin.evaluatedCell.format;
8609
8619
  if (clipboardOption?.pasteOption === "asValue") {
8610
8620
  this.dispatch("UPDATE_CELL", {
8611
8621
  ...target,
@@ -10170,6 +10180,10 @@ stores.inject(MyMetaStore, storeInstance);
10170
10180
  }
10171
10181
  const ctx = chart.ctx;
10172
10182
  ctx.save();
10183
+ const { left, top, height, width } = chart.chartArea;
10184
+ ctx.beginPath();
10185
+ ctx.rect(left, top, width, height);
10186
+ ctx.clip();
10173
10187
  ctx.textAlign = "center";
10174
10188
  ctx.textBaseline = "middle";
10175
10189
  ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
@@ -13108,7 +13122,7 @@ stores.inject(MyMetaStore, storeInstance);
13108
13122
  ],
13109
13123
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13110
13124
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13111
- 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)));
13125
+ return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
13112
13126
  },
13113
13127
  };
13114
13128
  // -----------------------------------------------------------------------------
@@ -13173,7 +13187,7 @@ stores.inject(MyMetaStore, storeInstance);
13173
13187
  ],
13174
13188
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13175
13189
  assertNonEmptyMatrix(dataY, "data_y");
13176
- return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13190
+ return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
13177
13191
  },
13178
13192
  isExported: true,
13179
13193
  };
@@ -13190,7 +13204,7 @@ stores.inject(MyMetaStore, storeInstance);
13190
13204
  ],
13191
13205
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13192
13206
  assertNonEmptyMatrix(dataY, "data_y");
13193
- const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13207
+ const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
13194
13208
  for (let i = 0; i < coeffs.length; i++) {
13195
13209
  coeffs[i][0] = Math.exp(coeffs[i][0]);
13196
13210
  }
@@ -13780,7 +13794,7 @@ stores.inject(MyMetaStore, storeInstance);
13780
13794
  ],
13781
13795
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13782
13796
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13783
- 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));
13797
+ return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
13784
13798
  },
13785
13799
  };
13786
13800
  // -----------------------------------------------------------------------------
@@ -26311,7 +26325,7 @@ stores.inject(MyMetaStore, storeInstance);
26311
26325
  return {
26312
26326
  background: context.background,
26313
26327
  type: "scorecard",
26314
- keyValue: context.range ? context.range[0].dataRange : undefined,
26328
+ keyValue: context.range?.[0]?.dataRange,
26315
26329
  title: context.title || { text: "" },
26316
26330
  baselineMode: DEFAULT_SCORECARD_BASELINE_MODE,
26317
26331
  baselineColorUp: DEFAULT_SCORECARD_BASELINE_COLOR_UP,
@@ -29724,6 +29738,7 @@ stores.inject(MyMetaStore, storeInstance);
29724
29738
  parser: luxonFormat,
29725
29739
  displayFormats,
29726
29740
  unit: timeUnit ?? false,
29741
+ tooltipFormat: luxonFormat,
29727
29742
  };
29728
29743
  }
29729
29744
  /**
@@ -30500,7 +30515,7 @@ stores.inject(MyMetaStore, storeInstance);
30500
30515
  background: context.background,
30501
30516
  title: context.title || { text: "" },
30502
30517
  type: "gauge",
30503
- dataRange: context.range ? context.range[0].dataRange : undefined,
30518
+ dataRange: context.range?.[0]?.dataRange,
30504
30519
  sectionRule: {
30505
30520
  colors: {
30506
30521
  lowerColor: DEFAULT_GAUGE_LOWER_COLOR,
@@ -42176,12 +42191,13 @@ stores.inject(MyMetaStore, storeInstance);
42176
42191
  onCloseSidePanel: { type: Function, optional: true },
42177
42192
  };
42178
42193
  state = owl.useState({ rule: this.defaultDataValidationRule });
42194
+ editingSheetId;
42179
42195
  setup() {
42196
+ this.editingSheetId = this.env.model.getters.getActiveSheetId();
42180
42197
  if (this.props.rule) {
42181
- const sheetId = this.env.model.getters.getActiveSheetId();
42182
42198
  this.state.rule = {
42183
42199
  ...this.props.rule,
42184
- ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, sheetId)),
42200
+ ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
42185
42201
  };
42186
42202
  this.state.rule.criterion.type = this.props.rule.criterion.type;
42187
42203
  }
@@ -42215,7 +42231,6 @@ stores.inject(MyMetaStore, storeInstance);
42215
42231
  const locale = this.env.model.getters.getLocale();
42216
42232
  const criterion = rule.criterion;
42217
42233
  const criterionEvaluator = dataValidationEvaluatorRegistry.get(criterion.type);
42218
- const sheetId = this.env.model.getters.getActiveSheetId();
42219
42234
  const values = criterion.values
42220
42235
  .slice(0, criterionEvaluator.numberOfValues(criterion))
42221
42236
  .map((value) => value?.trim())
@@ -42223,8 +42238,8 @@ stores.inject(MyMetaStore, storeInstance);
42223
42238
  .map((value) => canonicalizeContent(value, locale));
42224
42239
  rule.criterion = { ...criterion, values };
42225
42240
  return {
42226
- sheetId,
42227
- ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
42241
+ sheetId: this.editingSheetId,
42242
+ ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
42228
42243
  rule,
42229
42244
  };
42230
42245
  }
@@ -55257,7 +55272,7 @@ stores.inject(MyMetaStore, storeInstance);
55257
55272
  let sheetName = "";
55258
55273
  if (prefixSheet) {
55259
55274
  if (rangeImpl.invalidSheetName) {
55260
- sheetName = rangeImpl.invalidSheetName;
55275
+ sheetName = getCanonicalSymbolName(rangeImpl.invalidSheetName);
55261
55276
  }
55262
55277
  else {
55263
55278
  sheetName = getCanonicalSymbolName(this.getters.getSheetName(rangeImpl.sheetId));
@@ -58538,7 +58553,7 @@ stores.inject(MyMetaStore, storeInstance);
58538
58553
  * in the correct order they should be evaluated.
58539
58554
  * This is called a topological ordering (excluding cycles)
58540
58555
  */
58541
- getCellsDependingOn(ranges) {
58556
+ getCellsDependingOn(ranges, ignore) {
58542
58557
  const visited = this.createEmptyPositionSet();
58543
58558
  const queue = Array.from(ranges).reverse();
58544
58559
  while (queue.length > 0) {
@@ -58553,7 +58568,7 @@ stores.inject(MyMetaStore, storeInstance);
58553
58568
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
58554
58569
  const nextInQueue = {};
58555
58570
  for (const position of impactedPositions) {
58556
- if (!visited.has(position)) {
58571
+ if (!visited.has(position) && !ignore.has(position)) {
58557
58572
  if (!nextInQueue[position.sheetId]) {
58558
58573
  nextInQueue[position.sheetId] = [];
58559
58574
  }
@@ -59106,7 +59121,7 @@ stores.inject(MyMetaStore, storeInstance);
59106
59121
  }
59107
59122
  invalidatePositionsDependingOnSpread(sheetId, resultZone) {
59108
59123
  // the result matrix is split in 2 zones to exclude the array formula position
59109
- const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
59124
+ const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
59110
59125
  invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
59111
59126
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
59112
59127
  }
@@ -59221,7 +59236,7 @@ stores.inject(MyMetaStore, storeInstance);
59221
59236
  for (const sheetId in zonesBySheetIds) {
59222
59237
  ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
59223
59238
  }
59224
- return this.formulaDependencies().getCellsDependingOn(ranges);
59239
+ return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
59225
59240
  }
59226
59241
  }
59227
59242
  function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
@@ -74747,9 +74762,9 @@ stores.inject(MyMetaStore, storeInstance);
74747
74762
  exports.tokenize = tokenize;
74748
74763
 
74749
74764
 
74750
- __info__.version = "18.0.46";
74751
- __info__.date = "2025-10-07T10:00:44.707Z";
74752
- __info__.hash = "67a1b4a";
74765
+ __info__.version = "18.0.48";
74766
+ __info__.date = "2025-11-12T14:15:38.406Z";
74767
+ __info__.hash = "d1efb0b";
74753
74768
 
74754
74769
 
74755
74770
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);