@odoo/o-spreadsheet 17.1.16 → 17.1.18

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 17.1.16
6
- * @date 2024-05-24T11:27:23.083Z
7
- * @hash 3a41c3a
5
+ * @version 17.1.18
6
+ * @date 2024-06-10T09:34:55.045Z
7
+ * @hash 0e756ce
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, onWillUnmount, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -293,7 +293,10 @@ function deepCopy(obj) {
293
293
  * Check if the object is a plain old javascript object.
294
294
  */
295
295
  function isPlainObject(obj) {
296
- return typeof obj === "object" && obj?.constructor === Object;
296
+ return (typeof obj === "object" &&
297
+ obj !== null &&
298
+ // obj.constructor can be undefined when there's no prototype (`Object.create(null, {})`)
299
+ (obj?.constructor === Object || obj?.constructor === undefined));
297
300
  }
298
301
  /**
299
302
  * Sanitize the name of a sheet, by eventually removing quotes
@@ -2605,7 +2608,7 @@ function evaluatePredicate(value, criterion) {
2605
2608
  return false;
2606
2609
  }
2607
2610
  if (typeof operand === "number" && operator === "=") {
2608
- return toString(value) === toString(operand);
2611
+ return value.toString() === operand.toString();
2609
2612
  }
2610
2613
  if (operator === "<>" || operator === "=") {
2611
2614
  let result;
@@ -2665,14 +2668,13 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
2665
2668
  if (countArg % 2 === 1) {
2666
2669
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
2667
2670
  }
2668
- const dimRow = args[0].length;
2669
- const dimCol = args[0][0].length;
2671
+ const firstArg = toMatrix(args[0]);
2672
+ const dimRow = firstArg.length;
2673
+ const dimCol = firstArg[0].length;
2670
2674
  let predicates = [];
2671
2675
  for (let i = 0; i < countArg - 1; i += 2) {
2672
- const criteriaRange = args[i];
2673
- if (!isMatrix(criteriaRange) ||
2674
- criteriaRange.length !== dimRow ||
2675
- criteriaRange[0].length !== dimCol) {
2676
+ const criteriaRange = toMatrix(args[i]);
2677
+ if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
2676
2678
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
2677
2679
  }
2678
2680
  const description = toString(args[i + 1]);
@@ -2682,7 +2684,7 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
2682
2684
  for (let j = 0; j < dimCol; j++) {
2683
2685
  let validatedPredicates = true;
2684
2686
  for (let k = 0; k < countArg - 1; k += 2) {
2685
- const criteriaValue = args[k][i][j].value;
2687
+ const criteriaValue = toMatrix(args[k])[i][j].value;
2686
2688
  const criterion = predicates[k / 2];
2687
2689
  validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2688
2690
  if (!validatedPredicates) {
@@ -4370,8 +4372,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
4370
4372
  /**
4371
4373
  * Create a range from a xc. If the xc is empty, this function returns undefined.
4372
4374
  */
4373
- function createRange(getters, sheetId, range) {
4374
- return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
4375
+ function createValidRange(getters, sheetId, xc) {
4376
+ if (!xc)
4377
+ return;
4378
+ const range = getters.getRangeFromSheetXC(sheetId, xc);
4379
+ return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
4375
4380
  }
4376
4381
  /**
4377
4382
  * Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
@@ -5302,8 +5307,8 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
5302
5307
  type = "scorecard";
5303
5308
  constructor(definition, sheetId, getters) {
5304
5309
  super(definition, sheetId, getters);
5305
- this.keyValue = createRange(getters, sheetId, definition.keyValue);
5306
- this.baseline = createRange(getters, sheetId, definition.baseline);
5310
+ this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
5311
+ this.baseline = createValidRange(getters, sheetId, definition.baseline);
5307
5312
  this.baselineMode = definition.baselineMode;
5308
5313
  this.baselineDescr = definition.baselineDescr;
5309
5314
  this.background = definition.background;
@@ -6837,8 +6842,7 @@ function isCtrlKey(ev) {
6837
6842
  */
6838
6843
  function useSpreadsheetRect() {
6839
6844
  const position = useState({ x: 0, y: 0, width: 0, height: 0 });
6840
- let spreadsheetElement = document.querySelector(".o-spreadsheet");
6841
- updatePosition();
6845
+ let spreadsheetElement = null;
6842
6846
  function updatePosition() {
6843
6847
  if (!spreadsheetElement) {
6844
6848
  spreadsheetElement = document.querySelector(".o-spreadsheet");
@@ -8602,7 +8606,7 @@ function chartToImage(runtime, figure, type) {
8602
8606
  if ("chartJsConfig" in runtime) {
8603
8607
  runtime.chartJsConfig.plugins = [backgroundColorChartJSPlugin];
8604
8608
  // @ts-ignore
8605
- const chart = new window.Chart(canvas, runtime.chartJsConfig);
8609
+ const chart = new window.Chart(canvas, deepCopy(runtime.chartJsConfig));
8606
8610
  const imgContent = chart.toBase64Image();
8607
8611
  chart.destroy();
8608
8612
  div.remove();
@@ -8646,7 +8650,7 @@ class BarChart extends AbstractChart {
8646
8650
  constructor(definition, sheetId, getters) {
8647
8651
  super(definition, sheetId, getters);
8648
8652
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
8649
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
8653
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
8650
8654
  this.background = definition.background;
8651
8655
  this.verticalAxisPosition = definition.verticalAxisPosition;
8652
8656
  this.legendPosition = definition.legendPosition;
@@ -8889,7 +8893,7 @@ class GaugeChart extends AbstractChart {
8889
8893
  type = "gauge";
8890
8894
  constructor(definition, sheetId, getters) {
8891
8895
  super(definition, sheetId, getters);
8892
- this.dataRange = createRange(this.getters, this.sheetId, definition.dataRange);
8896
+ this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
8893
8897
  this.sectionRule = definition.sectionRule;
8894
8898
  this.background = definition.background;
8895
8899
  }
@@ -9223,7 +9227,7 @@ class LineChart extends AbstractChart {
9223
9227
  constructor(definition, sheetId, getters) {
9224
9228
  super(definition, sheetId, getters);
9225
9229
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
9226
- this.labelRange = createRange(this.getters, sheetId, definition.labelRange);
9230
+ this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
9227
9231
  this.background = definition.background;
9228
9232
  this.verticalAxisPosition = definition.verticalAxisPosition;
9229
9233
  this.legendPosition = definition.legendPosition;
@@ -9543,7 +9547,7 @@ class PieChart extends AbstractChart {
9543
9547
  constructor(definition, sheetId, getters) {
9544
9548
  super(definition, sheetId, getters);
9545
9549
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
9546
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
9550
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
9547
9551
  this.background = definition.background;
9548
9552
  this.legendPosition = definition.legendPosition;
9549
9553
  this.aggregated = definition.aggregated;
@@ -11187,6 +11191,9 @@ function makeArg(str, description) {
11187
11191
  if (types.some((t) => t.startsWith("RANGE"))) {
11188
11192
  result.acceptMatrix = true;
11189
11193
  }
11194
+ if (types.every((t) => t.startsWith("RANGE"))) {
11195
+ result.acceptMatrixOnly = true;
11196
+ }
11190
11197
  return result;
11191
11198
  }
11192
11199
  /**
@@ -11468,11 +11475,16 @@ const CHOOSECOLS = {
11468
11475
  compute: function (array, ...columns) {
11469
11476
  const _array = toMatrix(array);
11470
11477
  const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
11471
- assert(() => _columns.every((col) => col > 0 && col <= _array.length), _t("The columns arguments must be between 1 and %s (got %s).", _array.length.toString(), (_columns.find((col) => col <= 0 || col > _array.length) || 0).toString()));
11478
+ const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
11479
+ assert(() => argOutOfRange.length === 0, _t("The columns arguments must be between -%s and %s (got %s), excluding 0.", _array.length.toString(), _array.length.toString(), argOutOfRange.join(",")));
11472
11480
  const result = Array(_columns.length);
11473
11481
  for (let col = 0; col < _columns.length; col++) {
11474
- const colIndex = _columns[col] - 1; // -1 because columns arguments are 1-indexed
11475
- result[col] = _array[colIndex];
11482
+ if (_columns[col] > 0) {
11483
+ result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
11484
+ }
11485
+ else {
11486
+ result[col] = _array[_array.length + _columns[col]];
11487
+ }
11476
11488
  }
11477
11489
  return result;
11478
11490
  },
@@ -11493,8 +11505,14 @@ const CHOOSEROWS = {
11493
11505
  const _array = toMatrix(array);
11494
11506
  const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
11495
11507
  const _nbColumns = _array.length;
11496
- assert(() => _rows.every((row) => row > 0 && row <= _array[0].length), _t("The rows arguments must be between 1 and %s (got %s).", _array[0].length.toString(), (_rows.find((row) => row <= 0 || row > _array[0].length) || 0).toString()));
11497
- return generateMatrix(_nbColumns, _rows.length, (col, row) => _array[col][_rows[row] - 1]); // -1 because rows arguments are 1-indexed
11508
+ const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
11509
+ assert(() => argOutOfRange.length === 0, _t("The rows arguments must be between -%s and %s (got %s), excluding 0.", _array[0].length.toString(), _array[0].length.toString(), argOutOfRange.join(",")));
11510
+ return generateMatrix(_nbColumns, _rows.length, (col, row) => {
11511
+ if (_rows[row] > 0) {
11512
+ return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
11513
+ }
11514
+ return _array[col][_array[col].length + _rows[row]];
11515
+ });
11498
11516
  },
11499
11517
  isExported: true,
11500
11518
  };
@@ -12402,7 +12420,7 @@ const COUNTUNIQUEIFS = {
12402
12420
  compute: function (range, ...args) {
12403
12421
  let uniqueValues = new Set();
12404
12422
  visitMatchingRanges(args, (i, j) => {
12405
- const data = range[i][j];
12423
+ const data = range[i]?.[j];
12406
12424
  if (isDefined(data)) {
12407
12425
  uniqueValues.add(data.value);
12408
12426
  }
@@ -13032,7 +13050,7 @@ const SUMIF = {
13032
13050
  }
13033
13051
  let sum = 0;
13034
13052
  visitMatchingRanges([criteriaRange, criterion], (i, j) => {
13035
- const value = sumRange[i][j].value;
13053
+ const value = sumRange[i]?.[j]?.value;
13036
13054
  if (typeof value === "number") {
13037
13055
  sum += value;
13038
13056
  }
@@ -13057,7 +13075,7 @@ const SUMIFS = {
13057
13075
  compute: function (sumRange, ...criters) {
13058
13076
  let sum = 0;
13059
13077
  visitMatchingRanges(criters, (i, j) => {
13060
- const value = sumRange[i][j].value;
13078
+ const value = sumRange[i]?.[j]?.value;
13061
13079
  if (typeof value === "number") {
13062
13080
  sum += value;
13063
13081
  }
@@ -13604,7 +13622,7 @@ const AVERAGEIF = {
13604
13622
  let count = 0;
13605
13623
  let sum = 0;
13606
13624
  visitMatchingRanges([criteriaRange, criterion], (i, j) => {
13607
- const value = _averageRange[i][j].value;
13625
+ const value = _averageRange[i]?.[j]?.value;
13608
13626
  if (typeof value === "number") {
13609
13627
  count += 1;
13610
13628
  sum += value;
@@ -13633,7 +13651,7 @@ const AVERAGEIFS = {
13633
13651
  let count = 0;
13634
13652
  let sum = 0;
13635
13653
  visitMatchingRanges(args, (i, j) => {
13636
- const value = _averageRange[i][j].value;
13654
+ const value = _averageRange[i]?.[j]?.value;
13637
13655
  if (typeof value === "number") {
13638
13656
  count += 1;
13639
13657
  sum += value;
@@ -13938,7 +13956,7 @@ const MAXIFS = {
13938
13956
  compute: function (range, ...args) {
13939
13957
  let result = -Infinity;
13940
13958
  visitMatchingRanges(args, (i, j) => {
13941
- const value = range[i][j].value;
13959
+ const value = range[i]?.[j]?.value;
13942
13960
  if (typeof value === "number") {
13943
13961
  result = result < value ? value : result;
13944
13962
  }
@@ -14021,7 +14039,7 @@ const MINIFS = {
14021
14039
  compute: function (range, ...args) {
14022
14040
  let result = Infinity;
14023
14041
  visitMatchingRanges(args, (i, j) => {
14024
- const value = range[i][j].value;
14042
+ const value = range[i]?.[j]?.value;
14025
14043
  if (typeof value === "number") {
14026
14044
  result = result > value ? value : result;
14027
14045
  }
@@ -19798,6 +19816,9 @@ function addInputHandling(descr) {
19798
19816
  }
19799
19817
  args[i] = arg[0][0];
19800
19818
  }
19819
+ if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
19820
+ throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
19821
+ }
19801
19822
  }
19802
19823
  return descr.compute.apply(this, args);
19803
19824
  }
@@ -22150,7 +22171,7 @@ class LineBarPieConfigPanel extends Component {
22150
22171
  }
22151
22172
  const getters = this.env.model.getters;
22152
22173
  const sheetId = getters.getActiveSheetId();
22153
- const labelRange = createRange(getters, sheetId, this.labelRange);
22174
+ const labelRange = createValidRange(getters, sheetId, this.labelRange);
22154
22175
  const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
22155
22176
  if (dataSets.length) {
22156
22177
  return dataSets[0].dataRange.zone.top + 1;
@@ -26273,14 +26294,14 @@ class FigureComponent extends Component {
26273
26294
  }
26274
26295
  onKeyDown(ev) {
26275
26296
  const figure = this.props.figure;
26276
- switch (ev.key) {
26297
+ const keyDownShortcut = keyboardEventToShortcutString(ev);
26298
+ switch (keyDownShortcut) {
26277
26299
  case "Delete":
26278
26300
  this.env.model.dispatch("DELETE_FIGURE", {
26279
26301
  sheetId: this.env.model.getters.getActiveSheetId(),
26280
26302
  id: figure.id,
26281
26303
  });
26282
26304
  this.props.onFigureDeleted();
26283
- ev.stopPropagation();
26284
26305
  ev.preventDefault();
26285
26306
  ev.stopPropagation();
26286
26307
  break;
@@ -26301,7 +26322,22 @@ class FigureComponent extends Component {
26301
26322
  x: figure.x + delta[0],
26302
26323
  y: figure.y + delta[1],
26303
26324
  });
26325
+ ev.preventDefault();
26304
26326
  ev.stopPropagation();
26327
+ break;
26328
+ case "Ctrl+A":
26329
+ // Maybe in the future we will implement a way to select all figures
26330
+ ev.preventDefault();
26331
+ ev.stopPropagation();
26332
+ break;
26333
+ case "Ctrl+Y":
26334
+ case "Ctrl+Z":
26335
+ if (keyDownShortcut === "Ctrl+Y") {
26336
+ this.env.model.dispatch("REQUEST_REDO");
26337
+ }
26338
+ else if (keyDownShortcut === "Ctrl+Z") {
26339
+ this.env.model.dispatch("REQUEST_UNDO");
26340
+ }
26305
26341
  ev.preventDefault();
26306
26342
  ev.stopPropagation();
26307
26343
  break;
@@ -27339,8 +27375,15 @@ class Composer extends Component {
27339
27375
  }
27340
27376
  onPaste(ev) {
27341
27377
  if (this.env.model.getters.getEditionMode() !== "inactive") {
27378
+ // let the browser clipboard work
27342
27379
  ev.stopPropagation();
27343
27380
  }
27381
+ else {
27382
+ // the user meant to paste in the sheet, not open the composer with the pasted content
27383
+ // While we're not editing, we still have the focus and should therefore prevent
27384
+ // the native "paste" to occur.
27385
+ ev.preventDefault();
27386
+ }
27344
27387
  }
27345
27388
  /*
27346
27389
  * Triggered automatically by the content-editable between the keydown and key up
@@ -27349,10 +27392,6 @@ class Composer extends Component {
27349
27392
  if (!this.shouldProcessInputEvents) {
27350
27393
  return;
27351
27394
  }
27352
- if (ev.inputType === "insertFromPaste" &&
27353
- this.env.model.getters.getEditionMode() === "inactive") {
27354
- return;
27355
- }
27356
27395
  ev.stopPropagation();
27357
27396
  let content;
27358
27397
  if (this.env.model.getters.getEditionMode() === "inactive") {
@@ -27793,10 +27832,7 @@ class GridComposer extends Component {
27793
27832
  }
27794
27833
  get containerStyle() {
27795
27834
  if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
27796
- return `
27797
- position: absolute;
27798
- z-index: -1000;
27799
- `;
27835
+ return `z-index: -1000;`;
27800
27836
  }
27801
27837
  const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
27802
27838
  const cell = this.env.model.getters.getActiveCell();
@@ -35762,12 +35798,6 @@ function compileTokens(tokens) {
35762
35798
  // detect when an argument need to be evaluated as a meta argument
35763
35799
  const isMeta = argTypes.includes("META");
35764
35800
  const hasRange = argTypes.some((t) => isRangeType(t));
35765
- const isRangeOnly = argTypes.every((t) => isRangeType(t));
35766
- if (isRangeOnly) {
35767
- if (!isRangeInput(currentArg)) {
35768
- throw new BadExpressionError(_t("Function %s expects the parameter %s to be reference to a cell or range, not a %s.", functionName, (i + 1).toString(), currentArg.type.toLowerCase()));
35769
- }
35770
- }
35771
35801
  compiledArgs.push(compileAST(currentArg, isMeta, hasRange, {
35772
35802
  functionName,
35773
35803
  paramIndex: i + 1,
@@ -35938,16 +35968,6 @@ function assertEnoughArgs(ast) {
35938
35968
  function isRangeType(type) {
35939
35969
  return type.startsWith("RANGE");
35940
35970
  }
35941
- function isRangeInput(arg) {
35942
- if (arg.type === "REFERENCE") {
35943
- return true;
35944
- }
35945
- if (arg.type === "FUNCALL") {
35946
- const fnDef = functions$1[arg.value.toUpperCase()];
35947
- return fnDef && isRangeType(fnDef.returns[0]);
35948
- }
35949
- return false;
35950
- }
35951
35971
 
35952
35972
  /**
35953
35973
  * Add the following information on tokens:
@@ -39060,6 +39080,9 @@ class RangeAdapter {
39060
39080
  if (range.invalidXc) {
39061
39081
  return range.invalidXc;
39062
39082
  }
39083
+ if (!this.getters.tryGetSheet(range.sheetId)) {
39084
+ return CellErrorType.InvalidReference;
39085
+ }
39063
39086
  if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
39064
39087
  return CellErrorType.InvalidReference;
39065
39088
  }
@@ -42507,16 +42530,22 @@ class EvaluationPlugin extends UIPlugin {
42507
42530
  let newContent = undefined;
42508
42531
  let newFormat = undefined;
42509
42532
  let isExported = true;
42533
+ const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
42510
42534
  const formulaCell = this.getCorrespondingFormulaCell(position);
42511
42535
  if (formulaCell) {
42512
42536
  isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
42513
42537
  isFormula = isExported;
42514
42538
  if (!isExported) {
42515
- newContent = value.toString();
42516
- newFormat = evaluatedCell.format;
42539
+ // If the cell contains a non-exported formula and that is evaluates to
42540
+ // nothing* ,we don't export it.
42541
+ // * non-falsy value are relevant and so are 0 and FALSE, which only leaves
42542
+ // the empty string.
42543
+ if (value !== "") {
42544
+ newContent = value.toString();
42545
+ newFormat = evaluatedCell.format;
42546
+ }
42517
42547
  }
42518
42548
  }
42519
- const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
42520
42549
  const exportedCellData = exportedSheetData.cells[xc] || {};
42521
42550
  const format = newFormat
42522
42551
  ? getItemId(newFormat, data.formats)
@@ -52013,9 +52042,11 @@ class BottomBarSheet extends Component {
52013
52042
  if (ev.key === "Enter") {
52014
52043
  ev.preventDefault();
52015
52044
  this.stopEdition();
52045
+ this.env.focusableElement.focus();
52016
52046
  }
52017
52047
  if (ev.key === "Escape") {
52018
52048
  this.cancelEdition();
52049
+ this.env.focusableElement.focus();
52019
52050
  }
52020
52051
  }
52021
52052
  onClickSheetName(ev) {
@@ -56710,7 +56741,11 @@ function addRows(construct, data, sheet) {
56710
56741
  let cellNode = escapeXml ``;
56711
56742
  // Either formula or static value inside the cell
56712
56743
  if (cell.isFormula) {
56713
- ({ attrs: additionalAttrs, node: cellNode } = addFormula(cell));
56744
+ const res = addFormula(cell);
56745
+ if (!res) {
56746
+ continue;
56747
+ }
56748
+ ({ attrs: additionalAttrs, node: cellNode } = res);
56714
56749
  }
56715
56750
  else if (cell.content && isMarkdownLink(cell.content)) {
56716
56751
  const { label } = parseMarkdownLink(cell.content);
@@ -57704,6 +57739,6 @@ const constants = {
57704
57739
  export { AbstractChart, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
57705
57740
 
57706
57741
 
57707
- __info__.version = "17.1.16";
57708
- __info__.date = "2024-05-24T11:27:23.083Z";
57709
- __info__.hash = "3a41c3a";
57742
+ __info__.version = "17.1.18";
57743
+ __info__.date = "2024-06-10T09:34:55.045Z";
57744
+ __info__.hash = "0e756ce";