@odoo/o-spreadsheet 19.3.16 → 19.3.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 19.3.16
6
- * @date 2026-08-12T09:15:31.627Z
7
- * @hash 464be42
5
+ * @version 19.3.18
6
+ * @date 2026-08-29T09:16:28.272Z
7
+ * @hash 1f4b1ae
8
8
  */
9
9
 
10
10
  import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, whenReady, xml } from "@odoo/owl";
@@ -4069,6 +4069,18 @@ function toString(data) {
4069
4069
  default: return "";
4070
4070
  }
4071
4071
  }
4072
+ /**
4073
+ * Only converts the decimal separator, ignore number format such as % or dates
4074
+ */
4075
+ function toLocaleString(data, locale) {
4076
+ const value = toValue(data);
4077
+ switch (typeof value) {
4078
+ case "string": return value;
4079
+ case "number": return value.toString().replace(".", locale.decimalSeparator);
4080
+ case "boolean": return value ? "TRUE" : "FALSE";
4081
+ default: return "";
4082
+ }
4083
+ }
4072
4084
  /** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
4073
4085
  const normalizeString = memoize(function normalizeString(str) {
4074
4086
  return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
@@ -10473,6 +10485,7 @@ function getRadarChartDatasets(definition, args) {
10473
10485
  hidden,
10474
10486
  borderColor,
10475
10487
  backgroundColor: borderColor,
10488
+ pointBackgroundColor: borderColor,
10476
10489
  pointRadius: definition.hideDataMarkers ? 0 : 3
10477
10490
  };
10478
10491
  if (fill) {
@@ -29087,12 +29100,13 @@ var FilterMenu = class extends Component {
29087
29100
  }
29088
29101
  sortFilterZone(sortDirection) {
29089
29102
  const filterPosition = this.props.filterPosition;
29090
- const tableZone = this.table?.range.zone;
29103
+ const table = this.table;
29104
+ const tableZone = table?.range.zone;
29091
29105
  if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
29092
29106
  const sheetId = this.env.model.getters.getActiveSheetId();
29093
29107
  const contentZone = {
29094
29108
  ...tableZone,
29095
- top: tableZone.top + 1
29109
+ top: tableZone.top + table.config.numberOfHeaders
29096
29110
  };
29097
29111
  const sortAnchor = {
29098
29112
  col: filterPosition.col,
@@ -49825,6 +49839,7 @@ var Squisher = class {
49825
49839
  baseFormulaWasTransformed = false;
49826
49840
  rangeToStringOptions = { doNotSimplifyRange: true };
49827
49841
  baseNumber = void 0;
49842
+ baseNumberFormat = void 0;
49828
49843
  constructor(getters) {
49829
49844
  this.getters = getters;
49830
49845
  }
@@ -49859,6 +49874,11 @@ var Squisher = class {
49859
49874
  this.baseFormulaWasTransformed = false;
49860
49875
  }
49861
49876
  }
49877
+ /** Reset the base number literal chain, so the next literal number cannot be squished as an offset of it */
49878
+ resetBaseNumber() {
49879
+ this.baseNumber = void 0;
49880
+ this.baseNumberFormat = void 0;
49881
+ }
49862
49882
  /**
49863
49883
  * Takes a cell and squish their formulas against the previous one (in the previous call).
49864
49884
  * We should call this method for each cell in the sheet, in order from top to bottom, then from left to right (all cells of a columns, for each columns left to right).
@@ -49897,8 +49917,9 @@ var Squisher = class {
49897
49917
  if (typeof cell.parsedValue === "number" && cell.parsedValue % 1 === 0) {
49898
49918
  this.resetBaseFormula();
49899
49919
  const numberValue = cell.parsedValue;
49900
- if (this.baseNumber === void 0) {
49920
+ if (this.baseNumber === void 0 || cell.format !== this.baseNumberFormat) {
49901
49921
  this.baseNumber = numberValue;
49922
+ this.baseNumberFormat = cell.format;
49902
49923
  return cell.content;
49903
49924
  }
49904
49925
  const numberOffset = numberValue - this.baseNumber;
@@ -49909,7 +49930,7 @@ var Squisher = class {
49909
49930
  }
49910
49931
  }
49911
49932
  this.resetBaseFormula();
49912
- this.baseNumber = void 0;
49933
+ this.resetBaseNumber();
49913
49934
  return cell.content;
49914
49935
  }
49915
49936
  squishCommand(command) {
@@ -49918,6 +49939,8 @@ var Squisher = class {
49918
49939
  const squished = this.squish(cell, command.sheetId);
49919
49940
  return typeof squished === "string" ? command.content : squished;
49920
49941
  }
49942
+ this.resetBaseFormula();
49943
+ this.resetBaseNumber();
49921
49944
  return command.content;
49922
49945
  }
49923
49946
  /**
@@ -50071,8 +50094,10 @@ var Unsquisher = class {
50071
50094
  continue;
50072
50095
  }
50073
50096
  const current = command.content;
50074
- if (current === void 0 || current === null || current === "") strategy = "NOT_A_FORMULA";
50075
- else strategy = this.chooseStrategy(current, strategy, command.sheetId, getters);
50097
+ if (current === void 0 || current === null || current === "") {
50098
+ this.rebase();
50099
+ strategy = "NOT_A_FORMULA";
50100
+ } else strategy = this.chooseStrategy(current, strategy, command.sheetId, getters);
50076
50101
  let targetPositions;
50077
50102
  if (command.type === "SQUISHED_UPDATE_CELL" && "targetRange" in command) {
50078
50103
  const [start, end] = command.targetRange.split(":");
@@ -50117,8 +50142,11 @@ var Unsquisher = class {
50117
50142
  let strategy;
50118
50143
  for (const { key } of keys) {
50119
50144
  const current = squished[key];
50120
- if (current === void 0 || current === null || current === "") continue;
50121
- else strategy = this.chooseStrategy(current, strategy, sheetId, getters);
50145
+ if (current === void 0 || current === null || current === "") {
50146
+ this.rebase();
50147
+ strategy = void 0;
50148
+ continue;
50149
+ } else strategy = this.chooseStrategy(current, strategy, sheetId, getters);
50122
50150
  const parts = key.split(":");
50123
50151
  const targetPositions = parts.length === 1 ? expandXc(key) : expandRange(parts[0], parts[1]);
50124
50152
  yield* this.applyStrategy(strategy, targetPositions, current, sheetId, getters);
@@ -50164,6 +50192,9 @@ var Unsquisher = class {
50164
50192
  case "FIRST_OFFSET":
50165
50193
  strategy = "COMBINE_OFFSET";
50166
50194
  break;
50195
+ case "COMBINE_OFFSET":
50196
+ case "OFFSET_NUMBER": break;
50197
+ default: throw new Error(`Cannot unsquish an offset without a preceding base cell: ${strategy}`);
50167
50198
  }
50168
50199
  }
50169
50200
  return strategy;
@@ -60762,6 +60793,7 @@ var Session = class extends EventBus {
60762
60793
  transportService;
60763
60794
  serverRevisionId;
60764
60795
  commandSquisher;
60796
+ shouldVerifySquish;
60765
60797
  /**
60766
60798
  * Positions of the others client.
60767
60799
  */
