@odoo/o-spreadsheet 19.3.15 → 19.3.17
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.
- package/dist/o_spreadsheet.cjs +62 -40
- package/dist/o_spreadsheet.css +5 -3
- package/dist/o_spreadsheet.esm.js +62 -40
- package/dist/o_spreadsheet.iife.js +62 -40
- package/dist/o_spreadsheet.min.iife.js +252 -252
- package/dist/o_spreadsheet.xml +3 -3
- package/dist/types/functions/function_registry.d.ts +3 -0
- package/dist/types/functions/helpers.d.ts +4 -0
- package/dist/types/functions/module_operators.d.ts +1 -1
- package/dist/types/functions/module_text.d.ts +11 -11
- package/dist/types/functions/module_web.d.ts +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/plugins/core/squisher.d.ts +2 -1
- package/package.json +1 -1
package/dist/o_spreadsheet.cjs
CHANGED
|
@@ -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.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.17
|
|
6
|
+
* @date 2026-08-21T15:31:50.940Z
|
|
7
|
+
* @hash cf8c614
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
@@ -4070,6 +4070,18 @@ function toString(data) {
|
|
|
4070
4070
|
default: return "";
|
|
4071
4071
|
}
|
|
4072
4072
|
}
|
|
4073
|
+
/**
|
|
4074
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
4075
|
+
*/
|
|
4076
|
+
function toLocaleString(data, locale) {
|
|
4077
|
+
const value = toValue(data);
|
|
4078
|
+
switch (typeof value) {
|
|
4079
|
+
case "string": return value;
|
|
4080
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
4081
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
4082
|
+
default: return "";
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4073
4085
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
4074
4086
|
const normalizeString = memoize(function normalizeString(str) {
|
|
4075
4087
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -4744,6 +4756,9 @@ var FunctionRegistry = class extends Registry {
|
|
|
4744
4756
|
}
|
|
4745
4757
|
};
|
|
4746
4758
|
const functionRegistry = new FunctionRegistry();
|
|
4759
|
+
/** Formulas using one of these functions are never squished: they are always exported
|
|
4760
|
+
* as a full formula string, and they don't become the base formula of the next cells. */
|
|
4761
|
+
const NonSquishableFunctionRegistry = new Registry();
|
|
4747
4762
|
|
|
4748
4763
|
//#endregion
|
|
4749
4764
|
//#region src/types/locale.ts
|
|
@@ -29085,12 +29100,13 @@ var FilterMenu = class extends _odoo_owl.Component {
|
|
|
29085
29100
|
}
|
|
29086
29101
|
sortFilterZone(sortDirection) {
|
|
29087
29102
|
const filterPosition = this.props.filterPosition;
|
|
29088
|
-
const
|
|
29103
|
+
const table = this.table;
|
|
29104
|
+
const tableZone = table?.range.zone;
|
|
29089
29105
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
29090
29106
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
29091
29107
|
const contentZone = {
|
|
29092
29108
|
...tableZone,
|
|
29093
|
-
top: tableZone.top +
|
|
29109
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
29094
29110
|
};
|
|
29095
29111
|
const sortAnchor = {
|
|
29096
29112
|
col: filterPosition.col,
|
|
@@ -49864,7 +49880,8 @@ var Squisher = class {
|
|
|
49864
49880
|
* The result of this method is:
|
|
49865
49881
|
* - if the cell is not a formula, returns the content as is and resets the base formula
|
|
49866
49882
|
* - if the cell is a formula:
|
|
49867
|
-
* - if there is no previous formula, or the normalized formula is different from the previous one
|
|
49883
|
+
* - if there is no previous formula, or the normalized formula is different from the previous one or it contains blacklisted functions (see NonSquishableFunctionRegistry),
|
|
49884
|
+
* resets the base formula to this one and returns the full formula string
|
|
49868
49885
|
* - else, compares the literal values and range dependencies to the previous formula, and for each parameter:
|
|
49869
49886
|
* - for numbers: returns a relative change (+N or -N) if possible, else the full number or "=" if unchanged
|
|
49870
49887
|
* - for strings: returns the full string if changed, else "="
|
|
@@ -49872,6 +49889,10 @@ var Squisher = class {
|
|
|
49872
49889
|
* */
|
|
49873
49890
|
squish(cell, forSheetId) {
|
|
49874
49891
|
if (cell.isFormula) {
|
|
49892
|
+
if (NonSquishableFunctionRegistry.getAll().some((functionName) => cell.compiledFormula.usesSymbol(functionName))) {
|
|
49893
|
+
this.resetBaseFormula();
|
|
49894
|
+
return cell.compiledFormula.toFormulaString(this.getters, this.rangeToStringOptions);
|
|
49895
|
+
}
|
|
49875
49896
|
let numbers = [];
|
|
49876
49897
|
let strings = [];
|
|
49877
49898
|
let references = [];
|
|
@@ -61237,7 +61258,7 @@ var Session = class extends EventBus {
|
|
|
61237
61258
|
}
|
|
61238
61259
|
message = {
|
|
61239
61260
|
...message,
|
|
61240
|
-
commands:
|
|
61261
|
+
commands: revision.commands
|
|
61241
61262
|
};
|
|
61242
61263
|
}
|
|
61243
61264
|
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.
|
|
@@ -77391,7 +77412,7 @@ const ARRAYTOTEXT = {
|
|
|
77391
77412
|
else if (_format === 0) {
|
|
77392
77413
|
const rowSeparator = this.locale.decimalSeparator === "," ? "/" : ",";
|
|
77393
77414
|
return transposeMatrix(_array).flatMap((row) => row.map((value) => {
|
|
77394
|
-
return isEvaluationError(value.value) ? value.value :
|
|
77415
|
+
return isEvaluationError(value.value) ? value.value : toLocaleString(value, this.locale);
|
|
77395
77416
|
})).join(rowSeparator);
|
|
77396
77417
|
} else return new EvaluationError(_t("Format must be 0 or 1"));
|
|
77397
77418
|
},
|
|
@@ -83152,7 +83173,7 @@ const CONCAT = {
|
|
|
83152
83173
|
description: _t("Concatenation of two values."),
|
|
83153
83174
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
83154
83175
|
compute: function(value1, value2) {
|
|
83155
|
-
return
|
|
83176
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
83156
83177
|
},
|
|
83157
83178
|
isExported: true
|
|
83158
83179
|
};
|
|
@@ -84017,7 +84038,7 @@ const CLEAN = {
|
|
|
84017
84038
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
84018
84039
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
84019
84040
|
compute: function(text) {
|
|
84020
|
-
const _text =
|
|
84041
|
+
const _text = toLocaleString(text, this.locale);
|
|
84021
84042
|
let cleanedStr = "";
|
|
84022
84043
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
84023
84044
|
return cleanedStr;
|
|
@@ -84028,7 +84049,7 @@ const CONCATENATE = {
|
|
|
84028
84049
|
description: _t("Appends strings to one another."),
|
|
84029
84050
|
args: [arg("string (string, range<string>, repeating)", _t("String to append in sequence."))],
|
|
84030
84051
|
compute: function(...datas) {
|
|
84031
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
84052
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
84032
84053
|
},
|
|
84033
84054
|
isExported: true
|
|
84034
84055
|
};
|
|
@@ -84036,7 +84057,7 @@ const EXACT = {
|
|
|
84036
84057
|
description: _t("Tests whether two strings are identical."),
|
|
84037
84058
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
84038
84059
|
compute: function(string1, string2) {
|
|
84039
|
-
return
|
|
84060
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
84040
84061
|
},
|
|
84041
84062
|
isExported: true
|
|
84042
84063
|
};
|
|
@@ -84048,8 +84069,8 @@ const FIND = {
|
|
|
84048
84069
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
84049
84070
|
],
|
|
84050
84071
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
84051
|
-
const _searchFor =
|
|
84052
|
-
const _textToSearch =
|
|
84072
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
84073
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
84053
84074
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
84054
84075
|
if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
|
|
84055
84076
|
if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
|
|
@@ -84086,8 +84107,8 @@ const JOIN = {
|
|
|
84086
84107
|
description: _t("Concatenates elements of arrays with delimiter."),
|
|
84087
84108
|
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."))],
|
|
84088
84109
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
84089
|
-
const _delimiter =
|
|
84090
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
84110
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
84111
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
84091
84112
|
}
|
|
84092
84113
|
};
|
|
84093
84114
|
const LEFT = {
|
|
@@ -84096,7 +84117,7 @@ const LEFT = {
|
|
|
84096
84117
|
compute: function(text, ...args) {
|
|
84097
84118
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
84098
84119
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
84099
|
-
return
|
|
84120
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
84100
84121
|
},
|
|
84101
84122
|
isExported: true
|
|
84102
84123
|
};
|
|
@@ -84104,7 +84125,7 @@ const LEN = {
|
|
|
84104
84125
|
description: _t("Length of a string."),
|
|
84105
84126
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
84106
84127
|
compute: function(text) {
|
|
84107
|
-
return
|
|
84128
|
+
return toLocaleString(text, this.locale).length;
|
|
84108
84129
|
},
|
|
84109
84130
|
isExported: true
|
|
84110
84131
|
};
|
|
@@ -84112,7 +84133,7 @@ const LOWER = {
|
|
|
84112
84133
|
description: _t("Converts a specified string to lowercase."),
|
|
84113
84134
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
84114
84135
|
compute: function(text) {
|
|
84115
|
-
return
|
|
84136
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
84116
84137
|
},
|
|
84117
84138
|
isExported: true
|
|
84118
84139
|
};
|
|
@@ -84124,7 +84145,7 @@ const MID = {
|
|
|
84124
84145
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
84125
84146
|
],
|
|
84126
84147
|
compute: function(text, starting_at, extract_length) {
|
|
84127
|
-
const _text =
|
|
84148
|
+
const _text = toLocaleString(text, this.locale);
|
|
84128
84149
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
84129
84150
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
84130
84151
|
if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -84137,7 +84158,7 @@ const PROPER = {
|
|
|
84137
84158
|
description: _t("Capitalizes each word in a specified string."),
|
|
84138
84159
|
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."))],
|
|
84139
84160
|
compute: function(text) {
|
|
84140
|
-
return
|
|
84161
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
84141
84162
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
84142
84163
|
});
|
|
84143
84164
|
},
|
|
@@ -84285,9 +84306,9 @@ const REPLACE = {
|
|
|
84285
84306
|
compute: function(text, position, length, newText) {
|
|
84286
84307
|
const _position = toNumber(position, this.locale);
|
|
84287
84308
|
if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
|
|
84288
|
-
const _text =
|
|
84309
|
+
const _text = toLocaleString(text, this.locale);
|
|
84289
84310
|
const _length = toNumber(length, this.locale);
|
|
84290
|
-
const _newText =
|
|
84311
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
84291
84312
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
84292
84313
|
},
|
|
84293
84314
|
isExported: true
|
|
@@ -84298,7 +84319,7 @@ const RIGHT = {
|
|
|
84298
84319
|
compute: function(text, ...args) {
|
|
84299
84320
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
84300
84321
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
84301
|
-
const _text =
|
|
84322
|
+
const _text = toLocaleString(text, this.locale);
|
|
84302
84323
|
const stringLength = _text.length;
|
|
84303
84324
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
84304
84325
|
},
|
|
@@ -84312,8 +84333,8 @@ const SEARCH = {
|
|
|
84312
84333
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
84313
84334
|
],
|
|
84314
84335
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
84315
|
-
const _searchFor =
|
|
84316
|
-
const _textToSearch =
|
|
84336
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
84337
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
84317
84338
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
84318
84339
|
if (_textToSearch === "") return {
|
|
84319
84340
|
value: CellErrorType.GenericError,
|
|
@@ -84343,8 +84364,8 @@ const SPLIT = {
|
|
|
84343
84364
|
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."))
|
|
84344
84365
|
],
|
|
84345
84366
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
84346
|
-
const _text =
|
|
84347
|
-
const _delimiter = escapeRegExp(
|
|
84367
|
+
const _text = toLocaleString(text, this.locale);
|
|
84368
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
84348
84369
|
const _splitByEach = toBoolean(splitByEach);
|
|
84349
84370
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
84350
84371
|
if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -84366,10 +84387,10 @@ const SUBSTITUTE = {
|
|
|
84366
84387
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
84367
84388
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
84368
84389
|
if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
|
|
84369
|
-
const _textToSearch =
|
|
84370
|
-
const _searchFor =
|
|
84390
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
84391
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
84371
84392
|
if (_searchFor === "") return _textToSearch;
|
|
84372
|
-
const _replaceWith =
|
|
84393
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
84373
84394
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
84374
84395
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
84375
84396
|
let n = 0;
|
|
@@ -84392,10 +84413,10 @@ const TEXTJOIN = {
|
|
|
84392
84413
|
arg("texts (string, range<string>, repeating)", _t("Text item to join."))
|
|
84393
84414
|
],
|
|
84394
84415
|
compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
|
|
84395
|
-
const _delimiter =
|
|
84416
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
84396
84417
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
84397
84418
|
let n = 0;
|
|
84398
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
84419
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
84399
84420
|
},
|
|
84400
84421
|
isExported: true
|
|
84401
84422
|
};
|
|
@@ -84448,7 +84469,7 @@ const TRIM = {
|
|
|
84448
84469
|
description: _t("Removes space characters."),
|
|
84449
84470
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
84450
84471
|
compute: function(text) {
|
|
84451
|
-
return trimContent(
|
|
84472
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
84452
84473
|
},
|
|
84453
84474
|
isExported: true
|
|
84454
84475
|
};
|
|
@@ -84456,7 +84477,7 @@ const UPPER = {
|
|
|
84456
84477
|
description: _t("Converts a specified string to uppercase."),
|
|
84457
84478
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
84458
84479
|
compute: function(text) {
|
|
84459
|
-
return
|
|
84480
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
84460
84481
|
},
|
|
84461
84482
|
isExported: true
|
|
84462
84483
|
};
|
|
@@ -84553,7 +84574,7 @@ const HYPERLINK = {
|
|
|
84553
84574
|
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."))],
|
|
84554
84575
|
compute: function(url, linkLabel) {
|
|
84555
84576
|
const processedUrl = toString(url).trim();
|
|
84556
|
-
const processedLabel =
|
|
84577
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
84557
84578
|
if (processedUrl === "") return processedLabel;
|
|
84558
84579
|
return markdownLink(processedLabel, processedUrl);
|
|
84559
84580
|
},
|
|
@@ -84696,7 +84717,8 @@ const registries = {
|
|
|
84696
84717
|
supportedPivotPositionalFormulaRegistry,
|
|
84697
84718
|
pivotToFunctionValueRegistry,
|
|
84698
84719
|
migrationStepRegistry,
|
|
84699
|
-
chartJsExtensionRegistry
|
|
84720
|
+
chartJsExtensionRegistry,
|
|
84721
|
+
NonSquishableFunctionRegistry
|
|
84700
84722
|
};
|
|
84701
84723
|
const helpers = {
|
|
84702
84724
|
arg,
|
|
@@ -84949,6 +84971,6 @@ exports.stores = stores;
|
|
|
84949
84971
|
exports.tokenColors = tokenColors;
|
|
84950
84972
|
exports.tokenize = tokenize;
|
|
84951
84973
|
|
|
84952
|
-
__info__.version = "19.3.
|
|
84953
|
-
__info__.date = "2026-08-
|
|
84954
|
-
__info__.hash = "
|
|
84974
|
+
__info__.version = "19.3.17";
|
|
84975
|
+
__info__.date = "2026-08-21T15:31:50.940Z";
|
|
84976
|
+
__info__.hash = "cf8c614";
|
package/dist/o_spreadsheet.css
CHANGED
|
@@ -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.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.17
|
|
6
|
+
* @date 2026-08-21T15:31:52.347Z
|
|
7
|
+
* @hash cf8c614
|
|
8
8
|
*/
|
|
9
9
|
:root {
|
|
10
10
|
--os-gray-100: light-dark(#f9fafb, #1b1d26);
|
|
@@ -300,6 +300,7 @@
|
|
|
300
300
|
.os-input {
|
|
301
301
|
border-width: 0 0 1px 0;
|
|
302
302
|
border-color: transparent;
|
|
303
|
+
border-style: solid;
|
|
303
304
|
outline: none;
|
|
304
305
|
text-overflow: ellipsis;
|
|
305
306
|
color: var(--os-text-body);
|
|
@@ -630,6 +631,7 @@
|
|
|
630
631
|
width: 100%;
|
|
631
632
|
outline: none;
|
|
632
633
|
border-color: var(--os-border-color);
|
|
634
|
+
border-style: solid;
|
|
633
635
|
color: var(--os-gray-900);
|
|
634
636
|
|
|
635
637
|
&::placeholder {
|
|
@@ -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.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.17
|
|
6
|
+
* @date 2026-08-21T15:31:50.940Z
|
|
7
|
+
* @hash cf8c614
|
|
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, "");
|
|
@@ -4743,6 +4755,9 @@ var FunctionRegistry = class extends Registry {
|
|
|
4743
4755
|
}
|
|
4744
4756
|
};
|
|
4745
4757
|
const functionRegistry = new FunctionRegistry();
|
|
4758
|
+
/** Formulas using one of these functions are never squished: they are always exported
|
|
4759
|
+
* as a full formula string, and they don't become the base formula of the next cells. */
|
|
4760
|
+
const NonSquishableFunctionRegistry = new Registry();
|
|
4746
4761
|
|
|
4747
4762
|
//#endregion
|
|
4748
4763
|
//#region src/types/locale.ts
|
|
@@ -29084,12 +29099,13 @@ var FilterMenu = class extends Component {
|
|
|
29084
29099
|
}
|
|
29085
29100
|
sortFilterZone(sortDirection) {
|
|
29086
29101
|
const filterPosition = this.props.filterPosition;
|
|
29087
|
-
const
|
|
29102
|
+
const table = this.table;
|
|
29103
|
+
const tableZone = table?.range.zone;
|
|
29088
29104
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
29089
29105
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
29090
29106
|
const contentZone = {
|
|
29091
29107
|
...tableZone,
|
|
29092
|
-
top: tableZone.top +
|
|
29108
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
29093
29109
|
};
|
|
29094
29110
|
const sortAnchor = {
|
|
29095
29111
|
col: filterPosition.col,
|
|
@@ -49863,7 +49879,8 @@ var Squisher = class {
|
|
|
49863
49879
|
* The result of this method is:
|
|
49864
49880
|
* - if the cell is not a formula, returns the content as is and resets the base formula
|
|
49865
49881
|
* - if the cell is a formula:
|
|
49866
|
-
* - if there is no previous formula, or the normalized formula is different from the previous one
|
|
49882
|
+
* - if there is no previous formula, or the normalized formula is different from the previous one or it contains blacklisted functions (see NonSquishableFunctionRegistry),
|
|
49883
|
+
* resets the base formula to this one and returns the full formula string
|
|
49867
49884
|
* - else, compares the literal values and range dependencies to the previous formula, and for each parameter:
|
|
49868
49885
|
* - for numbers: returns a relative change (+N or -N) if possible, else the full number or "=" if unchanged
|
|
49869
49886
|
* - for strings: returns the full string if changed, else "="
|
|
@@ -49871,6 +49888,10 @@ var Squisher = class {
|
|
|
49871
49888
|
* */
|
|
49872
49889
|
squish(cell, forSheetId) {
|
|
49873
49890
|
if (cell.isFormula) {
|
|
49891
|
+
if (NonSquishableFunctionRegistry.getAll().some((functionName) => cell.compiledFormula.usesSymbol(functionName))) {
|
|
49892
|
+
this.resetBaseFormula();
|
|
49893
|
+
return cell.compiledFormula.toFormulaString(this.getters, this.rangeToStringOptions);
|
|
49894
|
+
}
|
|
49874
49895
|
let numbers = [];
|
|
49875
49896
|
let strings = [];
|
|
49876
49897
|
let references = [];
|
|
@@ -61052,7 +61073,7 @@ var Session = class extends EventBus {
|
|
|
61052
61073
|
}
|
|
61053
61074
|
message = {
|
|
61054
61075
|
...message,
|
|
61055
|
-
commands:
|
|
61076
|
+
commands: revision.commands
|
|
61056
61077
|
};
|
|
61057
61078
|
}
|
|
61058
61079
|
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.
|
|
@@ -77206,7 +77227,7 @@ const ARRAYTOTEXT = {
|
|
|
77206
77227
|
else if (_format === 0) {
|
|
77207
77228
|
const rowSeparator = this.locale.decimalSeparator === "," ? "/" : ",";
|
|
77208
77229
|
return transposeMatrix(_array).flatMap((row) => row.map((value) => {
|
|
77209
|
-
return isEvaluationError(value.value) ? value.value :
|
|
77230
|
+
return isEvaluationError(value.value) ? value.value : toLocaleString(value, this.locale);
|
|
77210
77231
|
})).join(rowSeparator);
|
|
77211
77232
|
} else return new EvaluationError(_t("Format must be 0 or 1"));
|
|
77212
77233
|
},
|
|
@@ -82967,7 +82988,7 @@ const CONCAT = {
|
|
|
82967
82988
|
description: _t("Concatenation of two values."),
|
|
82968
82989
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
82969
82990
|
compute: function(value1, value2) {
|
|
82970
|
-
return
|
|
82991
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
82971
82992
|
},
|
|
82972
82993
|
isExported: true
|
|
82973
82994
|
};
|
|
@@ -83832,7 +83853,7 @@ const CLEAN = {
|
|
|
83832
83853
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
83833
83854
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
83834
83855
|
compute: function(text) {
|
|
83835
|
-
const _text =
|
|
83856
|
+
const _text = toLocaleString(text, this.locale);
|
|
83836
83857
|
let cleanedStr = "";
|
|
83837
83858
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
83838
83859
|
return cleanedStr;
|
|
@@ -83843,7 +83864,7 @@ const CONCATENATE = {
|
|
|
83843
83864
|
description: _t("Appends strings to one another."),
|
|
83844
83865
|
args: [arg("string (string, range<string>, repeating)", _t("String to append in sequence."))],
|
|
83845
83866
|
compute: function(...datas) {
|
|
83846
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
83867
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
83847
83868
|
},
|
|
83848
83869
|
isExported: true
|
|
83849
83870
|
};
|
|
@@ -83851,7 +83872,7 @@ const EXACT = {
|
|
|
83851
83872
|
description: _t("Tests whether two strings are identical."),
|
|
83852
83873
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
83853
83874
|
compute: function(string1, string2) {
|
|
83854
|
-
return
|
|
83875
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
83855
83876
|
},
|
|
83856
83877
|
isExported: true
|
|
83857
83878
|
};
|
|
@@ -83863,8 +83884,8 @@ const FIND = {
|
|
|
83863
83884
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
83864
83885
|
],
|
|
83865
83886
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
83866
|
-
const _searchFor =
|
|
83867
|
-
const _textToSearch =
|
|
83887
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
83888
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
83868
83889
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
83869
83890
|
if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
|
|
83870
83891
|
if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
|
|
@@ -83901,8 +83922,8 @@ const JOIN = {
|
|
|
83901
83922
|
description: _t("Concatenates elements of arrays with delimiter."),
|
|
83902
83923
|
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."))],
|
|
83903
83924
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
83904
|
-
const _delimiter =
|
|
83905
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
83925
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
83926
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
83906
83927
|
}
|
|
83907
83928
|
};
|
|
83908
83929
|
const LEFT = {
|
|
@@ -83911,7 +83932,7 @@ const LEFT = {
|
|
|
83911
83932
|
compute: function(text, ...args) {
|
|
83912
83933
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
83913
83934
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
83914
|
-
return
|
|
83935
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
83915
83936
|
},
|
|
83916
83937
|
isExported: true
|
|
83917
83938
|
};
|
|
@@ -83919,7 +83940,7 @@ const LEN = {
|
|
|
83919
83940
|
description: _t("Length of a string."),
|
|
83920
83941
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
83921
83942
|
compute: function(text) {
|
|
83922
|
-
return
|
|
83943
|
+
return toLocaleString(text, this.locale).length;
|
|
83923
83944
|
},
|
|
83924
83945
|
isExported: true
|
|
83925
83946
|
};
|
|
@@ -83927,7 +83948,7 @@ const LOWER = {
|
|
|
83927
83948
|
description: _t("Converts a specified string to lowercase."),
|
|
83928
83949
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
83929
83950
|
compute: function(text) {
|
|
83930
|
-
return
|
|
83951
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
83931
83952
|
},
|
|
83932
83953
|
isExported: true
|
|
83933
83954
|
};
|
|
@@ -83939,7 +83960,7 @@ const MID = {
|
|
|
83939
83960
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
83940
83961
|
],
|
|
83941
83962
|
compute: function(text, starting_at, extract_length) {
|
|
83942
|
-
const _text =
|
|
83963
|
+
const _text = toLocaleString(text, this.locale);
|
|
83943
83964
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
83944
83965
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
83945
83966
|
if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -83952,7 +83973,7 @@ const PROPER = {
|
|
|
83952
83973
|
description: _t("Capitalizes each word in a specified string."),
|
|
83953
83974
|
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."))],
|
|
83954
83975
|
compute: function(text) {
|
|
83955
|
-
return
|
|
83976
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
83956
83977
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
83957
83978
|
});
|
|
83958
83979
|
},
|
|
@@ -84100,9 +84121,9 @@ const REPLACE = {
|
|
|
84100
84121
|
compute: function(text, position, length, newText) {
|
|
84101
84122
|
const _position = toNumber(position, this.locale);
|
|
84102
84123
|
if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
|
|
84103
|
-
const _text =
|
|
84124
|
+
const _text = toLocaleString(text, this.locale);
|
|
84104
84125
|
const _length = toNumber(length, this.locale);
|
|
84105
|
-
const _newText =
|
|
84126
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
84106
84127
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
84107
84128
|
},
|
|
84108
84129
|
isExported: true
|
|
@@ -84113,7 +84134,7 @@ const RIGHT = {
|
|
|
84113
84134
|
compute: function(text, ...args) {
|
|
84114
84135
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
84115
84136
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
84116
|
-
const _text =
|
|
84137
|
+
const _text = toLocaleString(text, this.locale);
|
|
84117
84138
|
const stringLength = _text.length;
|
|
84118
84139
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
84119
84140
|
},
|
|
@@ -84127,8 +84148,8 @@ const SEARCH = {
|
|
|
84127
84148
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
84128
84149
|
],
|
|
84129
84150
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
84130
|
-
const _searchFor =
|
|
84131
|
-
const _textToSearch =
|
|
84151
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
84152
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
84132
84153
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
84133
84154
|
if (_textToSearch === "") return {
|
|
84134
84155
|
value: CellErrorType.GenericError,
|
|
@@ -84158,8 +84179,8 @@ const SPLIT = {
|
|
|
84158
84179
|
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."))
|
|
84159
84180
|
],
|
|
84160
84181
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
84161
|
-
const _text =
|
|
84162
|
-
const _delimiter = escapeRegExp(
|
|
84182
|
+
const _text = toLocaleString(text, this.locale);
|
|
84183
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
84163
84184
|
const _splitByEach = toBoolean(splitByEach);
|
|
84164
84185
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
84165
84186
|
if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -84181,10 +84202,10 @@ const SUBSTITUTE = {
|
|
|
84181
84202
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
84182
84203
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
84183
84204
|
if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
|
|
84184
|
-
const _textToSearch =
|
|
84185
|
-
const _searchFor =
|
|
84205
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
84206
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
84186
84207
|
if (_searchFor === "") return _textToSearch;
|
|
84187
|
-
const _replaceWith =
|
|
84208
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
84188
84209
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
84189
84210
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
84190
84211
|
let n = 0;
|
|
@@ -84207,10 +84228,10 @@ const TEXTJOIN = {
|
|
|
84207
84228
|
arg("texts (string, range<string>, repeating)", _t("Text item to join."))
|
|
84208
84229
|
],
|
|
84209
84230
|
compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
|
|
84210
|
-
const _delimiter =
|
|
84231
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
84211
84232
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
84212
84233
|
let n = 0;
|
|
84213
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
84234
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
84214
84235
|
},
|
|
84215
84236
|
isExported: true
|
|
84216
84237
|
};
|
|
@@ -84263,7 +84284,7 @@ const TRIM = {
|
|
|
84263
84284
|
description: _t("Removes space characters."),
|
|
84264
84285
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
84265
84286
|
compute: function(text) {
|
|
84266
|
-
return trimContent(
|
|
84287
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
84267
84288
|
},
|
|
84268
84289
|
isExported: true
|
|
84269
84290
|
};
|
|
@@ -84271,7 +84292,7 @@ const UPPER = {
|
|
|
84271
84292
|
description: _t("Converts a specified string to uppercase."),
|
|
84272
84293
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
84273
84294
|
compute: function(text) {
|
|
84274
|
-
return
|
|
84295
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
84275
84296
|
},
|
|
84276
84297
|
isExported: true
|
|
84277
84298
|
};
|
|
@@ -84368,7 +84389,7 @@ const HYPERLINK = {
|
|
|
84368
84389
|
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."))],
|
|
84369
84390
|
compute: function(url, linkLabel) {
|
|
84370
84391
|
const processedUrl = toString(url).trim();
|
|
84371
|
-
const processedLabel =
|
|
84392
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
84372
84393
|
if (processedUrl === "") return processedLabel;
|
|
84373
84394
|
return markdownLink(processedLabel, processedUrl);
|
|
84374
84395
|
},
|
|
@@ -84511,7 +84532,8 @@ const registries = {
|
|
|
84511
84532
|
supportedPivotPositionalFormulaRegistry,
|
|
84512
84533
|
pivotToFunctionValueRegistry,
|
|
84513
84534
|
migrationStepRegistry,
|
|
84514
|
-
chartJsExtensionRegistry
|
|
84535
|
+
chartJsExtensionRegistry,
|
|
84536
|
+
NonSquishableFunctionRegistry
|
|
84515
84537
|
};
|
|
84516
84538
|
const helpers = {
|
|
84517
84539
|
arg,
|
|
@@ -84706,6 +84728,6 @@ const chartHelpers = {
|
|
|
84706
84728
|
//#endregion
|
|
84707
84729
|
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 };
|
|
84708
84730
|
|
|
84709
|
-
__info__.version = "19.3.
|
|
84710
|
-
__info__.date = "2026-08-
|
|
84711
|
-
__info__.hash = "
|
|
84731
|
+
__info__.version = "19.3.17";
|
|
84732
|
+
__info__.date = "2026-08-21T15:31:50.940Z";
|
|
84733
|
+
__info__.hash = "cf8c614";
|