@odoo/o-spreadsheet 16.2.3 → 16.2.4

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.
@@ -1005,6 +1005,10 @@
1005
1005
  }
1006
1006
  return true;
1007
1007
  }
1008
+ /** Check if the given array contains all the values of the other array. */
1009
+ function includesAll(arr, values) {
1010
+ return values.every((value) => arr.includes(value));
1011
+ }
1008
1012
  /**
1009
1013
  * Return an object with all the keys in the object that have a falsy value removed.
1010
1014
  */
@@ -1678,12 +1682,77 @@
1678
1682
  * - all digit stored in the decimal part of the number
1679
1683
  *
1680
1684
  * The 'maxDecimal' parameter allows to indicate the number of digits to not
1681
- * exceed in the decimal part, in which case digits are rounded
1685
+ * exceed in the decimal part, in which case digits are rounded.
1682
1686
  *
1683
- * Intl.Numberformat is used to properly handle all the roundings.
1684
- * e.g. 1234.7 with format ### (<> maxDecimals=0) should become 1235, not 1234
1685
1687
  **/
1686
1688
  function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
1689
+ const asString = value.toString();
1690
+ if (asString.includes("e"))
1691
+ return splitNumberIntl(value, maxDecimals);
1692
+ if (Number.isInteger(value)) {
1693
+ return { integerDigits: asString, decimalDigits: undefined };
1694
+ }
1695
+ const indexOfDot = asString.indexOf(".");
1696
+ let integerDigits = asString.substring(0, indexOfDot);
1697
+ let decimalDigits = asString.substring(indexOfDot + 1);
1698
+ if (maxDecimals === 0) {
1699
+ if (Number(decimalDigits[0]) >= 5) {
1700
+ integerDigits = (Number(integerDigits) + 1).toString();
1701
+ }
1702
+ return { integerDigits, decimalDigits: undefined };
1703
+ }
1704
+ if (decimalDigits.length > maxDecimals) {
1705
+ const { integerDigits: roundedIntegerDigits, decimalDigits: roundedDecimalDigits } = limitDecimalDigits(decimalDigits, maxDecimals);
1706
+ decimalDigits = roundedDecimalDigits;
1707
+ if (roundedIntegerDigits !== "0") {
1708
+ integerDigits = (Number(integerDigits) + Number(roundedIntegerDigits)).toString();
1709
+ }
1710
+ }
1711
+ return { integerDigits, decimalDigits: removeTrailingZeroes(decimalDigits || "") };
1712
+ }
1713
+ /**
1714
+ * Return the given string minus the trailing "0" characters.
1715
+ *
1716
+ * @param numberString : a string of integers
1717
+ * @returns the numberString, minus the eventual zeroes at the end
1718
+ */
1719
+ function removeTrailingZeroes(numberString) {
1720
+ let i = numberString.length - 1;
1721
+ while (i >= 0 && numberString[i] === "0") {
1722
+ i--;
1723
+ }
1724
+ return numberString.slice(0, i + 1) || undefined;
1725
+ }
1726
+ /**
1727
+ * Limit the size of the decimal part of a number to the given number of digits.
1728
+ */
1729
+ function limitDecimalDigits(decimalDigits, maxDecimals) {
1730
+ let integerDigits = "0";
1731
+ let resultDecimalDigits = decimalDigits;
1732
+ // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1733
+ // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1734
+ let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1735
+ const i = maxDecimals;
1736
+ if (Number(Number(decimalDigits[i]) < 5)) {
1737
+ return { integerDigits, decimalDigits: slicedDecimalDigits };
1738
+ }
1739
+ // round up
1740
+ const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1741
+ if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1742
+ integerDigits = (Number(integerDigits) + 1).toString();
1743
+ resultDecimalDigits = undefined;
1744
+ }
1745
+ else {
1746
+ resultDecimalDigits = slicedRoundedUp;
1747
+ }
1748
+ return { integerDigits, decimalDigits: resultDecimalDigits };
1749
+ }
1750
+ /**
1751
+ * Split numbers into decimal/integer digits using Intl.NumberFormat.
1752
+ * Supports numbers with a lot of digits that are transformed to scientific notation by
1753
+ * number.toString(), but is slow.
1754
+ */
1755
+ function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
1687
1756
  let formatter = numberRepresentation[maxDecimals];
