@odoo/o-spreadsheet 18.2.0-alpha.8 → 18.2.1

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 18.2.0-alpha.8
6
- * @date 2025-02-14T08:40:13.286Z
7
- * @hash 19d45d9
5
+ * @version 18.2.1
6
+ * @date 2025-02-25T06:03:13.262Z
7
+ * @hash 3b4b5c9
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2230,17 +2230,7 @@
2230
2230
  */
2231
2231
  function toUnboundedZone(xc) {
2232
2232
  const zone = toZoneWithoutBoundaryChanges(xc);
2233
- if (zone.right !== undefined && zone.right < zone.left) {
2234
- const tmp = zone.left;
2235
- zone.left = zone.right;
2236
- zone.right = tmp;
2237
- }
2238
- if (zone.bottom !== undefined && zone.bottom < zone.top) {
2239
- const tmp = zone.top;
2240
- zone.top = zone.bottom;
2241
- zone.bottom = tmp;
2242
- }
2243
- return zone;
2233
+ return reorderZone(zone);
2244
2234
  }
2245
2235
  /**
2246
2236
  * Convert from a cartesian reference to a Zone.
@@ -2514,11 +2504,11 @@
2514
2504
  return positions;
2515
2505
  }
2516
2506
  function reorderZone(zone) {
2517
- if (zone.left > zone.right) {
2518
- zone = { left: zone.right, right: zone.left, top: zone.top, bottom: zone.bottom };
2507
+ if (zone.right !== undefined && zone.left > zone.right) {
2508
+ zone = { ...zone, left: zone.right, right: zone.left };
2519
2509
  }
2520
- if (zone.top > zone.bottom) {
2521
- zone = { left: zone.left, right: zone.right, top: zone.bottom, bottom: zone.top };
2510
+ if (zone.bottom !== undefined && zone.top > zone.bottom) {
2511
+ zone = { ...zone, top: zone.bottom, bottom: zone.top };
2522
2512
  }
2523
2513
  return zone;
2524
2514
  }
@@ -3423,12 +3413,12 @@
3423
3413
  function isRangeDependant(cmd) {
3424
3414
  return "ranges" in cmd;
3425
3415
  }
3426
- function isZoneDependent(cmd) {
3427
- return "zone" in cmd;
3428
- }
3429
3416
  function isPositionDependent(cmd) {
3430
3417
  return "col" in cmd && "row" in cmd && "sheetId" in cmd;
3431
3418
  }
3419
+ function isZoneDependent(cmd) {
3420
+ return "sheetId" in cmd && "zone" in cmd;
3421
+ }
3432
3422
  const invalidateEvaluationCommands = new Set([
3433
3423
  "RENAME_SHEET",
3434
3424
  "DELETE_SHEET",
@@ -3440,6 +3430,7 @@
3440
3430
  "REDO",
3441
3431
  "ADD_MERGE",
3442
3432
  "REMOVE_MERGE",
3433
+ "DUPLICATE_SHEET",
3443
3434
  "UPDATE_LOCALE",
3444
3435
  "ADD_PIVOT",
3445
3436
  "UPDATE_PIVOT",
@@ -3469,7 +3460,6 @@
3469
3460
  ]);
3470
3461
  const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
3471
3462
  const invalidateCFEvaluationCommands = new Set([
3472
- "DUPLICATE_SHEET",
3473
3463
  "EVALUATE_CELLS",
3474
3464
  "ADD_CONDITIONAL_FORMAT",
3475
3465
  "REMOVE_CONDITIONAL_FORMAT",
@@ -3639,6 +3629,7 @@
3639
3629
  CommandResult["InvalidRange"] = "InvalidRange";
3640
3630
  CommandResult["InvalidZones"] = "InvalidZones";
3641
3631
  CommandResult["InvalidSheetId"] = "InvalidSheetId";
3632
+ CommandResult["InvalidCellId"] = "InvalidCellId";
3642
3633
  CommandResult["InvalidFigureId"] = "InvalidFigureId";
3643
3634
  CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
3644
3635
  CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
@@ -4468,7 +4459,7 @@
4468
4459
  * @param reverseSearch if true, search in the array starting from the end.
4469
4460
 
4470
4461
  */