@@ -60796,13 +60828,15 @@ var Session = class extends EventBus {
60796
60828
  * between all connected clients
60797
60829
  * @param serverRevisionId
60798
60830
  * @param commandSquisher used to squish and unsquish commands to reduce the size of messages sent to the server
60831
+ * @param shouldVerifySquish either the commands should be unsquished and verified before being sent to the server
60799
60832
  */
60800
- constructor(revisions, transportService, serverRevisionId = DEFAULT_REVISION_ID, commandSquisher) {
60833
+ constructor(revisions, transportService, serverRevisionId = DEFAULT_REVISION_ID, commandSquisher, shouldVerifySquish = true) {
60801
60834
  super();
60802
60835
  this.revisions = revisions;
60803
60836
  this.transportService = transportService;
60804
60837
  this.serverRevisionId = serverRevisionId;
60805
60838
  this.commandSquisher = commandSquisher;
60839
+ this.shouldVerifySquish = shouldVerifySquish;
60806
60840
  }
60807
60841
  canApplyOptimisticUpdate() {
60808
60842
  return !this.waitingUndoRedoAck;
@@ -61058,10 +61092,20 @@ var Session = class extends EventBus {
61058
61092
  this.revisions.rebase(revision.id);
61059
61093
  revision = this.revisions.get(message.nextRevisionId);
61060
61094
  }
61061
- message = {
61095
+ const squishedCommands = this.commandSquisher.squish(revision.commands);
61096
+ if (!squishedCommands.some((x) => x.type === "SQUISHED_UPDATE_CELL")) message = {
61062
61097
  ...message,
61063
61098
  commands: revision.commands
61064
61099
  };
61100
+ else if (this.shouldVerifySquish && !deepEquals(revision.commands, this.commandSquisher.unsquish(squishedCommands))) message = {
61101
+ ...message,
61102
+ commands: revision.commands,
61103
+ squishedFailed: true
61104
+ };
61105
+ else message = {
61106
+ ...message,
61107
+ commands: squishedCommands
61108
+ };
61065
61109
  }
61066
61110
  if (this.isReplayingInitialRevisions) throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
61067
61111
  ${JSON.stringify(message)}`);
@@ -77214,7 +77258,7 @@ const ARRAYTOTEXT = {
77214
77258
  else if (_format === 0) {
77215
77259
  const rowSeparator = this.locale.decimalSeparator === "," ? "/" : ",";
77216
77260
  return transposeMatrix(_array).flatMap((row) => row.map((value) => {
77217
- return isEvaluationError(value.value) ? value.value : toString(value);
77261
+ return isEvaluationError(value.value) ? value.value : toLocaleString(value, this.locale);
77218
77262
  })).join(rowSeparator);
77219
77263
  } else return new EvaluationError(_t("Format must be 0 or 1"));
77220
77264
  },
@@ -82975,7 +83019,7 @@ const CONCAT = {
82975
83019
  description: _t("Concatenation of two values."),
82976
83020
  args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
82977
83021
  compute: function(value1, value2) {
82978
- return toString(value1) + toString(value2);
83022
+ return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
82979
83023
  },
82980
83024
  isExported: true
82981
83025
  };
@@ -83840,7 +83884,7 @@ const CLEAN = {
83840
83884
  description: _t("Remove non-printable characters from a piece of text."),
83841
83885
  args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
83842
83886
  compute: function(text) {
83843
- const _text = toString(text);
83887
+ const _text = toLocaleString(text, this.locale);
83844
83888
  let cleanedStr = "";
83845
83889
  for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
83846
83890
  return cleanedStr;
@@ -83851,7 +83895,7 @@ const CONCATENATE = {
83851
83895
  description: _t("Appends strings to one another."),
83852
83896
  args: [arg("string (string, range<string>, repeating)", _t("String to append in sequence."))],
83853
83897
  compute: function(...datas) {
83854
- return reduceAny(datas, (acc, a) => acc + toString(a), "");
83898
+ return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
83855
83899
  },
83856
83900
  isExported: true
83857
83901
  };
@@ -83859,7 +83903,7 @@ const EXACT = {
83859
83903
  description: _t("Tests whether two strings are identical."),
83860
83904
  args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
83861
83905
  compute: function(string1, string2) {
83862
- return toString(string1) === toString(string2);
83906
+ return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
83863
83907
  },
83864
83908
  isExported: true
83865
83909
  };
@@ -83871,8 +83915,8 @@ const FIND = {
83871
83915
  arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
83872
83916
  ],
83873
83917
  compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
83874
- const _searchFor = toString(searchFor);
83875
- const _textToSearch = toString(textToSearch);
83918
+ const _searchFor = toLocaleString(searchFor, this.locale);
83919
+ const _textToSearch = toLocaleString(textToSearch, this.locale);
83876
83920
  const _startingAt = toNumber(startingAt, this.locale);
83877
83921
  if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
83878
83922
  if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
@@ -83909,8 +83953,8 @@ const JOIN = {
83909
83953
  description: _t("Concatenates elements of arrays with delimiter."),
83910
83954
  args: [arg("delimiter (string)", _t("The character or string to place between each concatenated value.")), arg("value_or_array (string, range<string>, repeating)", _t("Value to be appended using delimiter."))],
83911
83955
  compute: function(delimiter, ...valuesOrArrays) {
83912
- const _delimiter = toString(delimiter);
83913
- return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toString(a), "");
83956
+ const _delimiter = toLocaleString(delimiter, this.locale);
83957
+ return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
83914
83958
  }
83915
83959
  };
83916
83960
  const LEFT = {
@@ -83919,7 +83963,7 @@ const LEFT = {
83919
83963
  compute: function(text, ...args) {
83920
83964
  const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
83921
83965
  if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
83922
- return toString(text).substring(0, _numberOfCharacters);
83966
+ return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
83923
83967
  },
83924
83968
  isExported: true
83925
83969
  };
@@ -83927,7 +83971,7 @@ const LEN = {
83927
83971
  description: _t("Length of a string."),
83928
83972
  args: [arg("text (string)", _t("The string whose length will be returned."))],
83929
83973
  compute: function(text) {
83930
- return toString(text).length;
83974
+ return toLocaleString(text, this.locale).length;
83931
83975
  },
83932
83976
  isExported: true
83933
83977
  };
@@ -83935,7 +83979,7 @@ const LOWER = {
83935
83979
  description: _t("Converts a specified string to lowercase."),
83936
83980
  args: [arg("text (string)", _t("The string to convert to lowercase."))],
83937
83981
  compute: function(text) {
83938
- return toString(text).toLowerCase();
83982
+ return toLocaleString(text, this.locale).toLowerCase();
83939
83983
  },
83940
83984
  isExported: true
83941
83985
  };
@@ -83947,7 +83991,7 @@ const MID = {
83947
83991
  arg("extract_length (number)", _t("The length of the segment to extract."))
83948
83992
  ],
83949
83993
  compute: function(text, starting_at, extract_length) {
83950
- const _text = toString(text);
83994
+ const _text = toLocaleString(text, this.locale);
83951
83995
  const _starting_at = toNumber(starting_at, this.locale);
83952
83996
  const _extract_length = toNumber(extract_length, this.locale);
83953
83997
  if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
@@ -83960,7 +84004,7 @@ const PROPER = {
83960
84004
  description: _t("Capitalizes each word in a specified string."),
83961
84005
  args: [arg("text_to_capitalize (string)", _t("The text which will be returned with the first letter of each word in uppercase and all other letters in lowercase."))],
83962
84006
  compute: function(text) {
83963
- return toString(text).replace(wordRegex, (word) => {
84007
+ return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
83964
84008
  return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
83965
84009
  });
83966
84010
  },
@@ -84108,9 +84152,9 @@ const REPLACE = {
84108
84152
  compute: function(text, position, length, newText) {
84109
84153
  const _position = toNumber(position, this.locale);
84110
84154
  if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
84111
- const _text = toString(text);
84155
+ const _text = toLocaleString(text, this.locale);
84112
84156
  const _length = toNumber(length, this.locale);
84113
- const _newText = toString(newText);
84157
+ const _newText = toLocaleString(newText, this.locale);
84114
84158
  return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
84115
84159
  },
84116
84160
  isExported: true
@@ -84121,7 +84165,7 @@ const RIGHT = {
84121
84165
  compute: function(text, ...args) {
84122
84166
  const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
84123
84167
  if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
84124
- const _text = toString(text);
84168
+ const _text = toLocaleString(text, this.locale);
84125
84169
  const stringLength = _text.length;
84126
84170
  return _text.substring(stringLength - _numberOfCharacters, stringLength);
84127
84171
  },
@@ -84135,8 +84179,8 @@ const SEARCH = {
84135
84179
  arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
84136
84180
  ],
84137
84181
  compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
84138
- const _searchFor = toString(searchFor).toLowerCase();
84139
- const _textToSearch = toString(textToSearch).toLowerCase();
84182
+ const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
84183
+ const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
84140
84184
  const _startingAt = toNumber(startingAt, this.locale);
84141
84185
  if (_textToSearch === "") return {
84142
84186
  value: CellErrorType.GenericError,
@@ -84166,8 +84210,8 @@ const SPLIT = {
84166
84210
  arg(`remove_empty_text (boolean, default=${SPLIT_DEFAULT_REMOVE_EMPTY_TEXT})`, _t("Whether or not to remove empty text messages from the split results. The default behavior is to treat consecutive delimiters as one (if TRUE). If FALSE, empty cells values are added between consecutive delimiters."))
84167
84211
  ],
84168
84212
  compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
84169
- const _text = toString(text);
84170
- const _delimiter = escapeRegExp(toString(delimiter));
84213
+ const _text = toLocaleString(text, this.locale);
84214
+ const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
84171
84215
  const _splitByEach = toBoolean(splitByEach);
84172
84216
  const _removeEmptyText = toBoolean(removeEmptyText);
84173
84217
  if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
@@ -84189,10 +84233,10 @@ const SUBSTITUTE = {
84189
84233
  compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
84190
84234
  const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
84191
84235
  if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
84192
- const _textToSearch = toString(textToSearch);
84193
- const _searchFor = toString(searchFor);
84236
+ const _textToSearch = toLocaleString(textToSearch, this.locale);
84237
+ const _searchFor = toLocaleString(searchFor, this.locale);
84194
84238
  if (_searchFor === "") return _textToSearch;
84195
- const _replaceWith = toString(replaceWith);
84239
+ const _replaceWith = toLocaleString(replaceWith, this.locale);
84196
84240
  const reg = new RegExp(escapeRegExp(_searchFor), "g");
84197
84241
  if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
84198
84242
  let n = 0;
@@ -84215,10 +84259,10 @@ const TEXTJOIN = {
84215
84259
  arg("texts (string, range<string>, repeating)", _t("Text item to join."))
84216
84260
  ],
84217
84261
  compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
84218
- const _delimiter = toString(delimiter);
84262
+ const _delimiter = toLocaleString(delimiter, this.locale);
84219
84263
  const _ignoreEmpty = toBoolean(ignoreEmpty);
84220
84264
  let n = 0;
84221
- return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toString(a) === "") ? (n++ ? acc + _delimiter : "") + toString(a) : acc, "");
84265
+ return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
84222
84266
  },
84223
84267
  isExported: true
84224
84268
  };
@@ -84271,7 +84315,7 @@ const TRIM = {
84271
84315
  description: _t("Removes space characters."),
84272
84316
  args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
84273
84317
  compute: function(text) {
84274
- return trimContent(toString(text));
84318
+ return trimContent(toLocaleString(text, this.locale));
84275
84319
  },
84276
84320
  isExported: true
84277
84321
  };
@@ -84279,7 +84323,7 @@ const UPPER = {
84279
84323
  description: _t("Converts a specified string to uppercase."),
84280
84324
  args: [arg("text (string)", _t("The string to convert to uppercase."))],
84281
84325
  compute: function(text) {
84282
- return toString(text).toUpperCase();
84326
+ return toLocaleString(text, this.locale).toUpperCase();
84283
84327
  },
84284
84328
  isExported: true
84285
84329
  };
@@ -84376,7 +84420,7 @@ const HYPERLINK = {
84376
84420
  args: [arg("url (string)", _t("The full URL of the link enclosed in quotation marks.")), arg("link_label (string, optional)", _t("The text to display in the cell, enclosed in quotation marks."))],
84377
84421
  compute: function(url, linkLabel) {
84378
84422
  const processedUrl = toString(url).trim();
84379
- const processedLabel = toString(linkLabel) || processedUrl;
84423
+ const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
84380
84424
  if (processedUrl === "") return processedLabel;
84381
84425
  return markdownLink(processedLabel, processedUrl);
84382
84426
  },
@@ -84715,6 +84759,6 @@ const chartHelpers = {
84715
84759
  //#endregion
84716
84760
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, canExecuteInReadonly, categories, chartHelpers, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isSheetDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
84717
84761
 
84718
- __info__.version = "19.3.16";
84719
- __info__.date = "2026-08-12T09:15:31.627Z";
84720
- __info__.hash = "464be42";
84762
+ __info__.version = "19.3.18";
84763
+ __info__.date = "2026-08-29T09:16:28.272Z";
84764
+ __info__.hash = "1f4b1ae";