1688
1757
  if (!formatter) {
1689
1758
  formatter = new Intl.NumberFormat("en-US", {
@@ -9132,6 +9201,11 @@
9132
9201
  name: REMOVE_COLUMNS_NAME,
9133
9202
  sequence: 90,
9134
9203
  action: REMOVE_COLUMNS_ACTION,
9204
+ isVisible: (env) => {
9205
+ const sheetId = env.model.getters.getActiveSheetId();
9206
+ const selectedCols = env.model.getters.getElementsFromSelection("COL");
9207
+ return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
9208
+ },
9135
9209
  })
9136
9210
  .add("clear_column", {
9137
9211
  name: DELETE_CONTENT_COLUMNS_NAME,
@@ -9144,9 +9218,8 @@
9144
9218
  action: HIDE_COLUMNS_ACTION,
9145
9219
  isVisible: (env) => {
9146
9220
  const sheetId = env.model.getters.getActiveSheetId();
9147
- const hiddenCols = env.model.getters.getHiddenColsGroups(sheetId).flat();
9148
- return (env.model.getters.getNumberCols(sheetId) >
9149
- hiddenCols.length + env.model.getters.getElementsFromSelection("COL").length);
9221
+ const selectedCols = env.model.getters.getElementsFromSelection("COL");
9222
+ return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
9150
9223
  },
9151
9224
  separator: true,
9152
9225
  })
@@ -9220,6 +9293,11 @@
9220
9293
  name: REMOVE_ROWS_NAME,
9221
9294
  sequence: 70,
9222
9295
  action: REMOVE_ROWS_ACTION,
9296
+ isVisible: (env) => {
9297
+ const sheetId = env.model.getters.getActiveSheetId();
9298
+ const selectedRows = env.model.getters.getElementsFromSelection("ROW");
9299
+ return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
9300
+ },
9223
9301
  })
9224
9302
  .add("clear_row", {
9225
9303
  name: DELETE_CONTENT_ROWS_NAME,
@@ -9232,9 +9310,8 @@
9232
9310
  action: HIDE_ROWS_ACTION,
9233
9311
  isVisible: (env) => {
9234
9312
  const sheetId = env.model.getters.getActiveSheetId();
9235
- const hiddenRows = env.model.getters.getHiddenRowsGroups(sheetId).flat();
9236
- return (env.model.getters.getNumberRows(sheetId) >
9237
- hiddenRows.length + env.model.getters.getElementsFromSelection("ROW").length);
9313
+ const selectedRows = env.model.getters.getElementsFromSelection("ROW");
9314
+ return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
9238
9315
  },
9239
9316
  separator: true,
9240
9317
  })
@@ -21970,8 +22047,8 @@
21970
22047
  },
21971
22048
  "CTRL+END": () => {
21972
22049
  const sheetId = this.env.model.getters.getActiveSheetId();
21973
- const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", range(0, this.env.model.getters.getNumberCols(sheetId)).reverse());
21974
- const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", range(0, this.env.model.getters.getNumberRows(sheetId)).reverse());
22050
+ const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", this.env.model.getters.getNumberCols(sheetId) - 1, 0);
22051
+ const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", this.env.model.getters.getNumberRows(sheetId) - 1, 0);
21975
22052
  this.env.model.selection.selectCell(col, row);
21976
22053
  },
21977
22054
  "SHIFT+ ": () => {
@@ -22051,9 +22128,10 @@
22051
22128
  this.focus();
22052
22129
  }
22053
22130
  focus() {
22131
+ var _a;
22054
22132
  if (!this.env.model.getters.getSelectedFigureId() &&
22055
22133
  this.env.model.getters.getEditionMode() === "inactive") {
22056
- this.hiddenInput.el.focus();
22134
+ (_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
22057
22135
  }
22058
22136
  }
22059
22137
  get gridEl() {
@@ -25948,7 +26026,7 @@
25948
26026
  }
25949
26027
  }
25950
26028
  }
25951
- data = JSON.parse(JSON.stringify(data));
26029
+ data = deepCopy(data);
25952
26030
  // apply migrations, if needed