4471
- function linearSearch(data, target, mode, numberOfValues, getValueInData, reverseSearch = false) {
4462
+ function linearSearch(data, target, mode, numberOfValues, getValueInData, lookupCaches, reverseSearch = false) {
4472
4463
  if (target === undefined || target.value === null) {
4473
4464
  return -1;
4474
4465
  }
@@ -4477,17 +4468,48 @@
4477
4468
  }
4478
4469
  const _target = normalizeValue(target.value);
4479
4470
  const getValue = reverseSearch
4480
- ? (data, i) => getValueInData(data, numberOfValues - i - 1)
4481
- : getValueInData;
4471
+ ? (data, i) => normalizeValue(getValueInData(data, numberOfValues - i - 1))
4472
+ : (data, i) => normalizeValue(getValueInData(data, i));
4473
+ // first check if the target is in the cache
4474
+ const isNotWildcardTarget = mode !== "wildcard" ||
4475
+ typeof _target !== "string" ||
4476
+ !(_target.includes("*") || _target.includes("?"));
4477
+ if (lookupCaches && isNotWildcardTarget) {
4478
+ const searchMode = reverseSearch ? "reverseSearch" : "forwardSearch";
4479
+ let cache = lookupCaches[searchMode].get(data);
4480
+ if (cache === undefined) {
4481
+ // build the cache for all the values
4482
+ cache = new Map();
4483
+ for (let i = 0; i < numberOfValues; i++) {
4484
+ const value = getValue(data, i) ?? null;
4485
+ if (!cache.has(value)) {
4486
+ cache.set(value, i);
4487
+ }
4488
+ }
4489
+ lookupCaches[searchMode].set(data, cache);
4490
+ }
4491
+ if (cache.has(_target)) {
4492
+ const resultIndex = cache.get(_target);
4493
+ return reverseSearch ? numberOfValues - resultIndex - 1 : resultIndex;
4494
+ }
4495
+ if (mode === "strict") {
4496
+ return -1;
4497
+ }
4498
+ }
4499
+ // else perform the linear search
4500
+ const resultIndex = _linearSearch(data, _target, mode, numberOfValues, getValue);
4501
+ return reverseSearch && resultIndex !== -1 ? numberOfValues - resultIndex - 1 : resultIndex;
4502
+ }
4503
+ function _linearSearch(data, _target, mode, numberOfValues, getNormalizeValue) {
4482
4504
  let indexMatchTarget = (i) => {
4483
- return normalizeValue(getValue(data, i)) === _target;
4505
+ return getNormalizeValue(data, i) === _target;
4484
4506
  };
4485
4507
  if (mode === "wildcard" &&
4486
4508
  typeof _target === "string" &&
4487
4509
  (_target.includes("*") || _target.includes("?"))) {
4488
4510
  const regExp = wildcardToRegExp(_target);
4489
4511
  indexMatchTarget = (i) => {
4490
- const value = normalizeValue(getValue(data, i));
4512
+ const value = getNormalizeValue(data, i);
4491
4513
  if (typeof value === "string") {
4492
4514
  return regExp.test(value);
4493
4515
  }
@@ -4498,7 +4520,7 @@
4498
4520
  let closestMatchIndex = -1;
4499
4521
  if (mode === "nextSmaller") {
4500
4522
  indexMatchTarget = (i) => {
4501
- const value = normalizeValue(getValue(data, i));
4523
+ const value = getNormalizeValue(data, i);
4502
4524
  if ((!closestMatch && compareCellValues(_target, value) >= 0) ||
4503
4525
  (compareCellValues(_target, value) >= 0 && compareCellValues(value, closestMatch) > 0)) {
4504
4526
  closestMatch = value;
@@ -4509,7 +4531,7 @@
4509
4531
  }
4510
4532
  if (mode === "nextGreater") {
4511
4533
  indexMatchTarget = (i) => {
4512
- const value = normalizeValue(getValue(data, i));
4534
+ const value = getNormalizeValue(data, i);
4513
4535
  if ((!closestMatch && compareCellValues(_target, value) <= 0) ||
4514
4536
  (compareCellValues(_target, value) <= 0 && compareCellValues(value, closestMatch) < 0)) {
4515
4537
  closestMatch = value;
@@ -4520,12 +4542,10 @@
4520
4542
  }
4521
4543
  for (let i = 0; i < numberOfValues; i++) {
4522
4544
  if (indexMatchTarget(i)) {
4523
- return reverseSearch ? numberOfValues - i - 1 : i;
4545
+ return i;
4524
4546
  }
4525
4547
  }
4526
- return reverseSearch && closestMatchIndex !== -1
4527
- ? numberOfValues - closestMatchIndex - 1
4528
- : closestMatchIndex;
4548
+ return closestMatchIndex;
4529
4549
  }
4530
4550
  /**
4531
4551
  * Normalize a value.
@@ -6499,10 +6519,11 @@
6499
6519
  *
6500
6520
  */
6501
6521
  smallUuid() {
6502
- //@ts-ignore
6503
- if (window.crypto && window.crypto.getRandomValues) {
6504
- //@ts-ignore
6505
- return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6522
+ if (window.crypto) {
6523
+ return "10000000-1000".replace(/[01]/g, (c) => {
6524
+ const n = Number(c);
6525
+ return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
6526
+ });
6506
6527
  }
6507
6528
  else {
6508
6529
  // mainly for jest and other browsers that do not have the crypto functionality
@@ -6517,10 +6538,11 @@
6517
6538
  * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
6518
6539
  */
6519
6540
  uuidv4() {
6520
- //@ts-ignore
6521
- if (window.crypto && window.crypto.getRandomValues) {
6522
- //@ts-ignore
6523
- return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6541
+ if (window.crypto) {
6542
+ return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
6543
+ const n = Number(c);
6544
+ return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
6545
+ });
6524
6546
  }
6525
6547
  else {
6526
6548
  // mainly for jest and other browsers that do not have the crypto functionality
@@ -12237,6 +12259,25 @@ stores.inject(MyMetaStore, storeInstance);
12237
12259
  isExported: true,
12238
12260
  };
12239
12261
  // -----------------------------------------------------------------------------
12262
+ // LOG
12263
+ // -----------------------------------------------------------------------------
12264
+ const LOG = {
12265
+ description: _t("The logarithm of a number, for a given base."),
12266
+ args: [
12267
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
12268
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
12269
+ ],
12270
+ compute: function (value, base = { value: 10 }) {
12271
+ const _value = toNumber(value, this.locale);
12272
+ const _base = toNumber(base, this.locale);
12273
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
12274
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
12275
+ assert(() => _base !== 1, _t("The base must be different from 1."));
12276
+ return Math.log10(_value) / Math.log10(_base);
12277
+ },
12278
+ isExported: true,
12279
+ };
12280
+ // -----------------------------------------------------------------------------
12240
12281
  // MOD
12241
12282
  // -----------------------------------------------------------------------------
12242
12283
  function mod(dividend, divisor) {
@@ -12776,6 +12817,7 @@ stores.inject(MyMetaStore, storeInstance);
12776
12817
  ISODD: ISODD,
12777
12818
  ISO_CEILING: ISO_CEILING,
12778
12819
  LN: LN,
12820
+ LOG: LOG,
12779
12821
  MOD: MOD,
12780
12822
  MUNIT: MUNIT,
12781
12823
  ODD: ODD,
@@ -18674,7 +18716,7 @@ stores.inject(MyMetaStore, storeInstance);
18674
18716
  const _isSorted = toBoolean(isSorted.value);
18675
18717
  const colIndex = _isSorted
18676
18718
  ? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
18677
- : linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
18719
+ : linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
18678
18720
  const col = _range[colIndex];
18679
18721
  if (col === undefined) {
18680
18722
  return valueNotAvailable(searchKey);
@@ -18829,7 +18871,7 @@ stores.inject(MyMetaStore, storeInstance);
18829
18871
  index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
18830
18872
  break;
18831
18873
  case 0:
18832
- index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
18874
+ index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
18833
18875
  break;
18834
18876
  case -1:
18835
18877
  index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
@@ -18897,7 +18939,7 @@ stores.inject(MyMetaStore, storeInstance);
18897
18939
  const _isSorted = toBoolean(isSorted.value);
18898
18940
  const rowIndex = _isSorted
18899
18941
  ? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
18900
- : linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
18942
+ : linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
18901
18943
  const value = _range[_index - 1][rowIndex];
18902
18944
  if (value === undefined) {
18903
18945
  return valueNotAvailable(searchKey);
@@ -18953,7 +18995,7 @@ stores.inject(MyMetaStore, storeInstance);
18953
18995
  const reverseSearch = _searchMode === -1;
18954
18996
  const index = _searchMode === 2 || _searchMode === -2
18955
18997
  ? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18956
- : linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
18998
+ : linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
18957
18999
  if (index !== -1) {
18958
19000
  return lookupDirection === "col"
18959
19001
  ? _returnRange.map((col) => [col[index]])
@@ -28292,7 +28334,7 @@ stores.inject(MyMetaStore, storeInstance);
28292
28334
  }
28293
28335
  function getPyramidChartData(definition, dataSets, labelRange, getters) {
28294
28336
  const barChartData = getBarChartData(definition, dataSets, labelRange, getters);
28295
- const barDataset = barChartData.dataSetsValues;
28337
+ const barDataset = barChartData.dataSetsValues.filter((ds) => !ds.hidden);
28296
28338
  const pyramidDatasetValues = [];
28297
28339
  if (barDataset[0]) {
28298
28340
  const pyramidData = barDataset[0].data.map((value) => (value > 0 ? value : 0));
@@ -28769,10 +28811,8 @@ stores.inject(MyMetaStore, storeInstance);
28769
28811
  function getChartDatasetValues(getters, dataSets) {
28770
28812
  const datasetValues = [];
28771
28813
  for (const [dsIndex, ds] of Object.entries(dataSets)) {
28772
- if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
28773
- continue;
28774
- }
28775
28814
  let label;
28815
+ let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
28776
28816
  if (ds.labelCell) {
28777
28817
  const labelRange = ds.labelCell;
28778
28818
  const cell = labelRange
@@ -28799,9 +28839,9 @@ stores.inject(MyMetaStore, storeInstance);
28799
28839
  data.fill(1);
28800
28840
  }
28801
28841
  else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
28802
- continue;
28842
+ hidden = true;
28803
28843
  }
28804
- datasetValues.push({ data, label });
28844
+ datasetValues.push({ data, label, hidden });
28805
28845
  }
28806
28846
  return datasetValues;
28807
28847
  }
@@ -28812,12 +28852,13 @@ stores.inject(MyMetaStore, storeInstance);
28812
28852
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
28813
28853
  const trendDatasets = [];
28814
28854
  for (const index in dataSetsValues) {
28815
- let { label, data } = dataSetsValues[index];
28855
+ let { label, data, hidden } = dataSetsValues[index];
28816
28856
  label = definition.dataSets?.[index].label || label;
28817
28857
  const backgroundColor = colors.next();
28818
28858
  const dataset = {
28819
28859
  label,
28820
28860
  data,
28861
+ hidden,
28821
28862
  borderColor: definition.background || BACKGROUND_CHART_COLOR,
28822
28863
  borderWidth: definition.stacked ? 1 : 0,
28823
28864
  backgroundColor,
@@ -28850,6 +28891,9 @@ stores.inject(MyMetaStore, storeInstance);
28850
28891
  const labelsWithSubTotals = [];
28851
28892
  let lastValue = 0;
28852
28893
  for (const dataSetsValue of dataSetsValues) {
28894
+ if (dataSetsValue.hidden) {
28895
+ continue;
28896
+ }
28853
28897
  for (let i = 0; i < dataSetsValue.data.length; i++) {
28854
28898
  const data = dataSetsValue.data[i];
28855
28899
  labelsWithSubTotals.push(labels[i]);
@@ -28885,7 +28929,7 @@ stores.inject(MyMetaStore, storeInstance);
28885
28929
  const trendDatasets = [];
28886
28930
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
28887
28931
  for (let index = 0; index < dataSetsValues.length; index++) {
28888
- let { label, data } = dataSetsValues[index];
28932
+ let { label, data, hidden } = dataSetsValues[index];
28889
28933
  label = definition.dataSets?.[index].label || label;
28890
28934
  const color = colors.next();
28891
28935
  if (axisType && ["linear", "time"].includes(axisType)) {
@@ -28895,6 +28939,7 @@ stores.inject(MyMetaStore, storeInstance);
28895
28939
  const dataset = {
28896
28940
  label,
28897
28941
  data,
28942
+ hidden,
28898
28943
  tension: 0, // 0 -> render straight lines, which is much faster
28899
28944
  borderColor: color,
28900
28945
  backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
@@ -28927,11 +28972,13 @@ stores.inject(MyMetaStore, storeInstance);
28927
28972
  const dataSets = [];
28928
28973
  const dataSetsLength = Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0));
28929
28974
  const backgroundColor = getPieColors(new ColorGenerator(dataSetsLength), dataSetsValues);
28930
- for (const { label, data } of dataSetsValues) {
28975
+ for (const { label, data, hidden } of dataSetsValues) {
28976
+ if (hidden)
28977
+ continue;
28931
28978
  const dataset = {
28932
28979
  label,
28933
28980
  data,
28934
- borderColor: BACKGROUND_CHART_COLOR,
28981
+ borderColor: definition.background || "#FFFFFF",
28935
28982
  backgroundColor,
28936
28983
  hoverOffset: 30,
28937
28984
  };
@@ -28945,7 +28992,7 @@ stores.inject(MyMetaStore, storeInstance);
28945
28992
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
28946
28993
  const trendDatasets = [];
28947
28994
  for (let index = 0; index < dataSetsValues.length; index++) {
28948
- let { label, data } = dataSetsValues[index];
28995
+ let { label, data, hidden } = dataSetsValues[index];
28949
28996
  label = definition.dataSets?.[index].label || label;
28950
28997
  const design = definition.dataSets?.[index];
28951
28998
  const color = colors.next();
@@ -28953,6 +29000,7 @@ stores.inject(MyMetaStore, storeInstance);
28953
29000
  const dataset = {
28954
29001
  label: label,
28955
29002
  data,
29003
+ hidden,
28956
29004
  borderColor: color,
28957
29005
  backgroundColor: color,
28958
29006
  yAxisID: definition.dataSets?.[index].yAxisId || "y",
@@ -28977,7 +29025,7 @@ stores.inject(MyMetaStore, storeInstance);
28977
29025
  const fill = definition.fillArea ?? false;
28978
29026
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
28979
29027
  for (let i = 0; i < dataSetsValues.length; i++) {
28980
- let { label, data } = dataSetsValues[i];
29028
+ let { label, data, hidden } = dataSetsValues[i];
28981
29029
  if (definition.dataSets?.[i]?.label) {
28982
29030
  label = definition.dataSets[i].label;
28983
29031
  }
@@ -28985,6 +29033,7 @@ stores.inject(MyMetaStore, storeInstance);
28985
29033
  const dataset = {
28986
29034
  label,
28987
29035
  data,
29036
+ hidden,
28988
29037
  borderColor,
28989
29038
  backgroundColor: borderColor,
28990
29039
  };
@@ -29130,6 +29179,11 @@ stores.inject(MyMetaStore, storeInstance);
29130
29179
  hidden: false,
29131
29180
  lineWidth: 2,
29132
29181
  })),
29182
+ filter: (legendItem, data) => {
29183
+ return "datasetIndex" in legendItem
29184
+ ? !data.datasets[legendItem.datasetIndex].hidden
29185
+ : true;
29186
+ },
29133
29187
  },
29134
29188
  };
29135
29189
  }
@@ -29191,6 +29245,11 @@ stores.inject(MyMetaStore, storeInstance);
29191
29245
  }
29192
29246
  return legendValues;
29193
29247
  },
29248
+ filter: (legendItem, data) => {
29249
+ return "datasetIndex" in legendItem
29250
+ ? !data.datasets[legendItem.datasetIndex].hidden
29251
+ : true;
29252
+ },
29194
29253
  },
29195
29254
  onClick: () => { }, // Disables click interaction with the waterfall chart legend items
29196
29255
  };
@@ -29274,6 +29333,11 @@ stores.inject(MyMetaStore, storeInstance);
29274
29333
  ...legendLabelConfig,
29275
29334
  };
29276
29335
  }),
29336
+ filter: (legendItem, data) => {
29337
+ return "datasetIndex" in legendItem
29338
+ ? !data.datasets[legendItem.datasetIndex].hidden
29339
+ : true;
29340
+ },
29277
29341
  },
29278
29342
  };
29279
29343
  }
@@ -29607,7 +29671,7 @@ stores.inject(MyMetaStore, storeInstance);
29607
29671
  <div
29608
29672
  class="o-chart-custom-tooltip border rounded px-2 py-1 pe-none mw-100 position-absolute text-nowrap shadow opacity-100">
29609
29673
  <table class="overflow-hidden m-0">
29610
- <thead>
29674
+ <thead t-if="title">
29611
29675
  <tr>
29612
29676
  <th class="o-tooltip-title align-baseline border-0 text-truncate" t-esc="title" t-attf-style="max-width: {{ labelsMaxWidth }}"/>
29613
29677
  </tr>
@@ -29668,8 +29732,8 @@ stores.inject(MyMetaStore, storeInstance);
29668
29732
  ? undefined
29669
29733
  : "";
29670
29734
  },
29735
+ beforeLabel: (tooltipItem) => tooltipItem.dataset?.label || tooltipItem.label,
29671
29736
  label: function (tooltipItem) {
29672
- const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
29673
29737
  const horizontalChart = definition.horizontal;
29674
29738
  let yLabel = horizontalChart ? tooltipItem.parsed.x : tooltipItem.parsed.y;
29675
29739
  if (yLabel === undefined || yLabel === null) {
@@ -29677,7 +29741,7 @@ stores.inject(MyMetaStore, storeInstance);
29677
29741
  }
29678
29742
  const axisId = horizontalChart ? tooltipItem.dataset.xAxisID : tooltipItem.dataset.yAxisID;
29679
29743
  const yLabelStr = formatChartDatasetValue(args.axisFormats, args.locale)(yLabel, axisId);
29680
- return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
29744
+ return yLabelStr;
29681
29745
  },
29682
29746
  },
29683
29747
  };
@@ -29702,21 +29766,18 @@ stores.inject(MyMetaStore, storeInstance);
29702
29766
  const formattedX = formatValue(label, { locale, format: labelFormat });
29703
29767
  const axisId = tooltipItem.dataset.yAxisID || "y";
29704
29768
  const formattedY = formatValue(dataSetPoint, { locale, format: axisFormats?.[axisId] });
29705
- const dataSetTitle = tooltipItem.dataset.label;
29706
- return formattedX
29707
- ? `${dataSetTitle}: (${formattedX}, ${formattedY})`
29708
- : `${dataSetTitle}: ${formattedY}`;
29769
+ return formattedX ? `(${formattedX}, ${formattedY})` : `${formattedY}`;
29709
29770
  };
29710
29771
  }
29711
29772
  else {
29712
29773
  tooltip.callbacks.label = function (tooltipItem) {
29713
- const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
29714
29774
  const yLabel = tooltipItem.parsed.y;
29715
29775
  const axisId = tooltipItem.dataset.yAxisID;
29716
29776
  const yLabelStr = formatChartDatasetValue(axisFormats, locale)(yLabel, axisId);
29717
- return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
29777
+ return yLabelStr;
29718
29778
  };
29719
29779
  }
29780
+ tooltip.callbacks.beforeLabel = (tooltipItem) => tooltipItem.dataset?.label || tooltipItem.label;
29720
29781
  tooltip.callbacks.title = function (tooltipItems) {
29721
29782
  const displayTooltipTitle = axisType !== "linear" &&
29722
29783
  tooltipItems.some((item) => item.dataset.xAxisID !== TREND_LINE_XAXIS_ID);
@@ -29734,17 +29795,15 @@ stores.inject(MyMetaStore, storeInstance);
29734
29795
  title: function (tooltipItems) {
29735
29796
  return tooltipItems[0].dataset.label;
29736
29797
  },
29798
+ beforeLabel: (tooltipItem) => tooltipItem.label || tooltipItem.dataset.label,
29737
29799
  label: function (tooltipItem) {
29738
29800
  const data = tooltipItem.dataset.data;
29739
29801
  const dataIndex = tooltipItem.dataIndex;
29740
29802
  const percentage = calculatePercentage(data, dataIndex);
29741
- const xLabel = tooltipItem.label || tooltipItem.dataset.label;
29742
29803
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
29743
29804
  const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
29744
29805
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
29745
- return xLabel
29746
- ? `${xLabel}: ${yLabelStr} (${percentage}%)`
29747
- : `${yLabelStr} (${percentage}%)`;
29806
+ return `${yLabelStr} (${percentage}%)`;
29748
29807
  },
29749
29808
  },
29750
29809
  };
