@odoo/o-spreadsheet 17.0.16 → 17.0.18

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.0.16
6
- * @date 2024-03-25T09:42:01.717Z
7
- * @hash 9b128f8
5
+ * @version 17.0.18
6
+ * @date 2024-04-10T13:28:23.664Z
7
+ * @hash 6294758
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -558,7 +558,7 @@
558
558
  }
559
559
  // Generate new Id if the item didn't exist in the dictionary
560
560
  const ids = Object.keys(itemsDic);
561
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
561
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
562
562
  itemsDic[maxId + 1] = item;
563
563
  return maxId + 1;
564
564
  }
@@ -649,7 +649,7 @@
649
649
  if (typeof o1 !== typeof o2)
650
650
  return false;
651
651
  if (typeof o1 !== "object")
652
- return o1 === o2;
652
+ return false;
653
653
  // Objects can have different keys if the values are undefined
654
654
  for (const key in o2) {
655
655
  if (!(key in o1) && o2[key] !== undefined) {
@@ -775,6 +775,34 @@
775
775
  }
776
776
  return value >= min && value <= max;
777
777
  }
778
+ /**
779
+ * Alternative to Math.max that works with large arrays.
780
+ * Typically useful for arrays bigger than 100k elements.
781
+ */
782
+ function largeMax(array) {
783
+ let len = array.length;
784
+ if (len < 100000)
785
+ return Math.max(...array);
786
+ let max = -Infinity;
787
+ while (len--) {
788
+ max = array[len] > max ? array[len] : max;
789
+ }
790
+ return max;
791
+ }
792
+ /**
793
+ * Alternative to Math.min that works with large arrays.
794
+ * Typically useful for arrays bigger than 100k elements.
795
+ */
796
+ function largeMin(array) {
797
+ let len = array.length;
798
+ if (len < 100000)
799
+ return Math.min(...array);
800
+ let min = +Infinity;
801
+ while (len--) {
802
+ min = array[len] < min ? array[len] : min;
803
+ }
804
+ return min;
805
+ }
778
806
 
779
807
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
780
808
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4421,8 +4449,9 @@
4421
4449
  * Get the default height of the cell given its style.
4422
4450
  */
4423
4451
  function getDefaultCellHeight(ctx, cell, colSize) {
4424
- if (!cell || !cell.content)
4452
+ if (!cell || (!cell.isFormula && !cell.content)) {
4425
4453
  return DEFAULT_CELL_HEIGHT;
4454
+ }
4426
4455
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4427
4456
  const numberOfLines = cell.isFormula
4428
4457
  ? 1
@@ -8325,10 +8354,10 @@
8325
8354
  }
8326
8355
  }
8327
8356
  return {
8328
- labels: Object.keys(labelMap),
8357
+ labels: Array.from(labelSet),
8329
8358
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
8330
8359
  ...dataset,
8331
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
8360
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
8332
8361
  })),
8333
8362
  };
8334
8363
  }
@@ -8379,7 +8408,7 @@
8379
8408
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
8380
8409
  // tooltipItem.parsed.y can be an object or a number for pie charts
8381
8410
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
8382
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
8411
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
8383
8412
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
8384
8413
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
8385
8414
  },
@@ -8665,7 +8694,10 @@
8665
8694
  if (isNaN(value))
8666
8695
  return value;
8667
8696
  const { locale, format } = localeFormat;
8668
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
8697
+ return formatValue(value, {
8698
+ locale,
8699
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
8700
+ });
8669
8701
  },
8670
8702
  },
8671
8703
  },
@@ -9079,7 +9111,7 @@
9079
9111
  return undefined;
9080
9112
  }
9081
9113
  const labelsTimestamps = labelDates.map((date) => date.getTime());
9082
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
9114
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
9083
9115
  const minUnit = getFormatMinDisplayUnit(format);
9084
9116
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
9085
9117
  return "second";
@@ -9316,7 +9348,10 @@
9316
9348
  if (isNaN(value))
9317
9349
  return value;
9318
9350
  const { locale, format } = localeFormat;
