@odoo/o-spreadsheet 17.4.27 → 17.4.29

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.4.27
6
- * @date 2025-03-19T08:27:27.414Z
7
- * @hash a87c1da
5
+ * @version 17.4.29
6
+ * @date 2025-04-04T08:40:34.590Z
7
+ * @hash 2937d99
8
8
  */
9
9
 
10
10
  'use strict';
@@ -774,8 +774,7 @@ function removeFalsyAttributes(obj) {
774
774
  *
775
775
  * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
776
776
  */
777
- const whiteSpaceSpecialCharacters = [
778
- " ",
777
+ const specialWhiteSpaceSpecialCharacters = [
779
778
  "\t",
780
779
  "\f",
781
780
  "\v",
@@ -790,7 +789,7 @@ const whiteSpaceSpecialCharacters = [
790
789
  String.fromCharCode(parseInt("3000", 16)),
791
790
  String.fromCharCode(parseInt("feff", 16)),
792
791
  ];
793
- const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|"), "g");
792
+ const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
794
793
  const newLineRegexp = /(\r\n|\r)/g;
795
794
  /**
796
795
  * Replace all different newlines characters by \n
@@ -1009,7 +1008,10 @@ function rgbaStringToHex(color) {
1009
1008
  }
1010
1009
  else if (stringVals.length === 4) {
1011
1010
  const alpha = parseFloat(stringVals.pop() || "1");
1012
- alphaHex = Math.round((alpha || 1) * 255);
1011
+ if (isNaN(alpha)) {
1012
+ throw new Error("invalid alpha value");
1013
+ }
1014
+ alphaHex = Math.round(alpha * 255);
1013
1015
  }
1014
1016
  const vals = stringVals.map((val) => parseInt(val, 10));
1015
1017
  if (alphaHex !== 255) {
@@ -5724,8 +5726,12 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
5724
5726
  str = replaceNewLines(str);
5725
5727
  const chars = new TokenizingChars(str);
5726
5728
  const result = [];
5729
+ const tokenizeSpace = specialWhiteSpaceRegexp.test(str)
5730
+ ? tokenizeSpecialCharacterSpace
5731
+ : tokenizeSimpleSpace;
5727
5732
  while (!chars.isOver()) {
5728
- let token = tokenizeSpace(chars) ||
5733
+ let token = tokenizeNewLine(chars) ||
5734
+ tokenizeSpace(chars) ||
5729
5735
  tokenizeArgsSeparator(chars, locale) ||
5730
5736
  tokenizeParenthesis(chars) ||
5731
5737
  tokenizeOperator(chars) ||
@@ -5859,17 +5865,19 @@ function tokenizeSymbol(chars) {
5859
5865
  }
5860
5866
  return null;
5861
5867
  }
5862
- function tokenizeSpace(chars) {
5863
- let length = 0;
5864
- while (chars.current === NEWLINE) {
5865
- length++;
5866
- chars.shift();
5868
+ function tokenizeSpecialCharacterSpace(chars) {
5869
+ let spaces = "";
5870
+ while (chars.current === " " || (chars.current && chars.current.match(specialWhiteSpaceRegexp))) {
5871
+ spaces += chars.shift();
5867
5872
  }
5868
- if (length) {
5869
- return { type: "SPACE", value: NEWLINE.repeat(length) };
5873
+ if (spaces) {
5874
+ return { type: "SPACE", value: spaces };
5870
5875
  }
5876
+ return null;
5877
+ }
5878
+ function tokenizeSimpleSpace(chars) {
5871
5879
  let spaces = "";
5872
- while (chars.current && chars.current.match(whiteSpaceRegexp)) {
5880
+ while (chars.current === " ") {
5873
5881
  spaces += chars.shift();
5874
5882
  }
5875
5883
  if (spaces) {
@@ -5877,6 +5885,17 @@ function tokenizeSpace(chars) {
5877
5885
  }
5878
5886
  return null;
5879
5887
  }
5888
+ function tokenizeNewLine(chars) {
5889
+ let length = 0;
5890
+ while (chars.current === NEWLINE) {
5891
+ length++;
5892
+ chars.shift();
5893
+ }
5894
+ if (length) {
5895
+ return { type: "SPACE", value: NEWLINE.repeat(length) };
5896
+ }
5897
+ return null;
5898
+ }
5880
5899
  function tokenizeInvalidRange(chars) {
5881
5900
  if (chars.currentStartsWith(CellErrorType.InvalidReference)) {
5882
5901
  chars.advanceBy(CellErrorType.InvalidReference.length);
@@ -5965,7 +5984,7 @@ function isValidLocale(locale) {
5965
5984
  */
5966
5985
  function canonicalizeNumberContent(content, locale) {
5967
5986
  return content.startsWith("=")
5968
- ? canonicalizeFormula$1(content, locale)
5987
+ ? canonicalizeFormula(content, locale)
5969
5988
  : canonicalizeNumberLiteral(content, locale);
5970
5989
  }
5971
5990
  /**
@@ -5980,7 +5999,7 @@ function canonicalizeNumberContent(content, locale) {
5980
5999
  */
5981
6000
  function canonicalizeContent(content, locale) {
5982
6001
  return content.startsWith("=")
5983
- ? canonicalizeFormula$1(content, locale)
6002
+ ? canonicalizeFormula(content, locale)
5984
6003
  : canonicalizeLiteral(content, locale);
5985
6004
  }
5986
6005
  /**
@@ -5996,15 +6015,21 @@ function localizeContent(content, locale) {
5996
6015
  ? localizeFormula(content, locale)
5997
6016
  : localizeLiteral(content, locale);
5998
6017
  }
6018
+ /** Change a number string to its canonical form (en_US locale) */
6019
+ function canonicalizeNumberValue(content, locale) {
6020
+ return content.startsWith("=")
6021
+ ? canonicalizeFormula(content, locale)
6022
+ : canonicalizeNumberLiteral(content, locale);
6023
+ }
5999
6024
  /** Change a formula to its canonical form (en_US locale) */
6000
- function canonicalizeFormula$1(formula, locale) {
6001
- return _localizeFormula$1(formula, locale, DEFAULT_LOCALE);
6025
+ function canonicalizeFormula(formula, locale) {
6026
+ return _localizeFormula(formula, locale, DEFAULT_LOCALE);
6002
6027
  }
6003
6028
  /** Change a formula from the canonical form to the given locale */
6004
6029
  function localizeFormula(formula, locale) {
6005
- return _localizeFormula$1(formula, DEFAULT_LOCALE, locale);
6030
+ return _localizeFormula(formula, DEFAULT_LOCALE, locale);
6006
6031
  }
6007
- function _localizeFormula$1(formula, fromLocale, toLocale) {
6032
+ function _localizeFormula(formula, fromLocale, toLocale) {
6008
6033
  if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
6009
6034
  fromLocale.decimalSeparator === toLocale.decimalSeparator) {
6010
6035
  return formula;
@@ -6159,37 +6184,6 @@ function getDateTimeFormat(locale) {
6159
6184
  return locale.dateFormat + " " + locale.timeFormat;
6160
6185
  }
6161
6186
 
6162
- /** Change a number string to its canonical form (en_US locale) */
6163
- function canonicalizeNumberValue(content, locale) {
6164
- return content.startsWith("=")
6165
- ? canonicalizeFormula(content, locale)
6166
- : canonicalizeNumberLiteral(content, locale);
6167
- }
6168
- /** Change a formula to its canonical form (en_US locale) */
6169
- function canonicalizeFormula(formula, locale) {
6170
- return _localizeFormula(formula, locale, DEFAULT_LOCALE);
6171
- }
6172
- function _localizeFormula(formula, fromLocale, toLocale) {
6173
- if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
6174
- fromLocale.decimalSeparator === toLocale.decimalSeparator) {
6175
- return formula;
6176
- }
6177
- const tokens = tokenize(formula, fromLocale);
6178
- let localizedFormula = "";
6179
- for (const token of tokens) {
6180
- if (token.type === "NUMBER") {
6181
- localizedFormula += token.value.replace(fromLocale.decimalSeparator, toLocale.decimalSeparator);
6182
- }
6183
- else if (token.type === "ARG_SEPARATOR") {
6184
- localizedFormula += toLocale.formulaArgSeparator;
6185
- }
6186
- else {
6187
- localizedFormula += token.value;
6188
- }
6189
- }
6190
- return localizedFormula;
6191
- }
6192
-
6193
6187
  function boolAnd(args) {
6194
6188
  let foundBoolean = false;
6195
6189
  let acc = true;
@@ -12026,7 +12020,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
12026
12020
  }
12027
12021
  }
12028
12022
  else if (dataSets.length === 1) {
12029
- for (let i = 0; i < getData(getters, dataSets[0]).length; i++) {
12023
+ const dataLength = getData(getters, dataSets[0]).length;
12024
+ for (let i = 0; i < dataLength; i++) {
12030
12025
  labels.formattedValues.push("");
12031
12026
  labels.values.push("");
12032
12027
  }
@@ -43181,9 +43176,9 @@ const XLSX_CHART_TYPES = [
43181
43176
  /** In XLSX color format (no #) */
43182
43177
  const AUTO_COLOR = "000000";
43183
43178
  const XLSX_ICONSET_MAP = {
43184
- arrow: "3Arrows",
43179
+ arrows: "3Arrows",
43185
43180
  smiley: "3Symbols",
43186
- dot: "3TrafficLights1",
43181
+ dots: "3TrafficLights1",
43187
43182
  };
43188
43183
  const NAMESPACE = {
43189
43184
  styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
@@ -43599,6 +43594,7 @@ const ICON_SET_CONVERSION_MAP = {
43599
43594
  };
43600
43595
  /** Map between legend position in XLSX file and human readable position */
43601
43596
  const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
43597
+ none: "none",
43602
43598
  b: "bottom",
43603
43599
  t: "top",
43604
43600
  l: "left",
@@ -45848,7 +45844,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
45848
45844
  default: "ffffff",
45849
45845
  }).asString(),
45850
45846
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
45851
- default: "b",
45847
+ default: "none",
45852
45848
  }).asString()],
45853
45849
  stacked: barChartGrouping === "stacked",
45854
45850
  fontColor: "000000",
@@ -45882,7 +45878,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
45882
45878
  default: "ffffff",
45883
45879
  }).asString(),
45884
45880
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(chartElement, "c:legendPos", "val", {
45885
- default: "b",
45881
+ default: "none",
45886
45882
  }).asString()],