25953
26031
  if ("version" in data) {
25954
26032
  if (data.version < CURRENT_VERSION) {
@@ -29391,7 +29469,7 @@
29391
29469
  allowDispatch(cmd) {
29392
29470
  switch (cmd.type) {
29393
29471
  case "HIDE_COLUMNS_ROWS": {
29394
- if (!this.hiddenHeaders[cmd.sheetId]) {
29472
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
29395
29473
  return 27 /* CommandResult.InvalidSheetId */;
29396
29474
  }
29397
29475
  const hiddenGroup = cmd.dimension === "COL"
@@ -29404,6 +29482,14 @@
29404
29482
  ? 0 /* CommandResult.Success */
29405
29483
  : 66 /* CommandResult.TooManyHiddenElements */;
29406
29484
  }
29485
+ case "REMOVE_COLUMNS_ROWS":
29486
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
29487
+ return 27 /* CommandResult.InvalidSheetId */;
29488
+ }
29489
+ if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
29490
+ return 8 /* CommandResult.NotEnoughElements */;
29491
+ }
29492
+ return 0 /* CommandResult.Success */;
29407
29493
  }
29408
29494
  return 0 /* CommandResult.Success */;
29409
29495
  }
@@ -29450,6 +29536,10 @@
29450
29536
  }
29451
29537
  return;
29452
29538
  }
29539
+ canRemoveHeaders(sheetId, dimension, elements) {
29540
+ const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
29541
+ return !includesAll(elements, visibleHeaders);
29542
+ }
29453
29543
  isRowHiddenByUser(sheetId, index) {
29454
29544
  return this.hiddenHeaders[sheetId].ROW[index];
29455
29545
  }
@@ -29494,6 +29584,9 @@
29494
29584
  }
29495
29585
  return consecutiveIndexes;
29496
29586
  }
29587
+ getAllVisibleHeaders(sheetId, dimension) {
29588
+ return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
29589
+ }
29497
29590
  import(data) {
29498
29591
  var _a, _b;
29499
29592
  for (let sheet of data.sheets) {
@@ -29541,6 +29634,7 @@
29541
29634
  }
29542
29635
  }