@@ -29757,16 +29816,17 @@ stores.inject(MyMetaStore, storeInstance);
29757
29816
  enabled: false,
29758
29817
  external: customTooltipHandler,
29759
29818
  callbacks: {
29760
- label: function (tooltipItem) {
29761
- const [lastValue, currentValue] = tooltipItem.raw;
29762
- const yLabel = currentValue - lastValue;
29819
+ beforeLabel: function (tooltipItem) {
29763
29820
  const dataSeriesIndex = labels.length
29764
29821
  ? Math.floor(tooltipItem.dataIndex / labels.length)
29765
29822
  : 0;
29766
- const dataSeriesLabel = dataSeriesLabels[dataSeriesIndex];
29823
+ return dataSeriesLabels[dataSeriesIndex];
29824
+ },
29825
+ label: function (tooltipItem) {
29826
+ const [lastValue, currentValue] = tooltipItem.raw;
29827
+ const yLabel = currentValue - lastValue;
29767
29828
  const toolTipFormat = !format && Math.abs(yLabel) > 1000 ? "#,##" : format;
29768
- const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
29769
- return dataSeriesLabel ? `${dataSeriesLabel}: ${yLabelStr}` : yLabelStr;
29829
+ return formatValue(yLabel, { format: toolTipFormat, locale });
29770
29830
  },
29771
29831
  },
29772
29832
  };