45887
45883
  stacked: barChartGrouping === "stacked",
45888
45884
  fontColor: "000000",
@@ -64180,7 +64176,9 @@ css /* scss */ `
64180
64176
  margin-top: -1px;
64181
64177
  border: 1px solid;
64182
64178
 
64183
- .o-composer:empty:not(:focus):not(.active)::before {
64179
+ /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
64180
+ .o-composer:empty:not(:focus):not(.active)::before,
64181
+ &.o-topbar-composer-readonly .o-composer:empty::before {
64184
64182
  content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
64185
64183
  position: relative;
64186
64184
  top: 20%;
@@ -67424,10 +67422,14 @@ function addIconSetRule(cf, rule) {
67424
67422
  continue;
67425
67423
  }
67426
67424
  const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
67425
+ const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
67426
+ if (isIconSetReversed(rule.icons)) {
67427
+ iconSetAttrs.push(["reverse", "1"]);
67428
+ }
67427
67429
  conditionalFormats.push(escapeXml /*xml*/ `
67428
67430
  <conditionalFormatting sqref="${range}">
67429
67431
  <cfRule ${formatAttributes(ruleAttributes)}>
67430
- <iconSet iconSet="${getIconSet(rule.icons)}">
67432
+ <iconSet ${formatAttributes(iconSetAttrs)}>
67431
67433
  ${joinXmlNodes(cfValueObjectNodes)}
