@odoo/o-spreadsheet 16.0.70 → 16.0.72

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.
@@ -2128,7 +2128,7 @@ function convertInternalFormatToFormat(internalFormat) {
2128
2128
  * formula, commas are used to separate arguments
2129
2129
  * - it does not support % symbol, in formulas % is an operator
2130
2130
  */
2131
- const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
2131
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e(\+|-)?\d+)?)?|^-?\.\d+)(?!\w|!)/;
2132
2132
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
2133
2133
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
2134
2134
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3938,19 +3938,26 @@ class FilterMenu extends owl.Component {
3938
3938
  .filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
3939
3939
  .map(({ col, row }) => { var _a; return (_a = this.env.model.getters.getCell(sheetId, col, row)) === null || _a === void 0 ? void 0 : _a.formattedValue; });
3940
3940
  const filterValues = this.env.model.getters.getFilterValues(sheetId, position.col, position.row);
3941
- const strValues = [...cellValues, ...filterValues];
3942
- const normalizedFilteredValues = filterValues.map(toLowerCase);
3943
- // Set with lowercase values to avoid duplicates
3944
- const normalizedValues = [...new Set(strValues.map(toLowerCase))];
3945
- const sortedValues = normalizedValues.sort((val1, val2) => val1.localeCompare(val2, undefined, { numeric: true, sensitivity: "base" }));
3946
- return sortedValues.map((normalizedValue) => {
3947
- const checked = normalizedFilteredValues.findIndex((filteredValue) => filteredValue === normalizedValue) ===
3948
- -1;
3949
- return {
3950
- checked,
3951
- string: strValues.find((val) => toLowerCase(val) === normalizedValue) || "",
3952
- };
3953
- });
3941
+ const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
3942
+ const set = new Set();
3943
+ const values = [];
3944
+ const addValue = (value) => {
3945
+ const normalizedValue = toLowerCase(value);
3946
+ if (!set.has(normalizedValue)) {
3947
+ values.push({
3948
+ string: value || "",
3949
+ checked: !normalizedFilteredValues.has(normalizedValue),
3950
+ normalizedValue,
3951
+ });
3952
+ set.add(normalizedValue);
3953
+ }
3954
+ };
3955
+ cellValues.forEach(addValue);
3956
+ filterValues.forEach(addValue);
3957
+ return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
3958
+ numeric: true,
3959
+ sensitivity: "base",
3960
+ }));
3954
3961
  }