@@ -29790,11 +29850,10 @@ stores.inject(MyMetaStore, storeInstance);
29790
29850
  enabled: false,
29791
29851
  external: customTooltipHandler,
29792
29852
  callbacks: {
29853
+ beforeLabel: (tooltipItem) => tooltipItem.dataset?.label || tooltipItem.label,
29793
29854
  label: function (tooltipItem) {
29794
- const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
29795
29855
  const yLabel = tooltipItem.parsed.r;
29796
- const formattedY = formatValue(yLabel, { format: axisFormats?.r, locale });
29797
- return xLabel ? `${xLabel}: ${formattedY}` : formattedY;
29856
+ return formatValue(yLabel, { format: axisFormats?.r, locale });
29798
29857
  },
29799
29858
  },
29800
29859
  };
@@ -29809,13 +29868,12 @@ stores.inject(MyMetaStore, storeInstance);
29809
29868
  return tooltipItem.raw.value !== undefined;
29810
29869
  },
29811
29870
  callbacks: {
29871
+ beforeLabel: (tooltipItem) => tooltipItem.raw.feature.properties.name,
29812
29872
  label: function (tooltipItem) {
29813
29873
  const rawItem = tooltipItem.raw;
29814
- const xLabel = rawItem.feature.properties.name;
29815
29874
  const yLabel = rawItem.value;
29816
29875
  const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
29817
- const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
29818
- return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
29876
+ return formatValue(yLabel, { format: toolTipFormat, locale });
29819
29877
  },
29820
29878
  },