67432
67434
  </iconSet>
67433
67435
  </cfRule>
@@ -67445,9 +67447,21 @@ function commonCfAttributes(cf) {
67445
67447
  ["stopIfTrue", cf.stopIfTrue ? 1 : 0],
67446
67448
  ];
67447
67449
  }
67450
+ function isIconSetReversed(iconSet) {
67451
+ const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
67452
+ return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
67453
+ }
67448
67454
  function getIconSet(iconSet) {
67449
- return XLSX_ICONSET_MAP[Object.keys(XLSX_ICONSET_MAP).find((key) => iconSet.upper.toLowerCase().startsWith(key)) ||
67450
- "dots"];
67455
+ return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
67456
+ }
67457
+ /**
67458
+ * Partial detection based on "upper" point only.
67459
+ * We support any arbitrary icon in the set, while excel doesn't allow
67460
+ * mixing icons from different types.
67461
+ */
67462
+ function detectIconsType(iconSet) {
67463
+ const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
67464
+ return type;
67451
67465
  }
67452
67466
  function thresholdAttributes(threshold, position) {
67453
67467
  const type = getExcelThresholdType(threshold.type, position);
@@ -69229,6 +69243,6 @@ exports.tokenColors = tokenColors;
69229
69243
  exports.tokenize = tokenize;
69230
69244
 
69231
69245
 
69232
- __info__.version = "17.4.27";
69233
- __info__.date = "2025-03-19T08:27:27.414Z";
69234
- __info__.hash = "a87c1da";
69246
+ __info__.version = "17.4.29";
69247
+ __info__.date = "2025-04-04T08:40:34.590Z";
69248
+ __info__.hash = "2937d99";
@@ -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.4.27
6
- * @date 2025-03-19T08:27:27.414Z
7
- * @hash a87c1da
5
+ * @version 17.4.29
6
+ * @date 2025-04-04T08:40:34.590Z
7
+ * @hash 2937d99
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -772,8 +772,7 @@ function removeFalsyAttributes(obj) {
772
772
  *
773
773
  * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
774
774
  */
775
- const whiteSpaceSpecialCharacters = [
776
- " ",
775
+ const specialWhiteSpaceSpecialCharacters = [
777
776
  "\t",
778
777
  "\f",
779
778
  "\v",
@@ -788,7 +787,7 @@ const whiteSpaceSpecialCharacters = [
788
787
  String.fromCharCode(parseInt("3000", 16)),
789
788
  String.fromCharCode(parseInt("feff", 16)),
790
789
  ];
791
- const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|"), "g");
790
+ const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
792
791
  const newLineRegexp = /(\r\n|\r)/g;
793
792
  /**
794
793
  * Replace all different newlines characters by \n
@@ -1007,7 +1006,10 @@ function rgbaStringToHex(color) {
1007
1006
  }
1008
1007
  else if (stringVals.length === 4) {
1009
1008
  const alpha = parseFloat(stringVals.pop() || "1");
1010
- alphaHex = Math.round((alpha || 1) * 255);
1009
+ if (isNaN(alpha)) {
1010
+ throw new Error("invalid alpha value");
1011
+ }
1012
+ alphaHex = Math.round(alpha * 255);
1011
1013
  }
1012
1014
  const vals = stringVals.map((val) => parseInt(val, 10));
1013
1015
  if (alphaHex !== 255) {
@@ -5722,8 +5724,12 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
5722
5724
  str = replaceNewLines(str);
5723
5725
  const chars = new TokenizingChars(str);
5724
5726
  const result = [];
5727
+ const tokenizeSpace = specialWhiteSpaceRegexp.test(str)
5728
+ ? tokenizeSpecialCharacterSpace
5729
+ : tokenizeSimpleSpace;
5725
5730
  while (!chars.isOver()) {
5726
- let token = tokenizeSpace(chars) ||
5731
+ let token = tokenizeNewLine(chars) ||
5732
+ tokenizeSpace(chars) ||
5727
5733
  tokenizeArgsSeparator(chars, locale) ||
5728
5734
  tokenizeParenthesis(chars) ||
5729
5735
  tokenizeOperator(chars) ||
@@ -5857,17 +5863,19 @@ function tokenizeSymbol(chars) {
5857
5863
  }
5858
5864
  return null;
5859
5865
  }
5860
- function tokenizeSpace(chars) {
5861
- let length = 0;
5862
- while (chars.current === NEWLINE) {
5863
- length++;
5864
- chars.shift();
5866
+ function tokenizeSpecialCharacterSpace(chars) {
5867
+ let spaces = "";
5868
+ while (chars.current === " " || (chars.current && chars.current.match(specialWhiteSpaceRegexp))) {
5869
+ spaces += chars.shift();
5865
5870
  }
5866
- if (length) {
5867
- return { type: "SPACE", value: NEWLINE.repeat(length) };
5871
+ if (spaces) {
5872
+ return { type: "SPACE", value: spaces };
5868
5873
  }
5874
+ return null;
5875
+ }
5876
+ function tokenizeSimpleSpace(chars) {
5869
5877
  let spaces = "";
5870
- while (chars.current && chars.current.match(whiteSpaceRegexp)) {
5878
+ while (chars.current === " ") {
5871
5879
  spaces += chars.shift();
5872
5880
  }
5873
5881
  if (spaces) {
@@ -5875,6 +5883,17 @@ function tokenizeSpace(chars) {
5875
5883
  }
5876
5884
  return null;
5877
5885
  }
5886
+ function tokenizeNewLine(chars) {
5887
+ let length = 0;
5888
+ while (chars.current === NEWLINE) {
5889
+ length++;
5890
+ chars.shift();
5891
+ }
5892
+ if (length) {
5893
+ return { type: "SPACE", value: NEWLINE.repeat(length) };
5894
+ }
5895
+ return null;
5896
+ }
5878
5897
  function tokenizeInvalidRange(chars) {
5879
5898
  if (chars.currentStartsWith(CellErrorType.InvalidReference)) {
5880
5899
  chars.advanceBy(CellErrorType.InvalidReference.length);
@@ -5963,7 +5982,7 @@ function isValidLocale(locale) {
5963
5982
  */
5964
5983
  function canonicalizeNumberContent(content, locale) {
5965
5984
  return content.startsWith("=")
5966
- ? canonicalizeFormula$1(content, locale)
5985
+ ? canonicalizeFormula(content, locale)
5967
5986
  : canonicalizeNumberLiteral(content, locale);
5968
5987
  }
5969
5988
  /**
@@ -5978,7 +5997,7 @@ function canonicalizeNumberContent(content, locale) {
5978
5997
  */
5979
5998
  function canonicalizeContent(content, locale) {
5980
5999
  return content.startsWith("=")
5981
- ? canonicalizeFormula$1(content, locale)
6000
+ ? canonicalizeFormula(content, locale)
5982
6001
  : canonicalizeLiteral(content, locale);
5983
6002
  }
5984
6003
  /**
@@ -5994,15 +6013,21 @@ function localizeContent(content, locale) {
5994
6013
  ? localizeFormula(content, locale)
5995
6014
  : localizeLiteral(content, locale);
5996
6015
  }
6016
+ /** Change a number string to its canonical form (en_US locale) */
6017
+ function canonicalizeNumberValue(content, locale) {
6018
+ return content.startsWith("=")
6019
+ ? canonicalizeFormula(content, locale)
6020
+ : canonicalizeNumberLiteral(content, locale);
6021
+ }
5997
6022
  /** Change a formula to its canonical form (en_US locale) */
5998
- function canonicalizeFormula$1(formula, locale) {
5999
- return _localizeFormula$1(formula, locale, DEFAULT_LOCALE);
6023
+ function canonicalizeFormula(formula, locale) {
6024
+ return _localizeFormula(formula, locale, DEFAULT_LOCALE);
6000
6025
  }
6001
6026
  /** Change a formula from the canonical form to the given locale */
6002
6027
  function localizeFormula(formula, locale) {
6003
- return _localizeFormula$1(formula, DEFAULT_LOCALE, locale);
6028
+ return _localizeFormula(formula, DEFAULT_LOCALE, locale);
6004
6029
  }
6005
- function _localizeFormula$1(formula, fromLocale, toLocale) {
6030
+ function _localizeFormula(formula, fromLocale, toLocale) {
6006
6031
  if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
6007
6032
  fromLocale.decimalSeparator === toLocale.decimalSeparator) {
6008
6033
  return formula;
@@ -6157,37 +6182,6 @@ function getDateTimeFormat(locale) {
6157
6182
  return locale.dateFormat + " " + locale.timeFormat;
6158
6183
  }
6159
6184
 
6160
- /** Change a number string to its canonical form (en_US locale) */
6161
- function canonicalizeNumberValue(content, locale) {
6162
- return content.startsWith("=")
6163
- ? canonicalizeFormula(content, locale)
6164
- : canonicalizeNumberLiteral(content, locale);
6165
- }
6166
- /** Change a formula to its canonical form (en_US locale) */
6167
- function canonicalizeFormula(formula, locale) {
6168
- return _localizeFormula(formula, locale, DEFAULT_LOCALE);
6169
- }
6170
- function _localizeFormula(formula, fromLocale, toLocale) {
6171
- if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
6172
- fromLocale.decimalSeparator === toLocale.decimalSeparator) {
6173
- return formula;
6174
- }
6175
- const tokens = tokenize(formula, fromLocale);
6176
- let localizedFormula = "";
6177
- for (const token of tokens) {
6178
- if (token.type === "NUMBER") {
6179
- localizedFormula += token.value.replace(fromLocale.decimalSeparator, toLocale.decimalSeparator);
6180
- }
6181
- else if (token.type === "ARG_SEPARATOR") {
6182
- localizedFormula += toLocale.formulaArgSeparator;
6183
- }
6184
- else {
6185
- localizedFormula += token.value;
6186
- }
6187
- }
6188
- return localizedFormula;
6189
- }
6190
-
6191
6185
  function boolAnd(args) {
6192
6186
  let foundBoolean = false;
6193
6187
  let acc = true;
@@ -12024,7 +12018,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
12024
12018
  }
12025
12019
  }
12026
12020
  else if (dataSets.length === 1) {
12027
- for (let i = 0; i < getData(getters, dataSets[0]).length; i++) {
12021
+ const dataLength = getData(getters, dataSets[0]).length;
12022
+ for (let i = 0; i < dataLength; i++) {
12028
12023
  labels.formattedValues.push("");
12029
12024
  labels.values.push("");
12030
12025
  }
@@ -43179,9 +43174,9 @@ const XLSX_CHART_TYPES = [
43179
43174
  /** In XLSX color format (no #) */
43180
43175
  const AUTO_COLOR = "000000";
43181
43176
  const XLSX_ICONSET_MAP = {
43182
- arrow: "3Arrows",
43177
+ arrows: "3Arrows",
43183
43178
  smiley: "3Symbols",
43184
- dot: "3TrafficLights1",
43179
+ dots: "3TrafficLights1",
43185
43180
  };
43186
43181
  const NAMESPACE = {
43187
43182
  styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
@@ -43597,6 +43592,7 @@ const ICON_SET_CONVERSION_MAP = {
43597
43592
  };
43598
43593
  /** Map between legend position in XLSX file and human readable position */
43599
43594
  const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
43595
+ none: "none",
43600
43596
  b: "bottom",
43601
43597
  t: "top",
43602
43598
  l: "left",
@@ -45846,7 +45842,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
45846
45842
  default: "ffffff",
45847
45843
  }).asString(),
45848
45844
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
45849
- default: "b",
45845
+ default: "none",
45850
45846
  }).asString()],
45851
45847
  stacked: barChartGrouping === "stacked",
45852
45848
  fontColor: "000000",
@@ -45880,7 +45876,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
45880
45876
  default: "ffffff",
45881
45877
  }).asString(),
45882
45878
  legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(chartElement, "c:legendPos", "val", {
45883
- default: "b",
45879
+ default: "none",
45884
45880
  }).asString()],
45885
45881
  stacked: barChartGrouping === "stacked",
45886
45882
  fontColor: "000000",
@@ -64178,7 +64174,9 @@ css /* scss */ `
64178
64174
  margin-top: -1px;
64179
64175
  border: 1px solid;
64180
64176
 
64181
- .o-composer:empty:not(:focus):not(.active)::before {
64177
+ /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
64178
+ .o-composer:empty:not(:focus):not(.active)::before,
64179
+ &.o-topbar-composer-readonly .o-composer:empty::before {
64182
64180
  content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
64183
64181
  position: relative;
64184
64182
  top: 20%;
@@ -67422,10 +67420,14 @@ function addIconSetRule(cf, rule) {
67422
67420
  continue;
67423
67421
  }
67424
67422
  const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
67423
+ const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
67424
+ if (isIconSetReversed(rule.icons)) {
67425
+ iconSetAttrs.push(["reverse", "1"]);
67426
+ }
67425
67427
  conditionalFormats.push(escapeXml /*xml*/ `
67426
67428
  <conditionalFormatting sqref="${range}">
67427
67429
  <cfRule ${formatAttributes(ruleAttributes)}>
67428
- <iconSet iconSet="${getIconSet(rule.icons)}">
67430
+ <iconSet ${formatAttributes(iconSetAttrs)}>
67429
67431
  ${joinXmlNodes(cfValueObjectNodes)}
67430
67432
  </iconSet>
67431
67433
  </cfRule>
@@ -67443,9 +67445,21 @@ function commonCfAttributes(cf) {
67443
67445
  ["stopIfTrue", cf.stopIfTrue ? 1 : 0],
67444
67446
  ];
67445
67447
  }