9319
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
9351
+ return formatValue(value, {
9352
+ locale,
9353
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
9354
+ });
9320
9355
  },
9321
9356
  },
9322
9357
  },
@@ -9543,7 +9578,7 @@
9543
9578
  const percentage = calculatePercentage(data, dataIndex);
9544
9579
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
9545
9580
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
9546
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
9581
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
9547
9582
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
9548
9583
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
9549
9584
  };
@@ -9551,7 +9586,7 @@
9551
9586
  }
9552
9587
  function getPieColors(colors, dataSetsValues) {
9553
9588
  const pieColors = [];
9554
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
9589
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
9555
9590
  for (let i = 0; i <= maxLength; i++) {
9556
9591
  pieColors.push(colors.next());
9557
9592
  }
@@ -10453,8 +10488,8 @@
10453
10488
  let last;
10454
10489
  const activesRows = env.model.getters.getActiveRows();
10455
10490
  if (activesRows.size !== 0) {
10456
- first = Math.min(...activesRows);
10457
- last = Math.max(...activesRows);
10491
+ first = largeMin([...activesRows]);
10492
+ last = largeMax([...activesRows]);
10458
10493
  }
10459
10494
  else {
10460
10495
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10482,8 +10517,8 @@
10482
10517
  let last;
10483
10518
  const activeCols = env.model.getters.getActiveCols();
10484
10519
  if (activeCols.size !== 0) {
10485
- first = Math.min(...activeCols);
10486
- last = Math.max(...activeCols);
10520
+ first = largeMin([...activeCols]);
10521
+ last = largeMax([...activeCols]);
10487
10522
  }
10488
10523
  else {
10489
10524
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10511,8 +10546,8 @@
10511
10546
  let last;
10512
10547
  const activesRows = env.model.getters.getActiveRows();
10513
10548
  if (activesRows.size !== 0) {
10514
- first = Math.min(...activesRows);
10515
- last = Math.max(...activesRows);
10549
+ first = largeMin([...activesRows]);
10550
+ last = largeMax([...activesRows]);
10516
10551
  }
10517
10552
  else {
10518
10553
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10553,8 +10588,8 @@
10553
10588
  let last;
10554
10589
  const activeCols = env.model.getters.getActiveCols();
10555
10590
  if (activeCols.size !== 0) {
10556
- first = Math.min(...activeCols);
10557
- last = Math.max(...activeCols);
10591
+ first = largeMin([...activeCols]);
10592
+ last = largeMax([...activeCols]);
10558
10593
  }
10559
10594
  else {
10560
10595
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10595,7 +10630,7 @@
10595
10630
  let row;
10596
10631
  let quantity;
10597
10632
  if (activeRows.size) {
10598
- row = Math.min(...activeRows);
10633
+ row = largeMin([...activeRows]);
10599
10634
  quantity = activeRows.size;
10600
10635
  }
10601
10636
  else {
@@ -10616,7 +10651,7 @@
10616
10651
  let row;
10617
10652
  let quantity;
10618
10653
  if (activeRows.size) {
10619
- row = Math.max(...activeRows);
10654
+ row = largeMax([...activeRows]);
10620
10655
  quantity = activeRows.size;
10621
10656
  }
10622
10657
  else {
@@ -10637,7 +10672,7 @@
10637
10672
  let column;
10638
10673
  let quantity;
10639
10674
  if (activeCols.size) {
10640
- column = Math.min(...activeCols);
10675
+ column = largeMin([...activeCols]);
10641
10676
  quantity = activeCols.size;
10642
10677
  }
10643
10678
  else {
@@ -10658,7 +10693,7 @@
10658
10693
  let column;
10659
10694
  let quantity;
10660
10695
  if (activeCols.size) {
10661
- column = Math.max(...activeCols);
10696
+ column = largeMax([...activeCols]);
10662
10697
  quantity = activeCols.size;
10663
10698
  }
10664
10699
  else {
@@ -26928,6 +26963,11 @@
26928
26963
  }
26929
26964
  }
26930
26965
  }
26966
+ onContextMenu(ev) {
26967
+ if (this.env.model.getters.getEditionMode() === "inactive") {
26968
+ this.props.onInputContextMenu?.(ev);
26969
+ }
26970
+ }
26931
26971
  // ---------------------------------------------------------------------------
26932
26972
  // Private
26933
26973
  // ---------------------------------------------------------------------------
@@ -27165,6 +27205,7 @@
27165
27205
  onComposerCellFocused: { type: Function, optional: true },
27166
27206
  onComposerContentFocused: Function,
27167
27207
  isDefaultFocus: { type: Boolean, optional: true },
27208
+ onInputContextMenu: { type: Function, optional: true },
27168
27209
  };
27169
27210
 
27170
27211
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
@@ -27240,6 +27281,7 @@
27240
27281
  isDefaultFocus: true,
27241
27282
  onComposerContentFocused: this.props.onComposerContentFocused,
27242
27283
  onComposerCellFocused: this.props.onComposerCellFocused,
27284
+ onInputContextMenu: this.props.onInputContextMenu,
27243
27285
  };
27244
27286
  }
27245
27287
  get containerStyle() {
@@ -27328,6 +27370,7 @@
27328
27370
  onComposerContentFocused: Function,
27329
27371
  gridDims: Object,
27330
27372
  onComposerCellFocused: Function,
27373
+ onInputContextMenu: Function,
27331
27374
  };
27332
27375
 
27333
27376
  const CSS$1 = css /* scss */ `
@@ -31281,29 +31324,12 @@
31281
31324
  return width;
31282
31325
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
31283
31326
  }
31284
- function convertBorderDescr(descr) {
31285
- if (!descr) {
31286
- return undefined;
31287
- }
31288
- return {
31289
- style: descr.style,
31290
- color: { rgb: descr.color },
31291
- };
31292
- }
31293
31327
  function extractStyle(cell, data) {
31294
31328
  let style = {};
31295
31329
  if (cell.style) {
31296
31330
  style = data.styles[cell.style];
31297
31331
  }
31298
31332
  const format = extractFormat(cell, data);
31299
- const exportedBorder = {};
31300
- if (cell.border) {
31301
- const border = data.borders[cell.border];
31302
- exportedBorder.left = convertBorderDescr(border.left);
31303
- exportedBorder.right = convertBorderDescr(border.right);
31304
- exportedBorder.bottom = convertBorderDescr(border.bottom);
31305
- exportedBorder.top = convertBorderDescr(border.top);
31306
- }
31307
31333
  const styles = {
31308
31334
  font: {
31309
31335
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -31317,7 +31343,7 @@
31317
31343
  }
31318
31344
  : { reservedAttribute: "none" },
31319
31345
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
31320
- border: exportedBorder || {},
31346
+ border: cell.border || 0,
31321
31347
  alignment: {
31322
31348
  horizontal: style.align,
31323
31349
  vertical: style.verticalAlign
@@ -31339,15 +31365,12 @@
31339
31365
  return undefined;
31340
31366
  }
31341
31367
  function normalizeStyle(construct, styles) {
31342
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
31343
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
31344
- const { id: borderId } = pushElement(styles["border"], construct.borders);
31345
31368
  // Normalize this
31346
31369
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
31347
31370
  const style = {
31348
- fontId,
31349
- fillId,
31350
- borderId,
31371
+ fontId: pushElement(styles.font, construct.fonts),
31372
+ fillId: pushElement(styles.fill, construct.fills),
31373
+ borderId: styles.border,
31351
31374
  numFmtId,
31352
31375
  alignment: {
31353
31376
  vertical: styles.alignment.vertical,
@@ -31355,8 +31378,7 @@
31355
31378
  wrapText: styles.alignment.wrapText,
31356
31379
  },
31357
31380
  };
31358
- const { id } = pushElement(style, construct.styles);
31359
- return id;
31381
+ return pushElement(style, construct.styles);
31360
31382
  }
31361
31383
  function convertFormat(format, numFmtStructure) {
31362
31384
  if (!format) {
@@ -31364,8 +31386,7 @@
31364
31386
  }
31365
31387
  let formatId = XLSX_FORMAT_MAP[format.format];
31366
31388
  if (!formatId) {
31367
- const { id } = pushElement(format, numFmtStructure);
31368
- formatId = id + FIRST_NUMFMT_ID;
31389
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
31369
31390
  }
31370
31391
  return formatId;
31371
31392
  }
@@ -31390,20 +31411,15 @@
31390
31411
  return id;
31391
31412
  }
31392
31413
  function pushElement(property, propertyList) {
31393
- for (let [key, value] of Object.entries(propertyList)) {
31394
- if (JSON.stringify(value) === JSON.stringify(property)) {
31395
- return { id: parseInt(key, 10), list: propertyList };
31414
+ let len = propertyList.length;
31415
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
31416
+ for (let i = 0; i < len; i++) {
31417
+ if (operator(property, propertyList[i])) {
31418
+ return i;
31396
31419
  }
31397
31420
  }
31398
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
31399
- if (elemId === -1) {
31400
- propertyList.push(property);
31401
- elemId = propertyList.length - 1;
31402
- }
31403
- return {
31404
- id: elemId,
31405
- list: propertyList,
31406
- };
31421
+ propertyList[propertyList.length] = property;
31422
+ return propertyList.length - 1;
31407
31423
  }
31408
31424
  const chartIds = [];
31409
31425
  /**
@@ -31855,7 +31871,7 @@
31855
31871
  function getSheetDims(sheet) {
31856
31872
  const dims = [0, 0];
31857
31873
  for (let row of sheet.rows) {
31858
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
31874
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
31859
31875
  dims[1] = Math.max(dims[1], row.index);
31860
31876
  }
31861
31877
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -32124,7 +32140,25 @@
32124
32140
  }
32125
32141
  return document;
32126
32142
  }
32127
- function getDefaultXLSXStructure() {
32143
+ function convertBorderDescr(descr) {
32144
+ if (!descr) {
32145
+ return undefined;
32146
+ }
32147
+ return {
32148
+ style: descr.style,
32149
+ color: { rgb: descr.color },
32150
+ };
32151
+ }
32152
+ function getDefaultXLSXStructure(data) {
32153
+ const xlsxBorders = Object.values(data.borders).map((border) => {
32154
+ return {
32155
+ left: convertBorderDescr(border.left),
32156
+ right: convertBorderDescr(border.right),
32157
+ bottom: convertBorderDescr(border.bottom),
32158
+ top: convertBorderDescr(border.top),
32159
+ };
32160
+ });
32161
+ const borders = [{}, ...xlsxBorders];
32128
32162
  return {
32129
32163
  relsFiles: [],
32130
32164
  sharedStrings: [],
@@ -32147,7 +32181,7 @@
32147
32181
  },
32148
32182
  ],
32149
32183
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
32150
- borders: [{}],
32184
+ borders,
32151
32185
  numFmts: [],
32152
32186
  dxfs: [],
32153
32187
  };
@@ -36745,6 +36779,9 @@
36745
36779
  if (newRule.criterion.type === "isBoolean") {
36746
36780
  this.setCenterStyleToBooleanCells(newRule);
36747
36781
  }
36782
+ else if (newRule.criterion.type === "isValueInList") {
36783
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
36784
+ }
36748
36785
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
36749
36786
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
36750
36787
  if (ruleIndex !== -1) {
@@ -37330,7 +37367,17 @@
37330
37367
  }
37331
37368
  }
37332
37369
  exportForExcel(data) {
37333
- this.export(data);
37370
+ for (const sheet of data.sheets) {
37371
+ for (const filterTable of this.getFilterTables(sheet.id)) {
37372
+ if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
37373
+ continue;
37374
+ }
37375
+ sheet.filterTables.push({
37376
+ range: zoneToXc(filterTable.zone),
37377
+ filters: [],
37378
+ });
37379
+ }
37380
+ }
37334
37381
  }
37335
37382
  }
37336
37383
 
@@ -37471,7 +37518,7 @@
37471
37518
  if (hiddenElements.size >= elements) {
37472
37519
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37473
37520
  }
37474
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37521
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37475
37522
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37476
37523
  }
37477
37524
  else {
@@ -38286,8 +38333,8 @@
38286
38333
  let newRange = range;
38287
38334
  let changeType = "NONE";
38288
38335
  for (let group of groups) {
38289
- const min = Math.min(...group);
38290
- const max = Math.max(...group);
38336
+ const min = largeMin(group);
38337
+ const max = largeMax(group);
38291
38338
  if (range.zone[start] <= min && min <= range.zone[end]) {
38292
38339
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38293
38340
  changeType = "RESIZE";
@@ -38710,8 +38757,8 @@
38710
38757
  }
38711
38758
  return "Success" /* CommandResult.Success */;
38712
38759
  case "REMOVE_COLUMNS_ROWS": {
38713
- const min = Math.min(...cmd.elements);
38714
- const max = Math.max(...cmd.elements);
38760
+ const min = largeMin(cmd.elements);
38761
+ const max = largeMax(cmd.elements);
38715
38762
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
38716
38763
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
38717
38764
  }
@@ -41059,7 +41106,9 @@
41059
41106
  this.blockedArrayFormulas = new Set();
41060
41107
  this.spreadingRelations = new SpreadingRelation();
41061
41108
  this.formulaDependencies = lazy(() => {
41062
- const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
41109
+ const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
41110
+ .filter((range) => !range.invalidSheetName && !range.invalidXc)
41111
+ .map((range) => ({
41063
41112
  data: positionId,
41064
41113
  boundingBox: {
41065
41114
  zone: range.zone,
@@ -42043,13 +42092,13 @@
42043
42092
  .map((cell) => cell.value);
42044
42093
  switch (threshold.type) {
42045
42094
  case "value":
42046
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42095
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42047
42096
  return result;
42048
42097
  case "number":
42049
42098
  return Number(threshold.value);
42050
42099
  case "percentage":
42051
- const min = Math.min(...rangeValues);
42052
- const max = Math.max(...rangeValues);
42100
+ const min = largeMin(rangeValues);
42101
+ const max = largeMax(rangeValues);
42053
42102
  const delta = max - min;
42054
42103
  return min + (delta * Number(threshold.value)) / 100;
42055
42104
  case "percentile":
@@ -43101,13 +43150,13 @@
43101
43150
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43102
43151
  const cellPositions = range(end, -1, -1);
43103
43152
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43104
- const maxValidPosition = Math.max(...invalidCells);
43153
+ const maxValidPosition = largeMax(invalidCells);
43105
43154
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43106
43155
  const firstSequence = numberSequences[0] || [];
43107
- if (Math.max(...firstSequence) < maxValidPosition) {
43156
+ if (largeMax(firstSequence) < maxValidPosition) {
43108
43157
  return Infinity;
43109
43158
  }
43110
- return Math.min(...firstSequence);
43159
+ return largeMin(firstSequence);
43111
43160
  }
43112
43161
  shouldFindData(sheetId, zone) {
43113
43162
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -45511,7 +45560,7 @@
45511
45560
  * column of the current viewport
45512
45561
  */
45513
45562
  getColDimensionsInViewport(sheetId, col) {
45514
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
45563
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
45515
45564
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
45516
45565
  const size = this.getters.getColSize(sheetId, col);
45517
45566
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -45526,7 +45575,7 @@
45526
45575
  * of the current viewport
45527
45576
  */
45528
45577
  getRowDimensionsInViewport(sheetId, row) {
45529
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
45578
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
45530
45579
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
45531
45580
  const size = this.getters.getRowSize(sheetId, row);
45532
45581
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -46990,7 +47039,7 @@
46990
47039
  getColMaxWidth(sheetId, index) {
46991
47040
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
46992
47041
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
46993
- return Math.max(0, ...sizes);
47042
+ return Math.max(0, largeMax(sizes));
46994
47043
  }
46995
47044
  /**
46996
47045
  * Check that any "sheetId" in the command matches an existing
@@ -47755,7 +47804,7 @@
47755
47804
  }
47756
47805
  getPasteZone(target) {
47757
47806
  const height = this.values.length;
47758
- const width = Math.max(...this.values.map((a) => a.length));
47807
+ const width = largeMax(this.values.map((a) => a.length));
47759
47808
  const { left: activeCol, top: activeRow } = target[0];
47760
47809
  return {
47761
47810
  top: activeRow,
@@ -48792,11 +48841,11 @@
48792
48841
  }
48793
48842
  else {
48794
48843
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
48795
- values = this.getters
48844
+ values = Array.from(new Set(this.getters
48796
48845
  .getRangeValues(range)
48797
48846
  .filter(isNotNull)
48798
48847
  .map((value) => value.toString())
48799
- .filter((val) => val !== "");
48848
+ .filter((val) => val !== "")));
48800
48849
  }
48801
48850
  const composerContent = this.getCurrentContent();
48802
48851
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -51253,12 +51302,14 @@
51253
51302
  this.editionState = "initializing";
51254
51303
  }
51255
51304
  stopEdition() {
51256
- if (!this.state.isEditing)
51305
+ const input = this.sheetNameRef.el;
51306
+ if (!this.state.isEditing || !input)
51257
51307
  return;
51258
51308
  this.state.isEditing = false;
51259
51309
  this.editionState = "initializing";
51260
- this.sheetNameRef.el?.blur();
51310
+ input.blur();
51261
51311
  const inputValue = this.getInputContent() || "";
51312
+ input.innerText = inputValue;
51262
51313
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51263
51314
  }
51264
51315
  cancelEdition() {
@@ -51552,7 +51603,7 @@
51552
51603
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51553
51604
  }
51554
51605
  onSheetMouseDown(sheetId, event) {
51555
- if (event.button !== 0)
51606
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51556
51607
  return;
51557
51608
  this.closeMenu();
51558
51609
  const visibleSheets = this.getVisibleSheets();
@@ -55057,7 +55108,7 @@
55057
55108
  }
55058
55109
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55059
55110
  const colors = new ChartColors();
55060
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55111
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55061
55112
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55062
55113
  const dataSetsNodes = [];
55063
55114
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -55195,8 +55246,7 @@
55195
55246
  attrs.push(["t", "b"]);
55196
55247
  }
55197
55248
  else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
55198
- const { id } = pushElement(content, sharedStrings);
55199
- value = id.toString();
55249
+ value = pushElement(content, sharedStrings);
55200
55250
  attrs.push(["t", "s"]);
55201
55251
  }
55202
55252
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -55321,8 +55371,7 @@
55321
55371
  if (rule.style.fillColor) {
55322
55372
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
55323
55373
  }
55324
- const { id } = pushElement(dxf, dxfs);
55325
- ruleAttributes.push(["dxfId", id]);
55374
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
55326
55375
  return escapeXml /*xml*/ `
55327
55376
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
55328
55377
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -56131,7 +56180,7 @@
56131
56180
  */
56132
56181
  function getXLSX(data) {
56133
56182
  const files = [];
56134
- const construct = getDefaultXLSXStructure();
56183
+ const construct = getDefaultXLSXStructure(data);
56135
56184
  files.push(createWorkbook(data, construct));
56136
56185
  files.push(...createWorksheets(data, construct));
56137
56186
  files.push(createStylesSheet(construct));
@@ -57011,9 +57060,9 @@
57011
57060
  exports.tokenize = tokenize;
57012
57061
 
57013
57062
 
57014
- __info__.version = "17.0.16";
57015
- __info__.date = "2024-03-25T09:42:01.717Z";
57016
- __info__.hash = "9b128f8";
57063
+ __info__.version = "17.0.18";
57064
+ __info__.date = "2024-04-10T13:28:23.664Z";
57065
+ __info__.hash = "6294758";
57017
57066
 
57018
57067
 
57019
57068
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);