29821
29879
  };
@@ -29835,7 +29893,8 @@ stores.inject(MyMetaStore, storeInstance);
29835
29893
  return;
29836
29894
  }
29837
29895
  const tooltipItems = tooltip.body.map((body, index) => {
29838
- let [label, value] = body.lines[0].split(":").map((str) => str.trim());
29896
+ let label = body.before[0];
29897
+ let value = body.lines[0];
29839
29898
  if (!value) {
29840
29899
  value = label;
29841
29900
  label = "";
@@ -38919,7 +38978,7 @@ stores.inject(MyMetaStore, storeInstance);
38919
38978
  .o-font-size-editor {
38920
38979
  height: calc(100% - 4px);
38921
38980
  input.o-font-size {
38922
- outline-color: ${SELECTION_BORDER_COLOR};
38981
+ outline: none;
38923
38982
  height: 20px;
38924
38983
  width: 23px;
38925
38984
  }
@@ -51627,8 +51686,8 @@ stores.inject(MyMetaStore, storeInstance);
51627
51686
  css /* scss */ `
51628
51687
  .o-corner {
51629
51688
  position: absolute;
51630
- height: 6px;
51631
- width: 6px;
51689
+ height: 8px;
51690
+ width: 8px;
51632
51691
  border: 1px solid white;
51633
51692
  }
51634
51693
  .o-corner-nw,
@@ -53465,6 +53524,10 @@ stores.inject(MyMetaStore, storeInstance);
53465
53524
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
53466
53525
  case "CLEAR_CELL":
53467
53526
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
53527
+ case "UPDATE_CELL_POSITION":
53528
+ return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
53529
+ ? "Success" /* CommandResult.Success */
53530
+ : "InvalidCellId" /* CommandResult.InvalidCellId */;
53468
53531
  default:
53469
53532
  return "Success" /* CommandResult.Success */;
53470
53533
  }
@@ -53509,6 +53572,9 @@ stores.inject(MyMetaStore, storeInstance);
53509
53572
  case "DELETE_CONTENT":
53510
53573
  this.clearZones(cmd.sheetId, cmd.target);
53511
53574
  break;
53575
+ case "DELETE_SHEET": {
53576
+ this.history.update("cells", cmd.sheetId, undefined);
53577
+ }
53512
53578
  }
53513
53579
  }
53514
53580
  clearZones(sheetId, zones) {
@@ -54299,6 +54365,9 @@ stores.inject(MyMetaStore, storeInstance);
54299
54365
  allowDispatch(cmd) {
54300
54366
  switch (cmd.type) {
54301
54367
  case "ADD_CONDITIONAL_FORMAT":
54368
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
54369
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54370
+ }
54302
54371
  return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
54303
54372
  case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
54304
54373
  return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
@@ -54715,8 +54784,17 @@ stores.inject(MyMetaStore, storeInstance);
54715
54784
  allowDispatch(cmd) {
54716
54785
  switch (cmd.type) {
54717
54786
  case "ADD_DATA_VALIDATION_RULE":
54787
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
54788
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54789
+ }
54790
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
54791
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54792
+ }
54718
54793
  return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
54719
54794
  case "REMOVE_DATA_VALIDATION_RULE":
54795
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
54796
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54797
+ }
54720
54798
  if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
54721
54799
  return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
54722
54800
  }
@@ -54943,6 +55021,7 @@ stores.inject(MyMetaStore, storeInstance);
54943
55021
  class FigurePlugin extends CorePlugin {
54944
55022
  static getters = ["getFigures", "getFigure", "getFigureSheetId"];
54945
55023
  figures = {};
55024
+ insertionOrders = []; // TODO use a list in master
54946
55025
  // ---------------------------------------------------------------------------
54947
55026
  // Command Handling
54948
55027
  // ---------------------------------------------------------------------------
@@ -55045,11 +55124,14 @@ stores.inject(MyMetaStore, storeInstance);
55045
55124
  }
55046
55125
  addFigure(figure, sheetId) {
55047
55126
  this.history.update("figures", sheetId, figure.id, figure);
55127
+ this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
55048
55128
  }
55049
55129
  deleteSheet(sheetId) {
55130
+ this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
55050
55131
  this.history.update("figures", sheetId, undefined);
55051
55132
  }
55052
55133
  removeFigure(id, sheetId) {
55134
+ this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
55053
55135
  this.history.update("figures", sheetId, id, undefined);
55054
55136
  }
55055
55137
  checkFigureExists(sheetId, figureId) {
@@ -55068,7 +55150,14 @@ stores.inject(MyMetaStore, storeInstance);
55068
55150
  // Getters
55069
55151
  // ---------------------------------------------------------------------------
55070
55152
  getFigures(sheetId) {
55071
- return Object.values(this.figures[sheetId] || {}).filter(isDefined);
55153
+ const figures = [];
55154
+ for (const figureId of this.insertionOrders) {
55155
+ const figure = this.figures[sheetId]?.[figureId];
55156
+ if (figure) {
55157
+ figures.push(figure);
55158
+ }
55159
+ }
55160
+ return figures;
55072
55161
  }
55073
55162
  getFigure(sheetId, figureId) {
55074
55163
  return this.figures[sheetId]?.[figureId];
@@ -55081,11 +55170,9 @@ stores.inject(MyMetaStore, storeInstance);
55081
55170
  // ---------------------------------------------------------------------------
55082
55171
  import(data) {
55083
55172
  for (let sheet of data.sheets) {
55084
- const figures = {};
55085
- sheet.figures.forEach((figure) => {
55086
- figures[figure.id] = figure;
55087
- });
55088
- this.figures[sheet.id] = figures;
55173
+ for (const figure of sheet.figures) {
55174
+ this.addFigure(figure, sheet.id);
55175
+ }
55089
55176
  }
55090
55177
  }
55091
55178
  export(data) {
@@ -56545,6 +56632,9 @@ stores.inject(MyMetaStore, storeInstance);
56545
56632
  case "CREATE_SHEET": {
56546
56633
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
56547
56634
  }
56635
+ case "DUPLICATE_SHEET": {
56636
+ return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
56637
+ }
56548
56638
  case "MOVE_SHEET":
56549
56639
  try {
56550
56640
  const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
@@ -57347,14 +57437,18 @@ stores.inject(MyMetaStore, storeInstance);
57347
57437
  checkZonesAreInSheet(cmd) {
57348
57438
  if (!("sheetId" in cmd))
57349
57439
  return "Success" /* CommandResult.Success */;
57440
+ if ("ranges" in cmd &&
57441
+ cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
57442
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57443
+ }
57350
57444
  return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
57351
57445
  }
57352
57446
  }
57353
57447
 
57354
- let nextTableId = 1;
57355
57448
  class TablePlugin extends CorePlugin {
57356
57449
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
57357
57450
  tables = {};
57451
+ nextTableId = 1;
57358
57452
  adaptRanges(applyChange, sheetId) {
57359
57453
  const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
57360
57454
  for (const sheetId of sheetIds) {
@@ -57366,6 +57460,9 @@ stores.inject(MyMetaStore, storeInstance);
57366
57460
  allowDispatch(cmd) {
57367
57461
  switch (cmd.type) {
57368
57462
  case "CREATE_TABLE":
57463
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
57464
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57465
+ }
57369
57466
  const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
57370
57467
  if (!areZonesContinuous(zones)) {
57371
57468
  return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
@@ -57419,7 +57516,7 @@ stores.inject(MyMetaStore, storeInstance);
57419
57516
  const union = this.getters.getRangesUnion(ranges);
57420
57517
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
57421
57518
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
57422
- const id = `${nextTableId++}`;
57519
+ const id = this.consumeNextId();
57423
57520
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
57424
57521
  const newTable = cmd.tableType === "dynamic"
57425
57522
  ? this.createDynamicTable(id, union, config)
@@ -57572,7 +57669,7 @@ stores.inject(MyMetaStore, storeInstance);
57572
57669
  filters = [];
57573
57670
  for (const i of range(zone.left, zone.right + 1)) {
57574
57671
  const filterZone = { ...zone, left: i, right: i };
57575
- const uid = `${nextTableId++}`;
57672
+ const uid = this.consumeNextId();
57576
57673
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
57577
57674
  }
57578
57675
  }
@@ -57637,7 +57734,7 @@ stores.inject(MyMetaStore, storeInstance);
57637
57734
  ? table.filters.find((f) => f.col === i)
57638
57735
  : undefined;
57639
57736
  const filterZone = { ...tableZone, left: i, right: i };
57640
- const filterId = oldFilter?.id || `${nextTableId++}`;
57737
+ const filterId = oldFilter?.id || this.consumeNextId();
57641
57738
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
57642
57739
  }
57643
57740
  }
@@ -57738,7 +57835,7 @@ stores.inject(MyMetaStore, storeInstance);
57738
57835
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
57739
57836
  for (let col = tableZone.left; col <= tableZone.right; col++) {
57740
57837
  if (!filters.find((filter) => filter.col === col)) {
57741
- const uid = `${nextTableId++}`;
57838
+ const uid = this.consumeNextId();
57742
57839
  const filterZone = { ...tableZone, left: col, right: col };
57743
57840
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
57744
57841
  }
@@ -57748,13 +57845,18 @@ stores.inject(MyMetaStore, storeInstance);
57748
57845
  const newTable = this.createStaticTable(table.id, table.type, newTableRange, table.config, filters);
57749
57846
  this.history.update("tables", sheetId, table.id, newTable);
57750
57847
  }
57848
+ consumeNextId() {
57849
+ const id = `${this.nextTableId}`;
57850
+ this.history.update("nextTableId", this.nextTableId + 1);
57851
+ return id;
57852
+ }
57751
57853
  // ---------------------------------------------------------------------------
57752
57854
  // Import/Export
57753
57855
  // ---------------------------------------------------------------------------
57754
57856
  import(data) {
57755
57857
  for (const sheet of data.sheets) {
57756
57858
  for (const tableData of sheet.tables || []) {
57757
- const uuid = `${nextTableId++}`;
57859
+ const uuid = this.consumeNextId();
57758
57860
  const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
57759
57861
  const range = this.getters.getRangeFromSheetXC(sheet.id, tableData.range);
57760
57862
  const tableType = tableData.type || "static";
@@ -57802,7 +57904,10 @@ stores.inject(MyMetaStore, storeInstance);
57802
57904
  allowDispatch(cmd) {
57803
57905
  switch (cmd.type) {
57804
57906
  case "GROUP_HEADERS": {
57805
- const { start, end } = cmd;
57907
+ const { start, end, sheetId } = cmd;
57908
+ if (!this.getters.tryGetSheet(sheetId)) {
57909
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57910
+ }
57806
57911
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
57807
57912
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
57808
57913
  }
@@ -57815,7 +57920,10 @@ stores.inject(MyMetaStore, storeInstance);
57815
57920
  break;
57816
57921
  }
57817
57922
  case "UNGROUP_HEADERS": {
57818
- const { start, end } = cmd;
57923
+ const { start, end, sheetId } = cmd;
57924
+ if (!this.getters.tryGetSheet(sheetId)) {
57925
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57926
+ }
57819
57927
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
57820
57928
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
57821
57929
  }
@@ -57826,6 +57934,9 @@ stores.inject(MyMetaStore, storeInstance);
57826
57934
  }
57827
57935
  case "UNFOLD_HEADER_GROUP":
57828
57936
  case "FOLD_HEADER_GROUP":
57937
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
57938
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57939
+ }
57829
57940
  const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
57830
57941
  if (!group) {
57831
57942
  return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
@@ -58226,6 +58337,9 @@ stores.inject(MyMetaStore, storeInstance);
58226
58337
  return this.checkDuplicatedMeasureIds(cmd.pivot);
58227
58338
  }
58228
58339
  case "UPDATE_PIVOT": {
58340
+ if (!(cmd.pivotId in this.pivots)) {
58341
+ return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
58342
+ }
58229
58343
  if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
58230
58344
  return "NoChanges" /* CommandResult.NoChanges */;
58231
58345
  }
@@ -58242,6 +58356,8 @@ stores.inject(MyMetaStore, storeInstance);
58242
58356
  return "EmptyName" /* CommandResult.EmptyName */;
58243
58357
  }
58244
58358
  break;
58359
+ case "REMOVE_PIVOT":
58360
+ case "DUPLICATE_PIVOT":
58245
58361
  case "INSERT_PIVOT": {
58246
58362
  if (!(cmd.pivotId in this.pivots)) {
58247
58363
  return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
@@ -58291,7 +58407,7 @@ stores.inject(MyMetaStore, storeInstance);
58291
58407
  break;
58292
58408
  }
58293
58409
  case "UPDATE_PIVOT": {
58294
- this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
58410
+ this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
58295
58411
  this.compileCalculatedMeasures(cmd.pivot.measures);
58296
58412
  break;
58297
58413
  }
@@ -58362,7 +58478,7 @@ stores.inject(MyMetaStore, storeInstance);
58362
58478
  // Private
58363
58479
  // -------------------------------------------------------------------------
58364
58480
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
58365
- this.history.update("pivots", pivotId, { definition: pivot, formulaId });
58481
+ this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
58366
58482
  this.compileCalculatedMeasures(pivot.measures);
58367
58483
  this.history.update("formulaIds", formulaId, pivotId);
58368
58484
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
@@ -59932,6 +60048,10 @@ stores.inject(MyMetaStore, storeInstance);
59932
60048
  this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
59933
60049
  this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
59934
60050
  this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
60051
+ this.compilationParams.evalContext.lookupCaches = {
60052
+ forwardSearch: new Map(),
60053
+ reverseSearch: new Map(),
60054
+ };
59935
60055
  }
59936
60056
  createEmptyPositionSet() {
59937
60057
  const sheetSizes = {};
@@ -63280,6 +63400,9 @@ stores.inject(MyMetaStore, storeInstance);
63280
63400
  };
63281
63401
  }
63282
63402
  function createSheetTransformation(toTransform, executed) {
63403
+ if (toTransform.sheetId === executed.sheetId) {
63404
+ toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
63405
+ }
63283
63406
  if (toTransform.name === executed.name) {
63284
63407
  return {
63285
63408
  ...toTransform,
@@ -63923,15 +64046,6 @@ stores.inject(MyMetaStore, storeInstance);
63923
64046
  }
63924
64047
  this.sendPendingMessage();
63925
64048
  }
63926
- dropPendingRevision(revisionId) {
63927
- this.revisions.drop(revisionId);
63928
- const revisionIds = this.pendingMessages
63929
- .filter((message) => message.type === "REMOTE_REVISION")
63930
- .map((message) => message.nextRevisionId);
63931
- this.trigger("pending-revisions-dropped", { revisionIds });
63932
- this.waitingAck = false;
63933
- this.waitingUndoRedoAck = false;
63934
- }
63935
64049
  /**
63936
64050
  * Send the next pending message
63937
64051
  */
@@ -63940,15 +64054,14 @@ stores.inject(MyMetaStore, storeInstance);
63940
64054
  if (!message)
63941
64055
  return;
63942
64056
  if (message.type === "REMOTE_REVISION") {
63943
- const revision = this.revisions.get(message.nextRevisionId);
64057
+ let revision = this.revisions.get(message.nextRevisionId);
63944
64058
  if (revision.commands.length === 0) {
63945
64059
  /**
63946
- * The command is empty, we have to drop all the next local revisions
64060
+ * The command is empty, we have to rebase all the next local revisions
63947
64061
  * to avoid issues with undo/redo
63948
64062
  */
63949
- this.dropPendingRevision(revision.id);
63950
- this.pendingMessages = [];
63951
- return;
64063
+ this.revisions.rebase(revision.id);
64064
+ revision = this.revisions.get(message.nextRevisionId);
63952
64065
  }
63953
64066
  message = {
63954
64067
  ...message,
@@ -63984,18 +64097,16 @@ stores.inject(MyMetaStore, storeInstance);
63984
64097
  case "REVISION_UNDONE": {
63985
64098
  this.waitingAck = false;
63986
64099
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
63987
- const pendingRemoteRevisions = this.pendingMessages.filter((message) => message.type === "REMOTE_REVISION");
63988
- const firstTransformedRevisionIndex = pendingRemoteRevisions.findIndex((message) => !deepEquals(message.commands, this.revisions.get(message.nextRevisionId).commands));
63989
- if (firstTransformedRevisionIndex !== -1) {
64100
+ const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
64101
+ if (firstPendingRevisionId !== -1) {
63990
64102
  /**
63991
64103
  * Some revisions undergo transformations that may cause issues with
63992
64104
  * undo/redo if the transformation is destructive (we don't get back
63993
64105
  * the original command by transforming it with the inverse).
63994
- * To prevent these problems, we must discard all subsequent local
64106
+ * To prevent these problems, we must rebase all subsequent local
63995
64107
  * revisions.
63996
64108
  */
63997
- this.dropPendingRevision(this.pendingMessages[firstTransformedRevisionIndex].nextRevisionId);
63998
- this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
64109
+ this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
63999
64110
  }
64000
64111
  this.serverRevisionId = message.nextRevisionId;
64001
64112
  this.processedRevisions.add(message.nextRevisionId);
@@ -65117,6 +65228,10 @@ stores.inject(MyMetaStore, storeInstance);
65117
65228
  */
65118
65229
  checkZonesAreInSheet(cmd) {
65119
65230
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
65231
+ if ("ranges" in cmd &&
65232
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
65233
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
65234
+ }
65120
65235
  const zones = this.getters.getCommandZones(cmd);
65121
65236
  if (!sheetId && zones.length > 0) {
65122
65237
  return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
@@ -65671,7 +65786,6 @@ stores.inject(MyMetaStore, storeInstance);
65671
65786
  super(config);
65672
65787
  this.session = config.session;
65673
65788
  this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
65674
- this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
65675
65789
  this.session.on("snapshot", this, () => {
65676
65790
  this.undoStack = [];
65677
65791
  this.redoStack = [];
@@ -65741,10 +65855,6 @@ stores.inject(MyMetaStore, storeInstance);
65741
65855
  const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
65742
65856
  return canRepeatRevision(lastNonRedoRevision);
65743
65857
  }
65744
- drop(revisionIds) {
65745
- this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
65746
- this.redoStack = [];
65747
- }
65748
65858
  onNewLocalStateUpdate({ id }) {
65749
65859
  this.undoStack.push(id);
65750
65860
  this.redoStack = [];
@@ -68419,7 +68529,9 @@ stores.inject(MyMetaStore, storeInstance);
68419
68529
  case "UNGROUP_HEADERS":
68420
68530
  case "GROUP_HEADERS":
68421
68531
  case "CREATE_SHEET":
68422
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
68532
+ if (this.getters.tryGetSheet(cmd.sheetId)) {
68533
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
68534
+ }
68423
68535
  break;
68424
68536
  case "DUPLICATE_SHEET":
68425
68537
  this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
@@ -68427,12 +68539,14 @@ stores.inject(MyMetaStore, storeInstance);
68427
68539
  }
68428
68540
  }
68429
68541
  finalize() {
68430
- if (this.isDirty) {
68431
- for (const sheetId of this.getters.getSheetIds()) {
68542
+ for (const sheetId of this.getters.getSheetIds()) {
68543
+ // sheets can be created without this plugin being aware of it
68544
+ // in concurrent situations.
68545
+ if (this.isDirty || !this.headerPositions[sheetId]) {
68432
68546
  this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
68433
68547
  }
68434
- this.isDirty = false;
68435
68548
  }
68549
+ this.isDirty = false;
68436
68550
  }
68437
68551
  /**
68438
68552
  * Returns the size, start and end coordinates of a column on an unfolded sheet
@@ -70273,6 +70387,10 @@ stores.inject(MyMetaStore, storeInstance);
70273
70387
  </svg>
70274
70388
  `;
70275
70389
  css /* scss */ `
70390
+ .o-topbar-composer-container {
70391
+ height: ${TOPBAR_TOOLBAR_HEIGHT}px;
70392
+ }
70393
+
70276
70394
  .o-topbar-composer {
70277
70395
  height: fit-content;
70278
70396
  margin-top: -1px;
@@ -71836,9 +71954,16 @@ stores.inject(MyMetaStore, storeInstance);
71836
71954
  this.fastForward();
71837
71955
  this.insert(redoId, this.buildEmpty(redoId), insertAfter);
71838
71956
  }
71839
- drop(operationId) {
71957
+ rebase(operationId) {
71958
+ const operation = this.get(operationId);
71959
+ const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
71840
71960
  this.revertBefore(operationId);
71961
+ const baseId = this.HEAD_OPERATION.id;
71841
71962
  this.tree.drop(operationId);
71963
+ this.insert(operationId, operation, baseId);
71964
+ for (const { operation } of execution) {
71965
+ this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
71966
+ }
71842
71967
  }
71843
71968
  /**
71844
71969
  * Revert the state as it was *before* the given operation was executed.
@@ -74966,6 +75091,11 @@ stores.inject(MyMetaStore, storeInstance);
74966
75091
  dispatch: (command) => {
74967
75092
  const result = this.checkDispatchAllowed(command);
74968
75093
  if (!result.isSuccessful) {
75094
+ // core views plugins need to be invalidated
75095
+ this.dispatchToHandlers(this.coreHandlers, {
75096
+ type: "UNDO",
75097
+ commands: [command],
75098
+ });
74969
75099
  return;
74970
75100
  }
74971
75101
  this.isReplayingCommand = true;
@@ -75532,9 +75662,9 @@ stores.inject(MyMetaStore, storeInstance);
75532
75662
  exports.tokenize = tokenize;
75533
75663
 
75534
75664
 
75535
- __info__.version = "18.2.0-alpha.8";
75536
- __info__.date = "2025-02-14T08:40:13.286Z";
75537
- __info__.hash = "19d45d9";
75665
+ __info__.version = "18.2.1";
75666
+ __info__.date = "2025-02-25T06:03:13.262Z";
75667
+ __info__.hash = "3b4b5c9";
75538
75668
 
75539
75669
 
75540
75670
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);