29543
29636
  HeaderVisibilityPlugin.getters = [
29637
+ "canRemoveHeaders",
29544
29638
  "getHiddenColsGroups",
29545
29639
  "getHiddenRowsGroups",
29546
29640
  "isRowHiddenByUser",
@@ -30559,14 +30653,6 @@
30559
30653
  return this.orderedSheetIds.length > 1
30560
30654
  ? 0 /* CommandResult.Success */
30561
30655
  : 9 /* CommandResult.NotEnoughSheets */;
30562
- case "REMOVE_COLUMNS_ROWS": {
30563
- const length = cmd.dimension === "COL"
30564
- ? this.getNumberCols(cmd.sheetId)
30565
- : this.getNumberRows(cmd.sheetId);
30566
- return length > cmd.elements.length
30567
- ? 0 /* CommandResult.Success */
30568
- : 8 /* CommandResult.NotEnoughElements */;
30569
- }
30570
30656
  case "FREEZE_ROWS": {
30571
30657
  return this.checkValidations(cmd, this.checkRowFreezeQuantity, this.checkRowFreezeOverlapMerge);
30572
30658
  }
@@ -31033,7 +31119,7 @@
31033
31119
  duplicateSheet(fromId, toId) {
31034
31120
  const sheet = this.getSheet(fromId);
31035
31121
  const toName = this.getDuplicateSheetName(sheet.name);
31036
- const newSheet = JSON.parse(JSON.stringify(sheet));
31122
+ const newSheet = deepCopy(sheet);
31037
31123
  newSheet.id = toId;
31038
31124
  newSheet.name = toName;
31039
31125
  for (let col = 0; col <= newSheet.numberOfCols; col++) {
@@ -31160,10 +31246,10 @@
31160
31246
  }
31161
31247
  }
31162
31248
  moveCellOnColumnsDeletion(sheet, deletedColumn) {
31163
- for (let [index, row] of Object.entries(sheet.rows)) {
31164
- const rowIndex = parseInt(index, 10);
31249
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
31250
+ const row = sheet.rows[rowIndex];
31165
31251
  for (let i in row.cells) {
31166
- const colIndex = parseInt(i, 10);
31252
+ const colIndex = Number(i);
31167
31253
  const cellId = row.cells[i];
31168
31254
  if (cellId) {
31169
31255
  if (colIndex === deletedColumn) {
@@ -31190,11 +31276,11 @@
31190
31276
  */
31191
31277
  moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
31192
31278
  const commands = [];
31193
- for (const [index, row] of Object.entries(sheet.rows)) {
31194
- const rowIndex = parseInt(index, 10);
31279
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
31280
+ const row = sheet.rows[rowIndex];
31195
31281
  if (dimension !== "rows" || rowIndex >= addedElement) {
31196
31282
  for (let i in row.cells) {
31197
- const colIndex = parseInt(i, 10);
31283
+ const colIndex = Number(i);
31198
31284
  const cellId = row.cells[i];
31199
31285
  if (cellId) {
31200
31286
  if (dimension === "rows" || colIndex >= addedElement) {
@@ -31224,11 +31310,11 @@
31224
31310
  */
31225
31311
  moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
31226
31312
  const numberRows = deleteToRow - deleteFromRow + 1;
31227
- for (let [index, row] of Object.entries(sheet.rows)) {
31228
- const rowIndex = parseInt(index, 10);
31313
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
31314
+ const row = sheet.rows[rowIndex];
31229
31315
  if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
31230
31316
  for (let i in row.cells) {
31231
- const colIndex = parseInt(i, 10);
31317
+ const colIndex = Number(i);
31232
31318
  const cellId = row.cells[i];
31233
31319
  if (cellId) {
31234
31320
  this.dispatch("CLEAR_CELL", {
@@ -31241,7 +31327,7 @@
31241
31327
  }
31242
31328
  if (rowIndex > deleteToRow) {
31243
31329
  for (let i in row.cells) {
31244
- const colIndex = parseInt(i, 10);
31330
+ const colIndex = Number(i);
31245
31331
  const cellId = row.cells[i];
31246
31332
  if (cellId) {
31247
31333
  this.dispatch("UPDATE_CELL_POSITION", {
@@ -31259,7 +31345,7 @@
31259
31345
  const rows = [];
31260
31346
  const cellsQueue = sheet.rows.map((row) => row.cells);
31261
31347
  for (let i in sheet.rows) {
31262
- if (parseInt(i, 10) === index) {
31348
+ if (Number(i) === index) {
31263
31349
  continue;
31264
31350
  }
31265
31351
  rows.push({
@@ -32430,13 +32516,11 @@
32430
32516
  return Boolean(id && ((_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.length));
32431
32517
  }
32432
32518
  intersectZoneWithViewport(sheetId, zone) {
32433
- const colsRange = range(zone.left, zone.right + 1);
32434
- const rowsRange = range(zone.top, zone.bottom + 1);
32435
32519
  return {
32436
- left: this.getters.findVisibleHeader(sheetId, "COL", colsRange),
32437
- right: this.getters.findVisibleHeader(sheetId, "COL", colsRange.reverse()),
32438
- top: this.getters.findVisibleHeader(sheetId, "ROW", rowsRange),
32439
- bottom: this.getters.findVisibleHeader(sheetId, "ROW", rowsRange.reverse()),
32520
+ left: this.getters.findVisibleHeader(sheetId, "COL", zone.left, zone.right),
32521
+ right: this.getters.findVisibleHeader(sheetId, "COL", zone.right, zone.left),
32522
+ top: this.getters.findVisibleHeader(sheetId, "ROW", zone.top, zone.bottom),
32523
+ bottom: this.getters.findVisibleHeader(sheetId, "ROW", zone.bottom, zone.top),
32440
32524
  };
32441
32525
  }
32442
32526
  updateFilter({ col, row, values, sheetId }) {
@@ -34543,13 +34627,33 @@
34543
34627
  getNextVisibleCellPosition({ sheetId, col, row }) {
34544
34628
  return {
34545
34629
  sheetId,
34546
- col: this.findVisibleHeader(sheetId, "COL", range(col, this.getters.getNumberCols(sheetId))),
34547
- row: this.findVisibleHeader(sheetId, "ROW", range(row, this.getters.getNumberRows(sheetId))),
34630
+ col: this.findVisibleHeader(sheetId, "COL", col, this.getters.getNumberCols(sheetId) - 1),
34631
+ row: this.findVisibleHeader(sheetId, "ROW", row, this.getters.getNumberRows(sheetId) - 1),
34548
34632
  };
34549
34633
  }
34550
- findVisibleHeader(sheetId, dimension, indexes) {
34551
- return indexes.find((index) => this.getters.doesHeaderExist(sheetId, dimension, index) &&
34552
- !this.isHeaderHidden(sheetId, dimension, index));
34634
+ /**
34635
+ * Find the first visible header in the range [`from` => `to`].
34636
+ *
34637
+ * Both `from` and `to` are inclusive.
34638
+ */
34639
+ findVisibleHeader(sheetId, dimension, from, to) {
34640
+ if (from <= to) {
34641
+ for (let i = from; i <= to; i++) {
34642
+ if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
34643
+ !this.isHeaderHidden(sheetId, dimension, i)) {
34644
+ return i;
34645
+ }
34646
+ }
34647
+ }
34648
+ if (from > to) {
34649
+ for (let i = from; i >= to; i--) {
34650
+ if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
34651
+ !this.isHeaderHidden(sheetId, dimension, i)) {
34652
+ return i;
34653
+ }
34654
+ }
34655
+ }
34656
+ return undefined;
34553
34657
  }
34554
34658
  findLastVisibleColRowIndex(sheetId, dimension, { last, first }) {
34555
34659
  const lastVisibleIndex = range(last, first, -1).find((index) => !this.isHeaderHidden(sheetId, dimension, index));
@@ -34557,7 +34661,7 @@
34557
34661
  }
34558
34662
  findFirstVisibleColRowIndex(sheetId, dimension) {
34559
34663
  const numberOfHeaders = this.getters.getNumberHeaders(sheetId, dimension);
34560
- for (let i = 0; i < numberOfHeaders - 1; i++) {
34664
+ for (let i = 0; i < numberOfHeaders; i++) {
34561
34665
  if (dimension === "COL" && !this.isColHidden(sheetId, i)) {
34562
34666
  return i;
34563
34667
  }
@@ -42761,8 +42865,8 @@
42761
42865
  }
42762
42866
  const { left, right, top, bottom } = zone;
42763
42867
  const sheetId = this.getters.getActiveSheetId();
42764
- const refCol = this.getters.findVisibleHeader(sheetId, "COL", range(left, right + 1));
42765
- const refRow = this.getters.findVisibleHeader(sheetId, "ROW", range(top, bottom + 1));
42868
+ const refCol = this.getters.findVisibleHeader(sheetId, "COL", left, right);
42869
+ const refRow = this.getters.findVisibleHeader(sheetId, "ROW", top, bottom);
42766
42870
  if (refRow === undefined || refCol === undefined) {
42767
42871
  return 17 /* CommandResult.SelectionOutOfBound */;
42768
42872
  }
@@ -42837,10 +42941,10 @@
42837
42941
  const { col: anchorCol, row: anchorRow } = anchor.cell;
42838
42942
  return {
42839
42943
  col: this.getters.isColHidden(sheetId, anchorCol)
42840
- ? this.getters.findVisibleHeader(sheetId, "COL", range(left, right + 1)) || anchorCol
42944
+ ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
42841
42945
  : anchorCol,
42842
42946
  row: this.getters.isRowHidden(sheetId, anchorRow)
42843
- ? this.getters.findVisibleHeader(sheetId, "ROW", range(top, bottom + 1)) || anchorRow
42947
+ ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
42844
42948
  : anchorRow,
42845
42949
  };
42846
42950
  }
@@ -44590,6 +44694,8 @@
44590
44694
  * Internal status of the model. Important for command handling coordination
44591
44695
  */
44592
44696
  this.status = 0 /* Status.Ready */;
44697
+ this.handlers = [];
44698
+ this.coreHandlers = [];
44593
44699
  /**
44594
44700
  * The dispatch method is the only entry point to manipulate data in the model.
44595
44701
  * This is through this method that commands are dispatched most of the time
@@ -44694,6 +44800,8 @@
44694
44800
  this.uuidGenerator.setIsFastStrategy(true);
44695
44801
  // Initiate stream processor
44696
44802
  this.selection = new SelectionStreamProcessorImpl(this.getters);
44803
+ this.coreHandlers.push(this.range);
44804
+ this.handlers.push(this.range);
44697
44805
  this.corePluginConfig = this.setupCorePluginConfig();
44698
44806
  this.uiPluginConfig = this.setupUiPluginConfig();
44699
44807
  // registering plugins
@@ -44702,15 +44810,23 @@
44702
44810
  }
44703
44811
  Object.assign(this.getters, this.coreGetters);
44704
44812
  for (let Plugin of statefulUIPluginRegistry.getAll()) {
44705
- this.statefulUIPlugins.push(this.setupUiPlugin(Plugin));
44813
+ const plugin = this.setupUiPlugin(Plugin);
44814
+ this.statefulUIPlugins.push(plugin);
44815
+ this.handlers.push(plugin);
44706
44816
  }
44707
44817
  for (let Plugin of coreViewsPluginRegistry.getAll()) {
44708
- this.coreViewsPlugins.push(this.setupUiPlugin(Plugin));
44818
+ const plugin = this.setupUiPlugin(Plugin);
44819
+ this.coreViewsPlugins.push(plugin);
44820
+ this.handlers.push(plugin);
44821
+ this.coreHandlers.push(plugin);
44709
44822
  }
44710
44823
  for (let Plugin of featurePluginRegistry.getAll()) {
44711
- this.featurePlugins.push(this.setupUiPlugin(Plugin));
44824
+ const plugin = this.setupUiPlugin(Plugin);
44825
+ this.featurePlugins.push(plugin);
44826
+ this.handlers.push(plugin);
44712
44827
  }
44713
44828
  this.uuidGenerator.setIsFastStrategy(false);
44829
+ this.handlers.push(this.history);
44714
44830
  // starting plugins
44715
44831
  this.dispatch("START");
44716
44832
  // Model should be the last permanent subscriber in the list since he should render
@@ -44732,12 +44848,6 @@
44732
44848
  // by owl, since we do not rely on reactivity
44733
44849
  owl.markRaw(this);
44734
44850
  }
44735
- get handlers() {
44736
- return [this.range, ...this.corePlugins, ...this.allUIPlugins, this.history];
44737
- }
44738
- get allUIPlugins() {
44739
- return [...this.statefulUIPlugins, ...this.coreViewsPlugins, ...this.featurePlugins];
44740
- }
44741
44851
  joinSession() {
44742
44852
  this.session.join(this.config.client);
44743
44853
  }
@@ -44779,6 +44889,8 @@
44779
44889
  }
44780
44890
  plugin.import(data);
44781
44891
  this.corePlugins.push(plugin);
44892
+ this.coreHandlers.push(plugin);
44893
+ this.handlers.push(plugin);
44782
44894
  }
44783
44895
  onRemoteRevisionReceived({ commands }) {
44784
44896
  for (let command of commands) {
@@ -44921,7 +45033,7 @@
44921
45033
  }
44922
45034
  }
44923
45035
  data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
44924
- data = JSON.parse(JSON.stringify(data));
45036
+ data = deepCopy(data);
44925
45037
  return data;
44926
45038
  }
44927
45039
  updateMode(mode) {
@@ -44949,7 +45061,7 @@
44949
45061
  handler.exportForExcel(data);
44950
45062
  }
44951
45063
  }
44952
- data = JSON.parse(JSON.stringify(data));
45064
+ data = deepCopy(data);
44953
45065
  return getXLSX(data);
44954
45066
  }
44955
45067
  garbageCollectExternalResources() {
@@ -45091,9 +45203,9 @@
45091
45203
  Object.defineProperty(exports, '__esModule', { value: true });
45092
45204
 
45093
45205
 
45094
- __info__.version = '16.2.3';
45095
- __info__.date = '2023-04-14T12:47:50.453Z';
45096
- __info__.hash = '4514375';
45206
+ __info__.version = '16.2.4';
45207
+ __info__.date = '2023-04-21T07:30:02.765Z';
45208
+ __info__.hash = '7169d69';
45097
45209
 
45098
45210
 
45099
45211
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);