@odoo/o-spreadsheet 17.1.9 → 17.1.11

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.9
6
- * @date 2024-03-25T09:43:27.017Z
7
- * @hash 5fb076e
5
+ * @version 17.1.11
6
+ * @date 2024-04-10T12:27:11.107Z
7
+ * @hash 246caf7
8
8
  */
9
9
 
10
10
  'use strict';
@@ -460,7 +460,7 @@ function getItemId(item, itemsDic) {
460
460
  }
461
461
  // Generate new Id if the item didn't exist in the dictionary
462
462
  const ids = Object.keys(itemsDic);
463
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
463
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
464
464
  itemsDic[maxId + 1] = item;
465
465
  return maxId + 1;
466
466
  }
@@ -551,7 +551,7 @@ function deepEquals(o1, o2) {
551
551
  if (typeof o1 !== typeof o2)
552
552
  return false;
553
553
  if (typeof o1 !== "object")
554
- return o1 === o2;
554
+ return false;
555
555
  // Objects can have different keys if the values are undefined
556
556
  for (const key in o2) {
557
557
  if (!(key in o1) && o2[key] !== undefined) {
@@ -677,6 +677,34 @@ function isNumberBetween(value, min, max) {
677
677
  }
678
678
  return value >= min && value <= max;
679
679
  }
680
+ /**
681
+ * Alternative to Math.max that works with large arrays.
682
+ * Typically useful for arrays bigger than 100k elements.
683
+ */
684
+ function largeMax(array) {
685
+ let len = array.length;
686
+ if (len < 100000)
687
+ return Math.max(...array);
688
+ let max = -Infinity;
689
+ while (len--) {
690
+ max = array[len] > max ? array[len] : max;
691
+ }
692
+ return max;
693
+ }
694
+ /**
695
+ * Alternative to Math.min that works with large arrays.
696
+ * Typically useful for arrays bigger than 100k elements.
697
+ */
698
+ function largeMin(array) {
699
+ let len = array.length;
700
+ if (len < 100000)
701
+ return Math.min(...array);
702
+ let min = +Infinity;
703
+ while (len--) {
704
+ min = array[len] < min ? array[len] : min;
705
+ }
706
+ return min;
707
+ }
680
708
 
681
709
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
682
710
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4479,8 +4507,9 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4479
4507
  * Get the default height of the cell given its style.
4480
4508
  */
4481
4509
  function getDefaultCellHeight(ctx, cell, colSize) {
4482
- if (!cell || !cell.content)
4510
+ if (!cell || (!cell.isFormula && !cell.content)) {
4483
4511
  return DEFAULT_CELL_HEIGHT;
4512
+ }
4484
4513
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4485
4514
  const numberOfLines = cell.isFormula
4486
4515
  ? 1
@@ -8382,10 +8411,10 @@ function aggregateDataForLabels(labels, datasets) {
8382
8411
  }
8383
8412
  }
8384
8413
  return {
8385
- labels: Object.keys(labelMap),
8414
+ labels: Array.from(labelSet),
8386
8415
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
8387
8416
  ...dataset,
8388
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
8417
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
8389
8418
  })),
8390
8419
  };
8391
8420
  }
@@ -8436,7 +8465,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
8436
8465
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
8437
8466
  // tooltipItem.parsed.y can be an object or a number for pie charts
8438
8467
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
8439
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
8468
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
8440
8469
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
8441
8470
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
8442
8471
  },
@@ -8723,7 +8752,10 @@ function getBarConfiguration(chart, labels, localeFormat) {
8723
8752
  if (isNaN(value))
8724
8753
  return value;
8725
8754
  const { locale, format } = localeFormat;
8726
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
8755
+ return formatValue(value, {
8756
+ locale,
8757
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
8758
+ });
8727
8759
  },
8728
8760
  },
8729
8761
  },
@@ -9137,7 +9169,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
9137
9169
  return undefined;