3955
3962
  checkValue(value) {
3956
3963
  var _a;
@@ -17686,6 +17693,9 @@ function isEmpty(value) {
17686
17693
  return value === null || value === undefined;
17687
17694
  }
17688
17695
  const getNeutral = { number: 0, string: "", boolean: false };
17696
+ function areAlmostEqual(value1, value2, epsilon = 2e-16) {
17697
+ return Math.abs(value1 - value2) < epsilon;
17698
+ }
17689
17699
  const EQ = {
17690
17700
  description: _lt(`Equal.`),
17691
17701
  args: args(`
@@ -17702,6 +17712,9 @@ const EQ = {
17702
17712
  if (typeof value2 === "string") {
17703
17713
  value2 = value2.toUpperCase();
17704
17714
  }
17715
+ if (typeof value1 === "number" && typeof value2 === "number") {
17716
+ return areAlmostEqual(value1, value2);
17717
+ }
17705
17718
  return value1 === value2;
17706
17719
  },
17707
17720
  };
@@ -17736,6 +17749,9 @@ const GT = {
17736
17749
  returns: ["BOOLEAN"],
17737
17750
  compute: function (value1, value2) {
17738
17751
  return applyRelationalOperator(value1, value2, (v1, v2) => {
17752
+ if (typeof v1 === "number" && typeof v2 === "number") {
17753
+ return !areAlmostEqual(v1, v2) && v1 > v2;
17754
+ }
17739
17755
  return v1 > v2;
17740
17756
  });
17741
17757
  },
@@ -17752,6 +17768,9 @@ const GTE = {
17752
17768
  returns: ["BOOLEAN"],
17753
17769
  compute: function (value1, value2) {
17754
17770
  return applyRelationalOperator(value1, value2, (v1, v2) => {
17771
+ if (typeof v1 === "number" && typeof v2 === "number") {
17772
+ return areAlmostEqual(v1, v2) || v1 > v2;
17773
+ }
17755
17774
  return v1 >= v2;
17756
17775
  });
17757
17776
  },
@@ -26057,7 +26076,7 @@ class XlsxBaseExtractor {
26057
26076
  */
26058
26077
  handleMissingValue(parentElement, missingElementName, optionalArgs) {
26059
26078
  if (optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.required) {
26060
- if (optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.default) {
26079
+ if ((optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.default) !== undefined) {
26061
26080
  this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
26062
26081
  }
26063
26082
  else {
@@ -34022,9 +34041,10 @@ class FilterEvaluationPlugin extends UIPlugin {
34022
34041
  const filteredValues = (_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[filter.id]) === null || _b === void 0 ? void 0 : _b.map(toLowerCase);
34023
34042
  if (!filteredValues || !filter.filteredZone)
34024
34043
  continue;
34044
+ const filteredValuesSet = new Set(filteredValues);
34025
34045
  for (let row = filter.filteredZone.top; row <= filter.filteredZone.bottom; row++) {
34026
34046
  const value = this.getCellValueAsString(sheetId, filter.col, row);
34027
- if (filteredValues.includes(value)) {
34047
+ if (filteredValuesSet.has(value)) {
34028
34048
  hiddenRows.add(row);
34029
34049
  }
34030
34050
  }
@@ -43846,6 +43866,6 @@ exports.setTranslationMethod = setTranslationMethod;
43846
43866
  exports.tokenize = tokenize;
43847
43867
 
43848
43868
 
43849
- __info__.version = '16.0.70';
43850
- __info__.date = '2025-05-12T05:19:22.493Z';
43851
- __info__.hash = 'bbdc034';
43869
+ __info__.version = '16.0.72';
43870
+ __info__.date = '2025-06-12T10:45:09.183Z';
43871
+ __info__.hash = 'fb0036b';
@@ -2124,7 +2124,7 @@ function convertInternalFormatToFormat(internalFormat) {
2124
2124
  * formula, commas are used to separate arguments
2125
2125
  * - it does not support % symbol, in formulas % is an operator
2126
2126
  */
2127
- const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
2127
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e(\+|-)?\d+)?)?|^-?\.\d+)(?!\w|!)/;
2128
2128
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
2129
2129
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
2130
2130
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3934,19 +3934,26 @@ class FilterMenu extends Component {
3934
3934
  .filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
3935
3935
  .map(({ col, row }) => { var _a; return (_a = this.env.model.getters.getCell(sheetId, col, row)) === null || _a === void 0 ? void 0 : _a.formattedValue; });
3936
3936
  const filterValues = this.env.model.getters.getFilterValues(sheetId, position.col, position.row);
3937
- const strValues = [...cellValues, ...filterValues];
3938
- const normalizedFilteredValues = filterValues.map(toLowerCase);
3939
- // Set with lowercase values to avoid duplicates
3940
- const normalizedValues = [...new Set(strValues.map(toLowerCase))];
3941
- const sortedValues = normalizedValues.sort((val1, val2) => val1.localeCompare(val2, undefined, { numeric: true, sensitivity: "base" }));
3942
- return sortedValues.map((normalizedValue) => {
3943
- const checked = normalizedFilteredValues.findIndex((filteredValue) => filteredValue === normalizedValue) ===
3944
- -1;
3945
- return {
3946
- checked,
3947
- string: strValues.find((val) => toLowerCase(val) === normalizedValue) || "",
3948
- };
3949
- });
3937
+ const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
3938
+ const set = new Set();
3939
+ const values = [];
3940
+ const addValue = (value) => {
3941
+ const normalizedValue = toLowerCase(value);
3942
+ if (!set.has(normalizedValue)) {
3943
+ values.push({
3944
+ string: value || "",
3945
+ checked: !normalizedFilteredValues.has(normalizedValue),
3946
+ normalizedValue,
3947
+ });
3948
+ set.add(normalizedValue);
3949
+ }
3950
+ };
3951
+ cellValues.forEach(addValue);
3952
+ filterValues.forEach(addValue);
3953
+ return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
3954
+ numeric: true,
3955
+ sensitivity: "base",
3956
+ }));
3950
3957
  }
3951
3958
  checkValue(value) {
3952
3959
  var _a;
@@ -17682,6 +17689,9 @@ function isEmpty(value) {
17682
17689
  return value === null || value === undefined;
17683
17690
  }
17684
17691
  const getNeutral = { number: 0, string: "", boolean: false };
17692
+ function areAlmostEqual(value1, value2, epsilon = 2e-16) {
17693
+ return Math.abs(value1 - value2) < epsilon;
17694
+ }
17685
17695
  const EQ = {
17686
17696
  description: _lt(`Equal.`),
17687
17697
  args: args(`
@@ -17698,6 +17708,9 @@ const EQ = {
17698
17708
  if (typeof value2 === "string") {
17699
17709
  value2 = value2.toUpperCase();
17700
17710
  }
17711
+ if (typeof value1 === "number" && typeof value2 === "number") {
17712
+ return areAlmostEqual(value1, value2);
17713
+ }
17701
17714
  return value1 === value2;
17702
17715
  },
17703
17716
  };
@@ -17732,6 +17745,9 @@ const GT = {
17732
17745
  returns: ["BOOLEAN"],
17733
17746
  compute: function (value1, value2) {
17734
17747
  return applyRelationalOperator(value1, value2, (v1, v2) => {
17748
+ if (typeof v1 === "number" && typeof v2 === "number") {
17749
+ return !areAlmostEqual(v1, v2) && v1 > v2;
17750
+ }
17735
17751
  return v1 > v2;
17736
17752
  });
17737
17753
  },
@@ -17748,6 +17764,9 @@ const GTE = {
17748
17764
  returns: ["BOOLEAN"],
17749
17765
  compute: function (value1, value2) {
17750
17766
  return applyRelationalOperator(value1, value2, (v1, v2) => {
17767
+ if (typeof v1 === "number" && typeof v2 === "number") {
17768
+ return areAlmostEqual(v1, v2) || v1 > v2;
17769
+ }
17751
17770
  return v1 >= v2;
17752
17771
  });
17753
17772
  },
@@ -26053,7 +26072,7 @@ class XlsxBaseExtractor {
26053
26072
  */
26054
26073
  handleMissingValue(parentElement, missingElementName, optionalArgs) {
26055
26074
  if (optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.required) {
26056
- if (optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.default) {
26075
+ if ((optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.default) !== undefined) {
26057
26076
  this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
26058
26077
  }
26059
26078
  else {
@@ -34018,9 +34037,10 @@ class FilterEvaluationPlugin extends UIPlugin {
34018
34037
  const filteredValues = (_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[filter.id]) === null || _b === void 0 ? void 0 : _b.map(toLowerCase);
34019
34038
  if (!filteredValues || !filter.filteredZone)
34020
34039
  continue;
34040
+ const filteredValuesSet = new Set(filteredValues);
34021
34041
  for (let row = filter.filteredZone.top; row <= filter.filteredZone.bottom; row++) {
34022
34042
  const value = this.getCellValueAsString(sheetId, filter.col, row);
34023
- if (filteredValues.includes(value)) {
34043
+ if (filteredValuesSet.has(value)) {
34024
34044
  hiddenRows.add(row);
34025
34045
  }
34026
34046
  }
@@ -43814,6 +43834,6 @@ function addFunction(functionName, functionDescription) {
43814
43834
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, cellTypes, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
43815
43835
 
43816
43836
 
43817
- __info__.version = '16.0.70';
43818
- __info__.date = '2025-05-12T05:19:22.493Z';
43819
- __info__.hash = 'bbdc034';
43837
+ __info__.version = '16.0.72';
43838
+ __info__.date = '2025-06-12T10:45:09.183Z';
43839
+ __info__.hash = 'fb0036b';
@@ -2125,7 +2125,7 @@
2125
2125
  * formula, commas are used to separate arguments
2126
2126
  * - it does not support % symbol, in formulas % is an operator
2127
2127
  */
2128
- const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
2128
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e(\+|-)?\d+)?)?|^-?\.\d+)(?!\w|!)/;
2129
2129
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
2130
2130
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
2131
2131
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3935,19 +3935,26 @@
3935
3935
  .filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
3936
3936
  .map(({ col, row }) => { var _a; return (_a = this.env.model.getters.getCell(sheetId, col, row)) === null || _a === void 0 ? void 0 : _a.formattedValue; });
3937
3937
  const filterValues = this.env.model.getters.getFilterValues(sheetId, position.col, position.row);
3938
- const strValues = [...cellValues, ...filterValues];
3939
- const normalizedFilteredValues = filterValues.map(toLowerCase);
3940
- // Set with lowercase values to avoid duplicates
3941
- const normalizedValues = [...new Set(strValues.map(toLowerCase))];
3942
- const sortedValues = normalizedValues.sort((val1, val2) => val1.localeCompare(val2, undefined, { numeric: true, sensitivity: "base" }));
3943
- return sortedValues.map((normalizedValue) => {
3944
- const checked = normalizedFilteredValues.findIndex((filteredValue) => filteredValue === normalizedValue) ===
3945
- -1;
3946
- return {
3947
- checked,
3948
- string: strValues.find((val) => toLowerCase(val) === normalizedValue) || "",
3949
- };
3950
- });
3938
+ const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
3939
+ const set = new Set();
3940
+ const values = [];
3941
+ const addValue = (value) => {
3942
+ const normalizedValue = toLowerCase(value);
3943
+ if (!set.has(normalizedValue)) {
3944
+ values.push({
3945
+ string: value || "",
3946
+ checked: !normalizedFilteredValues.has(normalizedValue),
3947
+ normalizedValue,
3948
+ });
3949
+ set.add(normalizedValue);
3950
+ }
3951
+ };
3952
+ cellValues.forEach(addValue);
3953
+ filterValues.forEach(addValue);
3954
+ return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
3955
+ numeric: true,
3956
+ sensitivity: "base",
3957
+ }));
3951
3958
  }
3952
3959
  checkValue(value) {
3953
3960
  var _a;
@@ -17683,6 +17690,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17683
17690
  return value === null || value === undefined;
17684
17691
  }
17685
17692
  const getNeutral = { number: 0, string: "", boolean: false };
17693
+ function areAlmostEqual(value1, value2, epsilon = 2e-16) {
17694
+ return Math.abs(value1 - value2) < epsilon;
17695
+ }
17686
17696
  const EQ = {
17687
17697
  description: _lt(`Equal.`),
17688
17698
  args: args(`
@@ -17699,6 +17709,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17699
17709
  if (typeof value2 === "string") {
17700
17710
  value2 = value2.toUpperCase();
17701
17711
  }
17712
+ if (typeof value1 === "number" && typeof value2 === "number") {
17713
+ return areAlmostEqual(value1, value2);
17714
+ }
17702
17715
  return value1 === value2;
17703
17716
  },
17704
17717
  };
@@ -17733,6 +17746,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17733
17746
  returns: ["BOOLEAN"],
17734
17747
  compute: function (value1, value2) {
17735
17748
  return applyRelationalOperator(value1, value2, (v1, v2) => {
17749
+ if (typeof v1 === "number" && typeof v2 === "number") {
17750
+ return !areAlmostEqual(v1, v2) && v1 > v2;
17751
+ }
17736
17752
  return v1 > v2;
17737
17753
  });
17738
17754
  },
@@ -17749,6 +17765,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17749
17765
  returns: ["BOOLEAN"],
17750
17766
  compute: function (value1, value2) {
17751
17767
  return applyRelationalOperator(value1, value2, (v1, v2) => {
17768
+ if (typeof v1 === "number" && typeof v2 === "number") {
17769
+ return areAlmostEqual(v1, v2) || v1 > v2;
17770
+ }
17752
17771
  return v1 >= v2;
17753
17772
  });
17754
17773
  },
@@ -26054,7 +26073,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
26054
26073
  */
26055
26074
  handleMissingValue(parentElement, missingElementName, optionalArgs) {
26056
26075
  if (optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.required) {
26057
- if (optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.default) {
26076
+ if ((optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.default) !== undefined) {
26058
26077
  this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
26059
26078
  }
26060
26079
  else {
@@ -34019,9 +34038,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34019
34038
  const filteredValues = (_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[filter.id]) === null || _b === void 0 ? void 0 : _b.map(toLowerCase);
34020
34039
  if (!filteredValues || !filter.filteredZone)
34021
34040
  continue;
34041
+ const filteredValuesSet = new Set(filteredValues);
34022
34042
  for (let row = filter.filteredZone.top; row <= filter.filteredZone.bottom; row++) {
34023
34043
  const value = this.getCellValueAsString(sheetId, filter.col, row);
34024
- if (filteredValues.includes(value)) {
34044
+ if (filteredValuesSet.has(value)) {
34025
34045
  hiddenRows.add(row);
34026
34046
  }
34027
34047
  }
@@ -43845,9 +43865,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43845
43865
  Object.defineProperty(exports, '__esModule', { value: true });
43846
43866
 
43847
43867
 
43848
- __info__.version = '16.0.70';
43849
- __info__.date = '2025-05-12T05:19:22.493Z';
43850
- __info__.hash = 'bbdc034';
43868
+ __info__.version = '16.0.72';
43869
+ __info__.date = '2025-06-12T10:45:09.183Z';
43870
+ __info__.hash = 'fb0036b';
43851
43871
 
43852
43872
 
43853
43873
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);