@odoo/o-spreadsheet 17.1.20 → 17.1.22

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.20
6
- * @date 2024-07-02T09:03:04.534Z
7
- * @hash d15aaf3
5
+ * @version 17.1.22
6
+ * @date 2024-07-08T05:41:57.737Z
7
+ * @hash da27a94
8
8
  */
9
9
 
10
10
  'use strict';
@@ -1704,7 +1704,7 @@ const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSepa
1704
1704
  });
1705
1705
  const getNumberRegex = memoize(function getNumberRegex(locale) {
1706
1706
  const decimalSeparator = escapeRegExp(locale.decimalSeparator);
1707
- const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
1707
+ const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
1708
1708
  const pIntegerAndDecimals = `(\\d+(${thousandsSeparator}\\d{3,})*(${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
1709
1709
  const pOnlyDecimals = `(${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
1710
1710
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -1731,7 +1731,7 @@ function isNumber(value, locale) {
1731
1731
  return getNumberRegex(locale).test(value.trim());
1732
1732
  }
1733
1733
  const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
1734
- return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
1734
+ return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
1735
1735
  });
1736
1736
  /**
1737
1737
  * Convert a string into a number. It assumes that the string actually represents
@@ -7718,19 +7718,22 @@ class TokenizingChars {
7718
7718
  }
7719
7719
 
7720
7720
  function isValidLocale(locale) {
7721
- if (!(locale &&
7722
- typeof locale === "object" &&
7723
- typeof locale.name === "string" &&
7724
- typeof locale.code === "string" &&
7725
- typeof locale.thousandsSeparator === "string" &&
7726
- typeof locale.decimalSeparator === "string" &&
7727
- typeof locale.dateFormat === "string" &&
7728
- typeof locale.timeFormat === "string" &&
7729
- typeof locale.formulaArgSeparator === "string")) {
7721
+ if (!locale ||
7722
+ typeof locale !== "object" ||
7723
+ !(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
7730
7724
  return false;
7731
7725
  }
7732
- if (!Object.values(locale).every((v) => v)) {
7733
- return false;
7726
+ for (const property of [
7727
+ "code",
7728
+ "name",
7729
+ "decimalSeparator",
7730
+ "dateFormat",
7731
+ "timeFormat",
7732
+ "formulaArgSeparator",
7733
+ ]) {
7734
+ if (!locale[property] || typeof locale[property] !== "string") {
7735
+ return false;
7736
+ }
7734
7737
  }
7735
7738
  if (locale.formulaArgSeparator === locale.decimalSeparator) {
7736
7739
  return false;
@@ -7828,7 +7831,10 @@ function canonicalizeNumberLiteral(content, locale) {
7828
7831
  if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
7829
7832
  return content;
7830
7833
  }
7831
- return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
7834
+ if (locale.thousandsSeparator) {
7835
+ content = content.replaceAll(locale.thousandsSeparator, "");
7836
+ }
7837
+ return content.replace(locale.decimalSeparator, ".");
7832
7838
  }
7833
7839
  /**
7834
7840
  * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
@@ -9507,15 +9513,6 @@ function createLineChartRuntime(chart, getters) {
9507
9513
  }
9508
9514
  const colors = new ChartColors();
9509
9515
  for (let [index, { label, data }] of dataSetsValues.entries()) {
9510
- if (["linear", "time"].includes(axisType)) {
9511
- // Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
9512
- data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
9513
- }
9514
- const color = colors.next();
9515
- let backgroundRGBA = colorToRGBA(color);
9516
- if (chart.stacked) {
9517
- backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
9518
- }
9519
9516
  if (chart.cumulative) {
9520
9517
  let accumulator = 0;
9521
9518
  data = data.map((value) => {
@@ -9526,6 +9523,15 @@ function createLineChartRuntime(chart, getters) {
9526
9523
  return value;
9527
9524
  });
9528
9525
  }
9526
+ if (["linear", "time"].includes(axisType)) {
9527
+ // Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
9528
+ data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
9529
+ }
9530
+ const color = colors.next();
9531
+ let backgroundRGBA = colorToRGBA(color);
9532
+ if (chart.stacked) {
9533
+ backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
9534
+ }
9529
9535
  const backgroundColor = rgbaToHex(backgroundRGBA);
9530
9536
  const dataset = {
9531
9537
  label,
@@ -24781,7 +24787,13 @@ class SettingsPanel extends owl.Component {
24781
24787
  }
24782
24788
  async loadLocales() {
24783
24789
  this.loadedLocales = (await this.env.loadLocales())
24784
- .filter(isValidLocale)
24790
+ .filter((locale) => {
24791
+ const isValid = isValidLocale(locale);
24792
+ if (!isValid) {
24793
+ console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
24794
+ }
24795
+ return isValid;
24796
+ })
24785
24797
  .sort((a, b) => a.name.localeCompare(b.name));
24786
24798
  }
24787
24799
  get numberFormatPreview() {
@@ -30537,6 +30549,7 @@ class Grid extends owl.Component {
30537
30549
  return;
30538
30550
  }
30539
30551
  if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
30552
+ ev.preventDefault();
30540
30553
  const content = clipboardData.getData(ClipboardMIMEType.PlainText);
30541
30554
  const target = this.env.model.getters.getSelectedZones();
30542
30555
  const clipboardString = this.env.model.getters.getClipboardTextContent();
@@ -30792,6 +30805,8 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30792
30805
  "BITOR",
30793
30806
  "BITRSHIFT",
30794
30807
  "BITXOR",
30808
+ "BYCOL",
30809
+ "BYROW",
30795
30810
  "CEILING.MATH",
30796
30811
  "CEILING.PRECISE",
30797
30812
  "CHISQ.DIST",
@@ -30799,6 +30814,8 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30799
30814
  "CHISQ.INV",
30800
30815
  "CHISQ.INV.RT",
30801
30816
  "CHISQ.TEST",
30817
+ "CHOOSECOLS",
30818
+ "CHOOSEROWS",
30802
30819
  "COMBINA",
30803
30820
  "CONCAT",
30804
30821
  "CONFIDENCE.NORM",
@@ -30811,14 +30828,17 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30811
30828
  "CSCH",
30812
30829
  "DAYS",
30813
30830
  "DECIMAL",
30831
+ "DROP",
30814
30832
  "ERF.PRECISE",
30815
30833
  "ERFC.PRECISE",
30834
+ "EXPAND",
30816
30835
  "EXPON.DIST",
30817
30836
  "F.DIST",
30818
30837
  "F.DIST.RT",
30819
30838
  "F.INV",
30820
30839
  "F.INV.RT",
30821
30840
  "F.TEST",
30841
+ "FIELDVALUE",
30822
30842
  "FILTERXML",
30823
30843
  "FLOOR.MATH",
30824
30844
  "FLOOR.PRECISE",
@@ -30833,6 +30853,7 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30833
30853
  "GAMMA.INV",
30834
30854
  "GAMMALN.PRECISE",
30835
30855
  "GAUSS",
30856
+ "HSTACK",
30836
30857
  "HYPGEOM.DIST",
30837
30858
  "IFNA",
30838
30859
  "IFS",
@@ -30845,9 +30866,14 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30845
30866
  "IMSINH",
30846
30867
  "IMTAN",
30847
30868
  "ISFORMULA",
30869
+ "ISOMITTED",
30848
30870
  "ISOWEEKNUM",
30871
+ "LAMBDA",
30872
+ "LET",
30849
30873
  "LOGNORM.DIST",
30850
30874
  "LOGNORM.INV",
30875
+ "MAKEARRAY",
30876
+ "MAP",
30851
30877
  "MAXIFS",
30852
30878
  "MINIFS",
30853
30879
  "MODE.MULT",
@@ -30867,17 +30893,26 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30867
30893
  "PERMUTATIONA",
30868
30894
  "PHI",
30869
30895
  "POISSON.DIST",
30896
+ "PQSOURCE",
30897
+ "PYTHON_STR",
30898
+ "PYTHON_TYPE",
30899
+ "PYTHON_TYPENAME",
30870
30900
  "QUARTILE.EXC",
30871
30901
  "QUARTILE.INC",
30872
30902
  "QUERYSTRING",
30903
+ "RANDARRAY",
30873
30904
  "RANK.AVG",
30874
30905
  "RANK.EQ",
30906
+ "REDUCE",
30875
30907
  "RRI",
30908
+ "SCAN",
30876
30909
  "SEC",
30877
30910
  "SECH",
30911
+ "SEQUENCE",
30878
30912
  "SHEET",
30879
30913
  "SHEETS",
30880
30914
  "SKEW.P",
30915
+ "SORTBY",
30881
30916
  "STDEV.P",
30882
30917
  "STDEV.S",
30883
30918
  "SWITCH",
@@ -30887,13 +30922,24 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30887
30922
  "T.INV",
30888
30923
  "T.INV.2T",
30889
30924
  "T.TEST",
30925
+ "TAKE",
30926
+ "TEXTAFTER",
30927
+ "TEXTBEFORE",
30890
30928
  "TEXTJOIN",
30929
+ "TEXTSPLIT",
30930
+ "TOCOL",
30931
+ "TOROW",
30891
30932
  "UNICHAR",
30892
30933
  "UNICODE",
30934
+ "UNIQUE",
30893
30935
  "VAR.P",
30894
30936
  "VAR.S",
30937
+ "VSTACK",
30895
30938
  "WEBSERVICE",
30896
30939
  "WEIBULL.DIST",
30940
+ "WRAPCOLS",
30941
+ "WRAPROWS",
30942
+ "XLOOKUP",
30897
30943
  "XOR",
30898
30944
  "Z.TEST",
30899
30945
  ];
@@ -35101,6 +35147,21 @@ class BordersPlugin extends CorePlugin {
35101
35147
  return [];
35102
35148
  return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
35103
35149
  }
35150
+ /**
35151
+ * Get all the rows which contains at least a border
35152
+ */
35153
+ getRowsWithBorders(sheetId) {
35154
+ const sheetBorders = this.borders[sheetId]?.filter(isDefined$1);
35155
+ if (!sheetBorders)
35156
+ return [];
35157
+ const rowsWithBorders = new Set();
35158
+ for (const rowBorders of sheetBorders) {
35159
+ for (const rowBorder in rowBorders) {
35160
+ rowsWithBorders.add(parseInt(rowBorder, 10));
35161
+ }
35162
+ }
35163
+ return Array.from(rowsWithBorders);
35164
+ }
35104
35165
  /**
35105
35166
  * Get the range of all the rows in the sheet
35106
35167
  */
@@ -35150,7 +35211,7 @@ class BordersPlugin extends CorePlugin {
35150
35211
  destructive: false,
35151
35212
  });
35152
35213
  }