9138
9170
  }
9139
9171
  const labelsTimestamps = labelDates.map((date) => date.getTime());
9140
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
9172
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
9141
9173
  const minUnit = getFormatMinDisplayUnit(format);
9142
9174
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
9143
9175
  return "second";
@@ -9374,7 +9406,10 @@ function getLineConfiguration(chart, labels, localeFormat) {
9374
9406
  if (isNaN(value))
9375
9407
  return value;
9376
9408
  const { locale, format } = localeFormat;
9377
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
9409
+ return formatValue(value, {
9410
+ locale,
9411
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
9412
+ });
9378
9413
  },
9379
9414
  },
9380
9415
  },
@@ -9601,7 +9636,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
9601
9636
  const percentage = calculatePercentage(data, dataIndex);
9602
9637
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
9603
9638
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
9604
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
9639
+ const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
9605
9640
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
9606
9641
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
9607
9642
  };
@@ -9609,7 +9644,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
9609
9644
  }
9610
9645
  function getPieColors(colors, dataSetsValues) {
9611
9646
  const pieColors = [];
9612
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
9647
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
9613
9648
  for (let i = 0; i <= maxLength; i++) {
9614
9649
  pieColors.push(colors.next());
9615
9650
  }
@@ -10533,8 +10568,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
10533
10568
  let last;
10534
10569
  const activesRows = env.model.getters.getActiveRows();
10535
10570
  if (activesRows.size !== 0) {
10536
- first = Math.min(...activesRows);
10537
- last = Math.max(...activesRows);
10571
+ first = largeMin([...activesRows]);
10572
+ last = largeMax([...activesRows]);
10538
10573
  }
10539
10574
  else {
10540
10575
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10562,8 +10597,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
10562
10597
  let last;
10563
10598
  const activeCols = env.model.getters.getActiveCols();
10564
10599
  if (activeCols.size !== 0) {
10565
- first = Math.min(...activeCols);
10566
- last = Math.max(...activeCols);
10600
+ first = largeMin([...activeCols]);
10601
+ last = largeMax([...activeCols]);
10567
10602
  }
10568
10603
  else {
10569
10604
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10591,8 +10626,8 @@ const REMOVE_ROWS_NAME = (env) => {
10591
10626
  let last;
10592
10627
  const activesRows = env.model.getters.getActiveRows();
10593
10628
  if (activesRows.size !== 0) {
10594
- first = Math.min(...activesRows);
10595
- last = Math.max(...activesRows);
10629
+ first = largeMin([...activesRows]);
10630
+ last = largeMax([...activesRows]);
10596
10631
  }
10597
10632
  else {
10598
10633
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10633,8 +10668,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
10633
10668
  let last;
10634
10669
  const activeCols = env.model.getters.getActiveCols();
10635
10670
  if (activeCols.size !== 0) {
10636
- first = Math.min(...activeCols);
10637
- last = Math.max(...activeCols);
10671
+ first = largeMin([...activeCols]);
10672
+ last = largeMax([...activeCols]);
10638
10673
  }
10639
10674
  else {
10640
10675
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10675,7 +10710,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
10675
10710
  let row;
10676
10711
  let quantity;
10677
10712
  if (activeRows.size) {
10678
- row = Math.min(...activeRows);
10713
+ row = largeMin([...activeRows]);
10679
10714
  quantity = activeRows.size;
10680
10715
  }
10681
10716
  else {
@@ -10696,7 +10731,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
10696
10731
  let row;
10697
10732
  let quantity;
10698
10733
  if (activeRows.size) {
10699
- row = Math.max(...activeRows);
10734
+ row = largeMax([...activeRows]);
10700
10735
  quantity = activeRows.size;
10701
10736
  }
10702
10737
  else {
@@ -10717,7 +10752,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
10717
10752
  let column;
10718
10753
  let quantity;
10719
10754
  if (activeCols.size) {
10720
- column = Math.min(...activeCols);
10755
+ column = largeMin([...activeCols]);
10721
10756
  quantity = activeCols.size;
10722
10757
  }
10723
10758
  else {
@@ -10738,7 +10773,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
10738
10773
  let column;
10739
10774
  let quantity;
10740
10775
  if (activeCols.size) {
10741
- column = Math.max(...activeCols);
10776
+ column = largeMax([...activeCols]);
10742
10777
  quantity = activeCols.size;
10743
10778
  }
10744
10779
  else {
@@ -27074,6 +27109,7 @@ class Composer extends owl.Component {
27074
27109
  onComposerCellFocused: { type: Function, optional: true },
27075
27110
  onComposerContentFocused: Function,
27076
27111
  isDefaultFocus: { type: Boolean, optional: true },
27112
+ onInputContextMenu: { type: Function, optional: true },
27077
27113
  };
27078
27114
  static components = { TextValueProvider, FunctionDescriptionProvider };
27079
27115
  static defaultProps = {
@@ -27432,6 +27468,11 @@ class Composer extends owl.Component {
27432
27468
  }
27433
27469
  }
27434
27470
  }
27471
+ onContextMenu(ev) {
27472
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27473
+ this.props.onInputContextMenu?.(ev);
27474
+ }
27475
+ }
27435
27476
  // ---------------------------------------------------------------------------
27436
27477
  // Private
27437
27478
  // ---------------------------------------------------------------------------
@@ -27699,6 +27740,7 @@ class GridComposer extends owl.Component {
27699
27740
  onComposerCellFocused: Function,
27700
27741
  onComposerContentFocused: Function,
27701
27742
  gridDims: Object,
27743
+ onInputContextMenu: Function,
27702
27744
  };
27703
27745
  static components = { Composer };
27704
27746
  rect = this.defaultRect;
@@ -27743,6 +27785,7 @@ class GridComposer extends owl.Component {
27743
27785
  isDefaultFocus: true,
27744
27786
  onComposerContentFocused: this.props.onComposerContentFocused,
27745
27787
  onComposerCellFocused: this.props.onComposerCellFocused,
27788
+ onInputContextMenu: this.props.onInputContextMenu,
27746
27789
  };
27747
27790
  }
27748
27791
  get containerStyle() {
@@ -29219,11 +29262,6 @@ css /* scss */ `
29219
29262
  height: 10000px;
29220
29263
  background-color: ${SELECTION_BORDER_COLOR};
29221
29264
  }
29222
- .o-unhide-buttons {
29223
- width: fit-content;
29224
- gap: 5px;
29225
- transform: translate(-50%, 0);
29226
- }
29227
29265
  .o-unhide:hover {
29228
29266
  z-index: ${ComponentsImportance.Grid + 1};
29229
29267
  background-color: lightgrey;
@@ -29385,10 +29423,6 @@ css /* scss */ `
29385
29423
  height: 1px;
29386
29424
  background-color: ${SELECTION_BORDER_COLOR};
29387
29425
  }
29388
- .o-unhide-buttons {
29389
- height: fit-content;
29390
- transform: translate(0, -50%);
29391
- }
29392
29426
  .o-unhide:hover {
29393
29427
  z-index: ${ComponentsImportance.Grid + 1};
29394
29428
  background-color: lightgrey;
@@ -31749,29 +31783,12 @@ function convertWidthFromExcel(width) {
31749
31783
  return width;
31750
31784
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
31751
31785
  }
31752
- function convertBorderDescr(descr) {
31753
- if (!descr) {
31754
- return undefined;
31755
- }
31756
- return {
31757
- style: descr.style,
31758
- color: { rgb: descr.color },
31759
- };
31760
- }
31761
31786
  function extractStyle(cell, data) {
31762
31787
  let style = {};
31763
31788
  if (cell.style) {
31764
31789
  style = data.styles[cell.style];
31765
31790
  }
31766
31791
  const format = extractFormat(cell, data);
31767
- const exportedBorder = {};
31768
- if (cell.border) {
31769
- const border = data.borders[cell.border];
31770
- exportedBorder.left = convertBorderDescr(border.left);
31771
- exportedBorder.right = convertBorderDescr(border.right);
31772
- exportedBorder.bottom = convertBorderDescr(border.bottom);
31773
- exportedBorder.top = convertBorderDescr(border.top);
31774
- }
31775
31792
  const styles = {
31776
31793
  font: {
31777
31794
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -31785,7 +31802,7 @@ function extractStyle(cell, data) {
31785
31802
  }
31786
31803
  : { reservedAttribute: "none" },
31787
31804
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
31788
- border: exportedBorder || {},
31805
+ border: cell.border || 0,
31789
31806
  alignment: {
31790
31807
  horizontal: style.align,
31791
31808
  vertical: style.verticalAlign
@@ -31807,15 +31824,12 @@ function extractFormat(cell, data) {
31807
31824
  return undefined;
31808
31825
  }
31809
31826
  function normalizeStyle(construct, styles) {
31810
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
31811
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
31812
- const { id: borderId } = pushElement(styles["border"], construct.borders);
31813
31827
  // Normalize this
31814
31828
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
31815
31829
  const style = {
31816
- fontId,
31817
- fillId,
31818
- borderId,
31830
+ fontId: pushElement(styles.font, construct.fonts),
31831
+ fillId: pushElement(styles.fill, construct.fills),
31832
+ borderId: styles.border,
31819
31833
  numFmtId,
31820
31834
  alignment: {
31821
31835
  vertical: styles.alignment.vertical,
@@ -31823,8 +31837,7 @@ function normalizeStyle(construct, styles) {
31823
31837
  wrapText: styles.alignment.wrapText,
31824
31838
  },
31825
31839
  };
31826
- const { id } = pushElement(style, construct.styles);
31827
- return id;
31840
+ return pushElement(style, construct.styles);
31828
31841
  }
31829
31842
  function convertFormat(format, numFmtStructure) {
31830
31843
  if (!format) {
@@ -31832,8 +31845,7 @@ function convertFormat(format, numFmtStructure) {
31832
31845
  }
31833
31846
  let formatId = XLSX_FORMAT_MAP[format.format];
31834
31847
  if (!formatId) {
31835
- const { id } = pushElement(format, numFmtStructure);
31836
- formatId = id + FIRST_NUMFMT_ID;
31848
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
31837
31849
  }
31838
31850
  return formatId;
31839
31851
  }
@@ -31858,20 +31870,15 @@ function addRelsToFile(relsFiles, path, rel) {
31858
31870
  return id;
31859
31871
  }
31860
31872
  function pushElement(property, propertyList) {
31861
- for (let [key, value] of Object.entries(propertyList)) {
31862
- if (JSON.stringify(value) === JSON.stringify(property)) {
31863
- return { id: parseInt(key, 10), list: propertyList };
31873
+ let len = propertyList.length;
31874
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
31875
+ for (let i = 0; i < len; i++) {
31876
+ if (operator(property, propertyList[i])) {
31877
+ return i;
31864
31878
  }
31865
31879
  }
31866
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
31867
- if (elemId === -1) {
31868
- propertyList.push(property);
31869
- elemId = propertyList.length - 1;
31870
- }
31871
- return {
31872
- id: elemId,
31873
- list: propertyList,
31874
- };
31880
+ propertyList[propertyList.length] = property;
31881
+ return propertyList.length - 1;
31875
31882
  }
31876
31883
  const chartIds = [];
31877
31884
  /**
@@ -32329,7 +32336,7 @@ function convertHyperlink(link, cellValue, warningManager) {
32329
32336
  function getSheetDims(sheet) {
32330
32337
  const dims = [0, 0];
32331
32338
  for (let row of sheet.rows) {
32332
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
32339
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
32333
32340
  dims[1] = Math.max(dims[1], row.index);
32334
32341
  }
32335
32342
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -32598,7 +32605,25 @@ function parseXML(xmlString, mimeType = "text/xml") {
32598
32605
  }
32599
32606
  return document;
32600
32607
  }
32601
- function getDefaultXLSXStructure() {
32608
+ function convertBorderDescr(descr) {
32609
+ if (!descr) {
32610
+ return undefined;
32611
+ }
32612
+ return {
32613
+ style: descr.style,
32614
+ color: { rgb: descr.color },
32615
+ };
32616
+ }
32617
+ function getDefaultXLSXStructure(data) {
32618
+ const xlsxBorders = Object.values(data.borders).map((border) => {
32619
+ return {
32620
+ left: convertBorderDescr(border.left),
32621
+ right: convertBorderDescr(border.right),
32622
+ bottom: convertBorderDescr(border.bottom),
32623
+ top: convertBorderDescr(border.top),
32624
+ };
32625
+ });
32626
+ const borders = [{}, ...xlsxBorders];
32602
32627
  return {
32603
32628
  relsFiles: [],
32604
32629
  sharedStrings: [],
@@ -32621,7 +32646,7 @@ function getDefaultXLSXStructure() {
32621
32646
  },
32622
32647
  ],
32623
32648
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
32624
- borders: [{}],
32649
+ borders,
32625
32650
  numFmts: [],
32626
32651
  dxfs: [],
32627
32652
  };
@@ -37229,6 +37254,9 @@ class DataValidationPlugin extends CorePlugin {
37229
37254
  if (newRule.criterion.type === "isBoolean") {
37230
37255
  this.setCenterStyleToBooleanCells(newRule);
37231
37256
  }
37257
+ else if (newRule.criterion.type === "isValueInList") {
37258
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
37259
+ }
37232
37260
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
37233
37261
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
37234
37262
  if (ruleIndex !== -1) {
@@ -37814,7 +37842,17 @@ class FiltersPlugin extends CorePlugin {
37814
37842
  }
37815
37843
  }
37816
37844
  exportForExcel(data) {
37817
- this.export(data);
37845
+ for (const sheet of data.sheets) {
37846
+ for (const filterTable of this.getFilterTables(sheet.id)) {
37847
+ if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
37848
+ continue;
37849
+ }
37850
+ sheet.filterTables.push({
37851
+ range: zoneToXc(filterTable.zone),
37852
+ filters: [],
37853
+ });
37854
+ }
37855
+ }
37818
37856
  }
37819
37857
  }
37820
37858
 
@@ -37955,7 +37993,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
37955
37993
  if (hiddenElements.size >= elements) {
37956
37994
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37957
37995
  }
37958
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37996
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37959
37997
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37960
37998
  }
37961
37999
  else {
@@ -38770,8 +38808,8 @@ class RangeAdapter {
38770
38808
  let newRange = range;
38771
38809
  let changeType = "NONE";
38772
38810
  for (let group of groups) {
38773
- const min = Math.min(...group);
38774
- const max = Math.max(...group);
38811
+ const min = largeMin(group);
38812
+ const max = largeMax(group);
38775
38813
  if (range.zone[start] <= min && min <= range.zone[end]) {
38776
38814
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38777
38815
  changeType = "RESIZE";
@@ -39194,8 +39232,8 @@ class SheetPlugin extends CorePlugin {
39194
39232
  }
39195
39233
  return "Success" /* CommandResult.Success */;
39196
39234
  case "REMOVE_COLUMNS_ROWS": {
39197
- const min = Math.min(...cmd.elements);
39198
- const max = Math.max(...cmd.elements);
39235
+ const min = largeMin(cmd.elements);
39236
+ const max = largeMax(cmd.elements);
39199
39237
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
39200
39238
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
39201
39239
  }
@@ -41534,7 +41572,9 @@ class Evaluator {
41534
41572
  this.blockedArrayFormulas = new Set();
41535
41573
  this.spreadingRelations = new SpreadingRelation();
41536
41574
  this.formulaDependencies = lazy(() => {
41537
- const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
41575
+ const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
41576
+ .filter((range) => !range.invalidSheetName && !range.invalidXc)
41577
+ .map((range) => ({
41538
41578
  data: positionId,
41539
41579
  boundingBox: {
41540
41580
  zone: range.zone,
@@ -42103,7 +42143,7 @@ class EvaluationPlugin extends UIPlugin {
42103
42143
  ? getItemId(newFormat, data.formats)
42104
42144
  : exportedCellData.format;
42105
42145
  let content;
42106
- if (formulaCell instanceof FormulaCellWithDependencies) {
42146
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42107
42147
  content = formulaCell.contentWithFixedReferences;
42108
42148
  }
42109
42149
  else {
@@ -42524,13 +42564,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
42524
42564
  .map((cell) => cell.value);
42525
42565
  switch (threshold.type) {
42526
42566
  case "value":
42527
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42567
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42528
42568
  return result;
42529
42569
  case "number":
42530
42570
  return Number(threshold.value);
42531
42571
  case "percentage":
42532
- const min = Math.min(...rangeValues);
42533
- const max = Math.max(...rangeValues);
42572
+ const min = largeMin(rangeValues);
42573
+ const max = largeMax(rangeValues);
42534
42574
  const delta = max - min;
42535
42575
  return min + (delta * Number(threshold.value)) / 100;
42536
42576
  case "percentile":
@@ -43572,13 +43612,13 @@ class AutomaticSumPlugin extends UIPlugin {
43572
43612
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43573
43613
  const cellPositions = range(end, -1, -1);
43574
43614
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43575
- const maxValidPosition = Math.max(...invalidCells);
43615
+ const maxValidPosition = largeMax(invalidCells);
43576
43616
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43577
43617
  const firstSequence = numberSequences[0] || [];
43578
- if (Math.max(...firstSequence) < maxValidPosition) {
43618
+ if (largeMax(firstSequence) < maxValidPosition) {
43579
43619
  return Infinity;
43580
43620
  }
43581
- return Math.min(...firstSequence);
43621
+ return largeMin(firstSequence);
43582
43622
  }
43583
43623
  shouldFindData(sheetId, zone) {
43584
43624
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -46071,7 +46111,7 @@ class RendererPlugin extends UIPlugin {
46071
46111
  * column of the current viewport
46072
46112
  */
46073
46113
  getColDimensionsInViewport(sheetId, col) {
46074
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
46114
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
46075
46115
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
46076
46116
  const size = this.getters.getColSize(sheetId, col);
46077
46117
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -46086,7 +46126,7 @@ class RendererPlugin extends UIPlugin {
46086
46126
  * of the current viewport
46087
46127
  */
46088
46128
  getRowDimensionsInViewport(sheetId, row) {
46089
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
46129
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
46090
46130
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
46091
46131
  const size = this.getters.getRowSize(sheetId, row);
46092
46132
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -47469,7 +47509,7 @@ class SheetUIPlugin extends UIPlugin {
47469
47509
  getColMaxWidth(sheetId, index) {
47470
47510
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
47471
47511
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
47472
- return Math.max(0, ...sizes);
47512
+ return Math.max(0, largeMax(sizes));
47473
47513
  }
47474
47514
  /**
47475
47515
  * Check that any "sheetId" in the command matches an existing
@@ -48236,7 +48276,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
48236
48276
  }
48237
48277
  getPasteZone(target) {
48238
48278
  const height = this.values.length;
48239
- const width = Math.max(...this.values.map((a) => a.length));
48279
+ const width = largeMax(this.values.map((a) => a.length));
48240
48280
  const { left: activeCol, top: activeRow } = target[0];
48241
48281
  return {
48242
48282
  top: activeRow,
@@ -49182,11 +49222,11 @@ class EditionPlugin extends UIPlugin {
49182
49222
  }
49183
49223
  else {
49184
49224
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
49185
- values = this.getters
49225
+ values = Array.from(new Set(this.getters
49186
49226
  .getRangeValues(range)
49187
49227
  .filter(isNotNull)
49188
49228
  .map((value) => value.toString())
49189
- .filter((val) => val !== "");
49229
+ .filter((val) => val !== "")));
49190
49230
  }
49191
49231
  const composerContent = this.getCurrentContent();
49192
49232
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -51618,12 +51658,14 @@ class BottomBarSheet extends owl.Component {
51618
51658
  this.editionState = "initializing";
51619
51659
  }
51620
51660
  stopEdition() {
51621
- if (!this.state.isEditing)
51661
+ const input = this.sheetNameRef.el;
51662
+ if (!this.state.isEditing || !input)
51622
51663
  return;
51623
51664
  this.state.isEditing = false;
51624
51665
  this.editionState = "initializing";
51625
- this.sheetNameRef.el?.blur();
51666
+ input.blur();
51626
51667
  const inputValue = this.getInputContent() || "";
51668
+ input.innerText = inputValue;
51627
51669
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51628
51670
  }
51629
51671
  cancelEdition() {
@@ -51914,7 +51956,7 @@ class BottomBar extends owl.Component {
51914
51956
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51915
51957
  }
51916
51958
  onSheetMouseDown(sheetId, event) {
51917
- if (event.button !== 0)
51959
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51918
51960
  return;
51919
51961
  this.closeMenu();
51920
51962
  const visibleSheets = this.getVisibleSheets();
@@ -55368,7 +55410,7 @@ function addLineChart(chart) {
55368
55410
  }
55369
55411
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55370
55412
  const colors = new ChartColors();
55371
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55413
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55372
55414
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55373
55415
  const dataSetsNodes = [];
55374
55416
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -55506,8 +55548,7 @@ function addContent(content, sharedStrings, forceString = false) {
55506
55548
  attrs.push(["t", "b"]);
55507
55549
  }
55508
55550
  else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
55509
- const { id } = pushElement(content, sharedStrings);
55510
- value = id.toString();
55551
+ value = pushElement(content, sharedStrings);
55511
55552
  attrs.push(["t", "s"]);
55512
55553
  }
55513
55554
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -55632,8 +55673,7 @@ function addCellIsRule(cf, rule, dxfs) {
55632
55673
  if (rule.style.fillColor) {
55633
55674
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
55634
55675
  }
55635
- const { id } = pushElement(dxf, dxfs);
55636
- ruleAttributes.push(["dxfId", id]);
55676
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
55637
55677
  return escapeXml /*xml*/ `
55638
55678
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
55639
55679
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -56443,7 +56483,7 @@ function addSheetViews(sheet) {
56443
56483
  */
56444
56484
  function getXLSX(data) {
56445
56485
  const files = [];
56446
- const construct = getDefaultXLSXStructure();
56486
+ const construct = getDefaultXLSXStructure(data);
56447
56487
  files.push(createWorkbook(data, construct));
56448
56488
  files.push(...createWorksheets(data, construct));
56449
56489
  files.push(createStylesSheet(construct));
@@ -57332,6 +57372,6 @@ exports.setTranslationMethod = setTranslationMethod;
57332
57372
  exports.tokenize = tokenize;
57333
57373
 
57334
57374
 
57335
- __info__.version = "17.1.9";
57336
- __info__.date = "2024-03-25T09:43:27.017Z";
57337
- __info__.hash = "5fb076e";
57375
+ __info__.version = "17.1.11";
57376
+ __info__.date = "2024-04-10T12:27:11.107Z";
57377
+ __info__.hash = "246caf7";