67448
+ function isIconSetReversed(iconSet) {
67449
+ const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
67450
+ return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
67451
+ }
67446
67452
  function getIconSet(iconSet) {
67447
- return XLSX_ICONSET_MAP[Object.keys(XLSX_ICONSET_MAP).find((key) => iconSet.upper.toLowerCase().startsWith(key)) ||
67448
- "dots"];
67453
+ return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
67454
+ }
67455
+ /**
67456
+ * Partial detection based on "upper" point only.
67457
+ * We support any arbitrary icon in the set, while excel doesn't allow
67458
+ * mixing icons from different types.
67459
+ */
67460
+ function detectIconsType(iconSet) {
67461
+ const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
67462
+ return type;
67449
67463
  }
67450
67464
  function thresholdAttributes(threshold, position) {
67451
67465
  const type = getExcelThresholdType(threshold.type, position);
@@ -69184,6 +69198,6 @@ const constants = {
69184
69198
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
69185
69199
 
69186
69200
 
69187
- __info__.version = "17.4.27";
69188
- __info__.date = "2025-03-19T08:27:27.414Z";
69189
- __info__.hash = "a87c1da";
69201
+ __info__.version = "17.4.29";
69202
+ __info__.date = "2025-04-04T08:40:34.590Z";
69203
+ __info__.hash = "2937d99";