35153
- this.getRowsRange(sheetId)
35214
+ this.getRowsWithBorders(sheetId)
35154
35215
  .filter((row) => row >= start)
35155
35216
  .sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
35156
35217
  .forEach((row) => {
@@ -35605,7 +35666,7 @@ function parseExpression(tokens, parent_priority = 0) {
35605
35666
  * Parse an expression (as a string) into an AST.
35606
35667
  */
35607
35668
  function parse(str) {
35608
- return parseTokens(tokenize(str));
35669
+ return parseTokens(rangeTokenize(str));
35609
35670
  }
35610
35671
  function parseTokens(tokens) {
35611
35672
  tokens = tokens.filter((x) => x.type !== "SPACE");
@@ -57806,6 +57867,6 @@ exports.setTranslationMethod = setTranslationMethod;
57806
57867
  exports.tokenize = tokenize;
57807
57868
 
57808
57869
 
57809
- __info__.version = "17.1.20";
57810
- __info__.date = "2024-07-02T09:03:04.534Z";
57811
- __info__.hash = "d15aaf3";
57870
+ __info__.version = "17.1.22";
57871
+ __info__.date = "2024-07-08T05:41:57.737Z";
57872
+ __info__.hash = "da27a94";
@@ -2736,7 +2736,7 @@ type LocaleCode = string & Alias;
2736
2736
  interface Locale {
2737
2737
  name: string;
2738
2738
  code: LocaleCode;
2739
- thousandsSeparator: string;
2739
+ thousandsSeparator?: string;
2740
2740
  decimalSeparator: string;
2741
2741
  dateFormat: string;
2742
2742
  timeFormat: string;
@@ -3189,6 +3189,10 @@ declare class BordersPlugin extends CorePlugin<BordersPluginState> implements Bo
3189
3189
  * Get all the columns which contains at least a border
3190
3190
  */
3191
3191
  private getColumnsWithBorders;
3192
+ /**
3193
+ * Get all the rows which contains at least a border
3194
+ */
3195
+ private getRowsWithBorders;
3192
3196
  /**
3193
3197
  * Get the range of all the rows in the sheet
3194
3198
  */
@@ -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.20
6
- * @date 2024-07-02T09:03:04.534Z
7
- * @hash d15aaf3
5
+ * @version 17.1.22
6
+ * @date 2024-07-08T05:41:57.737Z
7
+ * @hash da27a94
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';
@@ -1702,7 +1702,7 @@ const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSepa
1702
1702
  });
1703
1703
  const getNumberRegex = memoize(function getNumberRegex(locale) {
1704
1704
  const decimalSeparator = escapeRegExp(locale.decimalSeparator);
1705
- const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
1705
+ const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
1706
1706
  const pIntegerAndDecimals = `(\\d+(${thousandsSeparator}\\d{3,})*(${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
1707
1707
  const pOnlyDecimals = `(${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
1708
1708
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -1729,7 +1729,7 @@ function isNumber(value, locale) {
1729
1729
  return getNumberRegex(locale).test(value.trim());
1730
1730
  }
1731
1731
  const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
1732
- return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
1732
+ return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
1733
1733
  });
1734
1734
  /**
1735
1735
  * Convert a string into a number. It assumes that the string actually represents
@@ -7716,19 +7716,22 @@ class TokenizingChars {
7716
7716
  }
7717
7717
 
7718
7718
  function isValidLocale(locale) {
7719
- if (!(locale &&
7720
- typeof locale === "object" &&
7721
- typeof locale.name === "string" &&
7722
- typeof locale.code === "string" &&
7723
- typeof locale.thousandsSeparator === "string" &&
7724
- typeof locale.decimalSeparator === "string" &&
7725
- typeof locale.dateFormat === "string" &&
7726
- typeof locale.timeFormat === "string" &&
7727
- typeof locale.formulaArgSeparator === "string")) {
7719
+ if (!locale ||
7720
+ typeof locale !== "object" ||
7721
+ !(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
7728
7722
  return false;
7729
7723
  }
7730
- if (!Object.values(locale).every((v) => v)) {
7731
- return false;
7724
+ for (const property of [
7725
+ "code",
7726
+ "name",
7727
+ "decimalSeparator",
7728
+ "dateFormat",
7729
+ "timeFormat",
7730
+ "formulaArgSeparator",
7731
+ ]) {
7732
+ if (!locale[property] || typeof locale[property] !== "string") {
7733
+ return false;
7734
+ }
7732
7735
  }
7733
7736
  if (locale.formulaArgSeparator === locale.decimalSeparator) {
7734
7737
  return false;
@@ -7826,7 +7829,10 @@ function canonicalizeNumberLiteral(content, locale) {
7826
7829
  if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
7827
7830
  return content;
7828
7831
  }
7829
- return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
7832
+ if (locale.thousandsSeparator) {
7833
+ content = content.replaceAll(locale.thousandsSeparator, "");
7834
+ }
7835
+ return content.replace(locale.decimalSeparator, ".");
7830
7836
  }
7831
7837
  /**
7832
7838
  * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
@@ -9505,15 +9511,6 @@ function createLineChartRuntime(chart, getters) {
9505
9511
  }
9506
9512
  const colors = new ChartColors();
9507
9513
  for (let [index, { label, data }] of dataSetsValues.entries()) {
9508
- if (["linear", "time"].includes(axisType)) {
9509
- // Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
9510
- data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
9511
- }
9512
- const color = colors.next();
9513
- let backgroundRGBA = colorToRGBA(color);
9514
- if (chart.stacked) {
9515
- backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
9516
- }
9517
9514
  if (chart.cumulative) {
9518
9515
  let accumulator = 0;
9519
9516
  data = data.map((value) => {
@@ -9524,6 +9521,15 @@ function createLineChartRuntime(chart, getters) {
9524
9521
  return value;
9525
9522
  });
9526
9523
  }
9524
+ if (["linear", "time"].includes(axisType)) {
9525
+ // Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
9526
+ data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
9527
+ }
9528
+ const color = colors.next();
9529
+ let backgroundRGBA = colorToRGBA(color);
9530
+ if (chart.stacked) {
9531
+ backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
9532
+ }
9527
9533
  const backgroundColor = rgbaToHex(backgroundRGBA);
9528
9534
  const dataset = {
9529
9535
  label,
@@ -24779,7 +24785,13 @@ class SettingsPanel extends Component {
24779
24785
  }
24780
24786
  async loadLocales() {
24781
24787
  this.loadedLocales = (await this.env.loadLocales())
24782
- .filter(isValidLocale)
24788
+ .filter((locale) => {
24789
+ const isValid = isValidLocale(locale);
24790
+ if (!isValid) {
24791
+ console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
24792
+ }
24793
+ return isValid;
24794
+ })
24783
24795
  .sort((a, b) => a.name.localeCompare(b.name));
24784
24796
  }
24785
24797
  get numberFormatPreview() {
@@ -30535,6 +30547,7 @@ class Grid extends Component {
30535
30547
  return;
30536
30548
  }
30537
30549
  if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
30550
+ ev.preventDefault();
30538
30551
  const content = clipboardData.getData(ClipboardMIMEType.PlainText);
30539
30552
  const target = this.env.model.getters.getSelectedZones();
30540
30553
  const clipboardString = this.env.model.getters.getClipboardTextContent();
@@ -30790,6 +30803,8 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30790
30803
  "BITOR",
30791
30804
  "BITRSHIFT",
30792
30805
  "BITXOR",
30806
+ "BYCOL",
30807
+ "BYROW",
30793
30808
  "CEILING.MATH",
30794
30809
  "CEILING.PRECISE",
30795
30810
  "CHISQ.DIST",
@@ -30797,6 +30812,8 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30797
30812
  "CHISQ.INV",
30798
30813
  "CHISQ.INV.RT",
30799
30814
  "CHISQ.TEST",
30815
+ "CHOOSECOLS",
30816
+ "CHOOSEROWS",
30800
30817
  "COMBINA",
30801
30818
  "CONCAT",
30802
30819
  "CONFIDENCE.NORM",
@@ -30809,14 +30826,17 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30809
30826
  "CSCH",
30810
30827
  "DAYS",
30811
30828
  "DECIMAL",
30829
+ "DROP",
30812
30830
  "ERF.PRECISE",
30813
30831
  "ERFC.PRECISE",
30832
+ "EXPAND",
30814
30833
  "EXPON.DIST",
30815
30834
  "F.DIST",
30816
30835
  "F.DIST.RT",
30817
30836
  "F.INV",
30818
30837
  "F.INV.RT",
30819
30838
  "F.TEST",
30839
+ "FIELDVALUE",
30820
30840
  "FILTERXML",
30821
30841
  "FLOOR.MATH",
30822
30842
  "FLOOR.PRECISE",
@@ -30831,6 +30851,7 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30831
30851
  "GAMMA.INV",
30832
30852
  "GAMMALN.PRECISE",
30833
30853
  "GAUSS",
30854
+ "HSTACK",
30834
30855
  "HYPGEOM.DIST",
30835
30856
  "IFNA",
30836
30857
  "IFS",
@@ -30843,9 +30864,14 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30843
30864
  "IMSINH",
30844
30865
  "IMTAN",
30845
30866
  "ISFORMULA",
30867
+ "ISOMITTED",
30846
30868
  "ISOWEEKNUM",
30869
+ "LAMBDA",
30870
+ "LET",
30847
30871
  "LOGNORM.DIST",
30848
30872
  "LOGNORM.INV",
30873
+ "MAKEARRAY",
30874
+ "MAP",
30849
30875
  "MAXIFS",
30850
30876
  "MINIFS",
30851
30877
  "MODE.MULT",
@@ -30865,17 +30891,26 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30865
30891
  "PERMUTATIONA",
30866
30892
  "PHI",
30867
30893
  "POISSON.DIST",
30894
+ "PQSOURCE",
30895
+ "PYTHON_STR",
30896
+ "PYTHON_TYPE",
30897
+ "PYTHON_TYPENAME",
30868
30898
  "QUARTILE.EXC",
30869
30899
  "QUARTILE.INC",
30870
30900
  "QUERYSTRING",
30901
+ "RANDARRAY",
30871
30902
  "RANK.AVG",
30872
30903
  "RANK.EQ",
30904
+ "REDUCE",
30873
30905
  "RRI",
30906
+ "SCAN",
30874
30907
  "SEC",
30875
30908
  "SECH",
30909
+ "SEQUENCE",
30876
30910
  "SHEET",
30877
30911
  "SHEETS",
30878
30912
  "SKEW.P",
30913
+ "SORTBY",
30879
30914
  "STDEV.P",
30880
30915
  "STDEV.S",
30881
30916
  "SWITCH",
@@ -30885,13 +30920,24 @@ const NON_RETROCOMPATIBLE_FUNCTIONS = [
30885
30920
  "T.INV",
30886
30921
  "T.INV.2T",
30887
30922
  "T.TEST",
30923
+ "TAKE",
30924
+ "TEXTAFTER",
30925
+ "TEXTBEFORE",
30888
30926
  "TEXTJOIN",
30927
+ "TEXTSPLIT",
30928
+ "TOCOL",
30929
+ "TOROW",
30889
30930
  "UNICHAR",
30890
30931
  "UNICODE",
30932
+ "UNIQUE",
30891
30933
  "VAR.P",
30892
30934
  "VAR.S",
30935
+ "VSTACK",
30893
30936
  "WEBSERVICE",
30894
30937
  "WEIBULL.DIST",
30938
+ "WRAPCOLS",
30939
+ "WRAPROWS",
30940
+ "XLOOKUP",
30895
30941
  "XOR",
30896
30942
  "Z.TEST",
30897
30943
  ];
@@ -35099,6 +35145,21 @@ class BordersPlugin extends CorePlugin {
35099
35145
  return [];
35100
35146
  return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
35101
35147
  }
35148
+ /**
35149
+ * Get all the rows which contains at least a border
35150
+ */
35151
+ getRowsWithBorders(sheetId) {
35152
+ const sheetBorders = this.borders[sheetId]?.filter(isDefined$1);
35153
+ if (!sheetBorders)
35154
+ return [];
35155
+ const rowsWithBorders = new Set();
35156
+ for (const rowBorders of sheetBorders) {
35157
+ for (const rowBorder in rowBorders) {
35158
+ rowsWithBorders.add(parseInt(rowBorder, 10));
35159
+ }
35160
+ }
35161
+ return Array.from(rowsWithBorders);
35162
+ }
35102
35163
  /**
35103
35164
  * Get the range of all the rows in the sheet
35104
35165
  */
@@ -35148,7 +35209,7 @@ class BordersPlugin extends CorePlugin {
35148
35209
  destructive: false,
35149
35210
  });
35150
35211
  }
35151
- this.getRowsRange(sheetId)
35212
+ this.getRowsWithBorders(sheetId)
35152
35213
  .filter((row) => row >= start)
35153
35214
  .sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
35154
35215
  .forEach((row) => {
@@ -35603,7 +35664,7 @@ function parseExpression(tokens, parent_priority = 0) {
35603
35664
  * Parse an expression (as a string) into an AST.
35604
35665
  */
35605
35666
  function parse(str) {
35606
- return parseTokens(tokenize(str));
35667
+ return parseTokens(rangeTokenize(str));
35607
35668
  }
35608
35669
  function parseTokens(tokens) {
35609
35670
  tokens = tokens.filter((x) => x.type !== "SPACE");
@@ -57768,6 +57829,6 @@ const constants = {
57768
57829
  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 };
57769
57830
 
57770
57831
 
57771
- __info__.version = "17.1.20";
57772
- __info__.date = "2024-07-02T09:03:04.534Z";
57773
- __info__.hash = "d15aaf3";
57832
+ __info__.version = "17.1.22";
57833
+ __info__.date = "2024-07-08T05:41:57.737Z";
57834
+ __info__.hash = "da27a94";