@odoo/o-spreadsheet 19.0.9 → 19.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 19.0.9
6
- * @date 2025-11-03T12:32:15.473Z
7
- * @hash 10359f4
5
+ * @version 19.0.11
6
+ * @date 2025-11-24T07:46:47.685Z
7
+ * @hash f5bdbcc
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -863,7 +863,7 @@
863
863
  };
864
864
  const PIVOT_INDENT = 15;
865
865
  const PIVOT_COLLAPSE_ICON_SIZE = 12;
866
- const PIVOT_MAX_NUMBER_OF_CELLS = 1e5;
866
+ const PIVOT_MAX_NUMBER_OF_CELLS = 5e5;
867
867
  const DEFAULT_CURRENCY = {
868
868
  symbol: "$",
869
869
  position: "before",
@@ -2500,7 +2500,10 @@
2500
2500
  * Check if a zone is inside another
2501
2501
  */
2502
2502
  function isZoneInside(smallZone, biggerZone) {
2503
- return isEqual(union(biggerZone, smallZone), biggerZone);
2503
+ return (smallZone.left >= biggerZone.left &&
2504
+ smallZone.right <= biggerZone.right &&
2505
+ smallZone.top >= biggerZone.top &&
2506
+ smallZone.bottom <= biggerZone.bottom);
2504
2507
  }
2505
2508
  function zoneToDimension(zone) {
2506
2509
  return {
@@ -6903,7 +6906,7 @@
6903
6906
  let sheetName = "";
6904
6907
  if (prefixSheet) {
6905
6908
  if (range.invalidSheetName) {
6906
- sheetName = range.invalidSheetName;
6909
+ sheetName = getCanonicalSymbolName(range.invalidSheetName);
6907
6910
  }
6908
6911
  else {
6909
6912
  sheetName = getCanonicalSymbolName(getSheetName(range.sheetId));
@@ -13346,7 +13349,7 @@ stores.inject(MyMetaStore, storeInstance);
13346
13349
  if (!acceptHiddenCells && this.getters.isRowHiddenByUser(sheetId, row))
13347
13350
  continue;
13348
13351
  for (let col = left; col <= right; col++) {
13349
- const cell = this.getters.getCell({ sheetId, col, row });
13352
+ const cell = this.getters.getCorrespondingFormulaCell({ sheetId, col, row });
13350
13353
  if (!cell || !isSubtotalCell(cell)) {
13351
13354
  evaluatedCellToKeep.push(this.getters.getEvaluatedCell({ sheetId, col, row }));
13352
13355
  }
@@ -19342,7 +19345,7 @@ stores.inject(MyMetaStore, storeInstance);
19342
19345
  function setXcToFixedReferenceType(xc, referenceType) {
19343
19346
  let sheetName;
19344
19347
  ({ sheetName, xc } = splitReference(xc));
19345
- sheetName = sheetName ? sheetName + "!" : "";
19348
+ sheetName = sheetName ? getCanonicalSymbolName(sheetName) + "!" : "";
19346
19349
  xc = xc.replace(/\$/g, "");
19347
19350
  const splitIndex = xc.indexOf(":");
19348
19351
  if (splitIndex >= 0) {
@@ -24419,7 +24422,7 @@ stores.inject(MyMetaStore, storeInstance);
24419
24422
  return {
24420
24423
  background: context.background,
24421
24424
  type: "scorecard",
24422
- keyValue: context.range ? context.range[0].dataRange : undefined,
24425
+ keyValue: context.range?.[0]?.dataRange,
24423
24426
  title: context.title || { text: "" },
24424
24427
  baselineMode: DEFAULT_SCORECARD_BASELINE_MODE,
24425
24428
  baselineColorUp: DEFAULT_SCORECARD_BASELINE_COLOR_UP,
@@ -29128,7 +29131,7 @@ stores.inject(MyMetaStore, storeInstance);
29128
29131
  background: context.background,
29129
29132
  title: context.title || { text: "" },
29130
29133
  type: "gauge",
29131
- dataRange: context.range ? context.range[0].dataRange : undefined,
29134
+ dataRange: context.range?.[0]?.dataRange,
29132
29135
  sectionRule: {
29133
29136
  colors: {
29134
29137
  lowerColor: DEFAULT_GAUGE_LOWER_COLOR,
@@ -31020,8 +31023,7 @@ stores.inject(MyMetaStore, storeInstance);
31020
31023
  .filter((ds) => !isTrendLineAxis(ds["xAxisID"]))
31021
31024
  .map((ds) => ({
31022
31025
  ...ds,
31023
- pointRadius: 0,
31024
- showLine: true,
31026
+ pointRadius: ds.showLine === false ? 2 : 0, // Show points only for scatter plots
31025
31027
  })),
31026
31028
  },
31027
31029
  options: {
@@ -34522,16 +34524,12 @@ stores.inject(MyMetaStore, storeInstance);
34522
34524
  processTabKey(ev, direction) {
34523
34525
  ev.preventDefault();
34524
34526
  ev.stopPropagation();
34525
- if (!this.assistant.forcedClosed) {
34526
- this.props.composerStore.autoCompleteOrStop(direction);
34527
- }
34527
+ this.props.composerStore.autoCompleteOrStop(direction, this.assistant.forcedClosed);
34528
34528
  }
34529
34529
  processEnterKey(ev, direction) {
34530
34530
  ev.preventDefault();
34531
34531
  ev.stopPropagation();
34532
- if (!this.assistant.forcedClosed) {
34533
- this.props.composerStore.autoCompleteOrStop(direction);
34534
- }
34532
+ this.props.composerStore.autoCompleteOrStop(direction, this.assistant.forcedClosed);
34535
34533
  }
34536
34534
  processNewLineEvent(ev) {
34537
34535
  ev.preventDefault();
@@ -34707,7 +34705,6 @@ stores.inject(MyMetaStore, storeInstance);
34707
34705
  return;
34708
34706
  }
34709
34707
  const newSelection = this.contentHelper.getCurrentSelection();
34710
- this.props.composerStore.stopComposerRangeSelection();
34711
34708
  const isCurrentlyInactive = this.props.composerStore.editionMode === "inactive";
34712
34709
  this.props.onComposerContentFocused(newSelection);
34713
34710
  if (!isCurrentlyInactive) {
@@ -35163,6 +35160,7 @@ stores.inject(MyMetaStore, storeInstance);
35163
35160
  this.highlightStore.register(this);
35164
35161
  this.onDispose(() => {
35165
35162
  this.highlightStore.unRegister(this);
35163
+ this._cancelEdition();
35166
35164
  });
35167
35165
  }
35168
35166
  handleEvent(event) {
@@ -35197,6 +35195,7 @@ stores.inject(MyMetaStore, storeInstance);
35197
35195
  }
35198
35196
  this.selectionStart = start;
35199
35197
  this.selectionEnd = end;
35198
+ this.editionMode = "editing";
35200
35199
  this.computeFormulaCursorContext();
35201
35200
  this.computeParenthesisRelatedToCursor();
35202
35201
  this.updateAutoCompleteProvider();
@@ -35867,10 +35866,13 @@ stores.inject(MyMetaStore, storeInstance);
35867
35866
  hideHelp() {
35868
35867
  this.autoComplete.hide();
35869
35868
  }
35870
- autoCompleteOrStop(direction) {
35869
+ autoCompleteOrStop(direction, assistantForcedClosed = false) {
35871
35870
  if (this.editionMode !== "inactive") {
35872
35871
  const autoComplete = this.autoComplete;
35873
- if (autoComplete.provider && autoComplete.selectedIndex !== undefined) {
35872
+ const suppressAutocomplete = assistantForcedClosed && this.canBeToggled;
35873
+ if (!suppressAutocomplete &&
35874
+ autoComplete.provider &&
35875
+ autoComplete.selectedIndex !== undefined) {
35874
35876
  const autoCompleteValue = autoComplete.provider.proposals[autoComplete.selectedIndex]?.text;
35875
35877
  if (autoCompleteValue) {
35876
35878
  this.autoComplete.provider?.selectProposal(autoCompleteValue);
@@ -51561,10 +51563,11 @@ stores.inject(MyMetaStore, storeInstance);
51561
51563
  this.state.waitingForMove = false;
51562
51564
  }
51563
51565
  onMouseMove(ev) {
51564
- if (this.env.isMobile()) {
51565
- return;
51566
- }
51567
- if (this.state.isResizing || this.state.isMoving || this.state.isSelecting) {
51566
+ if (this.env.isMobile() ||
51567
+ this.env.model.getters.isReadonly() ||
51568
+ this.state.isResizing ||
51569
+ this.state.isMoving ||
51570
+ this.state.isSelecting) {
51568
51571
  return;
51569
51572
  }
51570
51573
  this._computeHandleDisplay(ev);
@@ -51631,6 +51634,10 @@ stores.inject(MyMetaStore, storeInstance);
51631
51634
  if (index < 0) {
51632
51635
  return;
51633
51636
  }
51637
+ if (this.env.model.getters.isReadonly()) {
51638
+ this._selectElement(index, false);
51639
+ return;
51640
+ }
51634
51641
  if (this.state.waitingForMove) {
51635
51642
  if (!this.env.model.getters.isGridSelectionActive()) {
51636
51643
  this._selectElement(index, false);
@@ -52190,6 +52197,9 @@ stores.inject(MyMetaStore, storeInstance);
52190
52197
  break;
52191
52198
  }
52192
52199
  }
52200
+ finalize() {
52201
+ this.zonesWithPreventedAnimationsInNextFrame = recomputeZones(this.zonesWithPreventedAnimationsInNextFrame);
52202
+ }
52193
52203
  get renderingLayers() {
52194
52204
  return ["Background", "Headers"];
52195
52205
  }
@@ -52989,7 +52999,7 @@ stores.inject(MyMetaStore, storeInstance);
52989
52999
  const verticalScrollFactor = 1;
52990
53000
  const horizontalScrollFactor = 1;
52991
53001
  const resetTimeoutDuration = 100;
52992
- function useTouchScroll(ref, updateScroll, canMoveUp) {
53002
+ function useTouchScroll(ref, updateScroll, canMoveUp, canMoveDown) {
52993
53003
  let lastX = 0;
52994
53004
  let lastY = 0;
52995
53005
  let velocityX = 0;
@@ -53026,7 +53036,7 @@ stores.inject(MyMetaStore, storeInstance);
53026
53036
  lastX = clientX;
53027
53037
  lastY = clientY;
53028
53038
  lastTime = currentTime;
53029
- if (canMoveUp()) {
53039
+ if ((deltaY < 0 && canMoveUp()) || (deltaY > 0 && canMoveDown())) {
53030
53040
  if (event.cancelable) {
53031
53041
  event.preventDefault();
53032
53042
  }
@@ -59264,7 +59274,6 @@ stores.inject(MyMetaStore, storeInstance);
59264
59274
  // replace the whole token
59265
59275
  start = tokenAtCursor.start;
59266
59276
  }
59267
- this.composer.stopComposerRangeSelection();
59268
59277
  this.composer.changeComposerCursorSelection(start, end);
59269
59278
  this.composer.replaceComposerCursorSelection(value);
59270
59279
  }
@@ -59282,7 +59291,6 @@ stores.inject(MyMetaStore, storeInstance);
59282
59291
  // replace the whole token
59283
59292
  start = tokenAtCursor.start;
59284
59293
  }
59285
- this.composer.stopComposerRangeSelection();
59286
59294
  this.composer.changeComposerCursorSelection(start, end);
59287
59295
  this.composer.replaceComposerCursorSelection(value);
59288
59296
  }
@@ -60743,6 +60751,7 @@ stores.inject(MyMetaStore, storeInstance);
60743
60751
  getPanelProps(panelInfo) {
60744
60752
  const state = this.computeState(panelInfo);
60745
60753
  if (state.isOpen) {
60754
+ panelInfo.currentPanelProps = state.props ?? panelInfo.currentPanelProps;
60746
60755
  return state.props ?? {};
60747
60756
  }
60748
60757
  return {};
@@ -60754,11 +60763,11 @@ stores.inject(MyMetaStore, storeInstance);
60754
60763
  }
60755
60764
  return undefined;
60756
60765
  }
60757
- open(componentTag, initialPanelProps = {}) {
60766
+ open(componentTag, currentPanelProps = {}) {
60758
60767
  if (this.screenWidthStore.isSmall) {
60759
60768
  return;
60760
60769
  }
60761
- const newPanelInfo = { initialPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60770
+ const newPanelInfo = { currentPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60762
60771
  const state = this.computeState(newPanelInfo);
60763
60772
  if (!state.isOpen) {
60764
60773
  return;
@@ -60782,8 +60791,8 @@ stores.inject(MyMetaStore, storeInstance);
60782
60791
  }
60783
60792
  this._openPanel("secondaryPanel", newPanelInfo, state);
60784
60793
  }
60785
- replace(componentTag, currentPanelKey, initialPanelProps = {}) {
60786
- const newPanelInfo = { initialPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60794
+ replace(componentTag, currentPanelKey, currentPanelProps = {}) {
60795
+ const newPanelInfo = { currentPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60787
60796
  const state = this.computeState(newPanelInfo);
60788
60797
  if (!state.isOpen) {
60789
60798
  return;
@@ -60813,10 +60822,10 @@ stores.inject(MyMetaStore, storeInstance);
60813
60822
  _openPanel(panel, newPanel, state) {
60814
60823
  const currentPanel = this[panel];
60815
60824
  if (currentPanel && newPanel.componentTag !== currentPanel.componentTag) {
60816
- currentPanel.initialPanelProps?.onCloseSidePanel?.();
60825
+ currentPanel.currentPanelProps?.onCloseSidePanel?.();
60817
60826
  }
60818
60827
  this[panel] = {
60819
- initialPanelProps: state.props ?? {},
60828
+ currentPanelProps: state.props ?? {},
60820
60829
  componentTag: newPanel.componentTag,
60821
60830
  size: currentPanel?.size || DEFAULT_SIDE_PANEL_SIZE,
60822
60831
  isCollapsed: currentPanel?.isCollapsed || false,
@@ -60838,16 +60847,16 @@ stores.inject(MyMetaStore, storeInstance);
60838
60847
  close() {
60839
60848
  if (this.mainPanel?.isPinned) {
60840
60849
  if (this.secondaryPanel) {
60841
- this.secondaryPanel.initialPanelProps.onCloseSidePanel?.();
60850
+ this.secondaryPanel.currentPanelProps.onCloseSidePanel?.();
60842
60851
  this.secondaryPanel = undefined;
60843
60852
  }
60844
60853
  return;
60845
60854
  }
60846
- this.mainPanel?.initialPanelProps.onCloseSidePanel?.();
60855
+ this.mainPanel?.currentPanelProps.onCloseSidePanel?.();
60847
60856
  this.mainPanel = undefined;
60848
60857
  }
60849
60858
  closeMainPanel() {
60850
- this.mainPanel?.initialPanelProps.onCloseSidePanel?.();
60859
+ this.mainPanel?.currentPanelProps.onCloseSidePanel?.();
60851
60860
  this.mainPanel = this.secondaryPanel || undefined;
60852
60861
  this.secondaryPanel = undefined;
60853
60862
  }
@@ -60879,7 +60888,7 @@ stores.inject(MyMetaStore, storeInstance);
60879
60888
  }
60880
60889
  this.mainPanel.isPinned = !this.mainPanel.isPinned;
60881
60890
  if (!this.mainPanel.isPinned && this.secondaryPanel) {
60882
- this.secondaryPanel?.initialPanelProps.onCloseSidePanel?.();
60891
+ this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
60883
60892
  this.mainPanel = this.secondaryPanel;
60884
60893
  this.secondaryPanel = undefined;
60885
60894
  }
@@ -60898,7 +60907,7 @@ stores.inject(MyMetaStore, storeInstance);
60898
60907
  panelInfo.size = COLLAPSED_SIDE_PANEL_SIZE;
60899
60908
  }
60900
60909
  }
60901
- computeState({ componentTag, initialPanelProps }) {
60910
+ computeState({ componentTag, currentPanelProps: initialPanelProps, }) {
60902
60911
  const customComputeState = sidePanelRegistry.get(componentTag).computeState;
60903
60912
  const state = customComputeState
60904
60913
  ? customComputeState(this.getters, initialPanelProps)
@@ -60908,7 +60917,7 @@ stores.inject(MyMetaStore, storeInstance);
60908
60917
  changeSpreadsheetWidth(width) {
60909
60918
  this.availableWidth = width - MIN_SHEET_VIEW_WIDTH;
60910
60919
  if (this.secondaryPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
60911
- this.secondaryPanel?.initialPanelProps.onCloseSidePanel?.();
60920
+ this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
60912
60921
  this.secondaryPanel = undefined;
60913
60922
  }
60914
60923
  if (this.mainPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
@@ -61068,6 +61077,10 @@ stores.inject(MyMetaStore, storeInstance);
61068
61077
  useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
61069
61078
  const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
61070
61079
  return scrollY > 0;
61080
+ }, () => {
61081
+ const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
61082
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
61083
+ return scrollY < maxOffsetY;
61071
61084
  });
61072
61085
  }
61073
61086
  get highlights() {
@@ -62360,22 +62373,34 @@ stores.inject(MyMetaStore, storeInstance);
62360
62373
  addBorder(sheetId, zone, newBorder, force = false) {
62361
62374
  const borders = [];
62362
62375
  const plannedBorder = newBorder ? { zone, style: newBorder } : undefined;
62363
- const sideToClear = {
62364
- left: force || !!newBorder?.left,
62365
- right: force || !!newBorder?.right,
62366
- top: force || !!newBorder?.top,
62367
- bottom: force || !!newBorder?.bottom,
62376
+ // For each side, decide if we must clear the border on the *adjacent*
62377
+ // existing cell when we draw on the opposite side of the new zone.
62378
+ //
62379
+ // Example:
62380
+ // - newBorder.right is set → we draw border on the RIGHT side of `zone`
62381
+ // - the cell on the right may already have a LEFT border on that edge
62382
+ // In that case we clear that LEFT border, so only the new RIGHT border
62383
+ // remains on the shared edge.
62384
+ //
62385
+ // existingBorderSideToClear[side] = true means we should clear the border on that
62386
+ // side of the existing adjacent zone before adding the new border.
62387
+ const existingBorderSideToClear = {
62388
+ left: force || !!newBorder?.right,
62389
+ right: force || !!newBorder?.left,
62390
+ top: force || !!newBorder?.bottom,
62391
+ bottom: force || !!newBorder?.top,
62368
62392
  };
62369
62393
  let editingZone = [zone];
62370
62394
  for (const existingBorder of this.borders[sheetId] ?? []) {
62371
62395
  const inter = intersection(existingBorder.zone, zone);
62372
62396
  if (!inter) {
62373
- // Clear adjacent borders on which you write
62397
+ // Check if the existing border is adjacent to the new zone
62374
62398
  const adjacentEdge = adjacent(existingBorder.zone, zone);
62375
- if (adjacentEdge && sideToClear[adjacentEdge.position]) {
62399
+ if (adjacentEdge && existingBorderSideToClear[adjacentEdge.position]) {
62376
62400
  for (const newZone of splitIfAdjacent(existingBorder.zone, zone)) {
62377
62401
  const border = this.computeBorderFromZone(newZone, existingBorder);
62378
62402
  const adjacentEdge = adjacent(newZone, zone);
62403
+ // Clear the existing border on the side that touches the new zone
62379
62404
  switch (adjacentEdge?.position) {
62380
62405
  case "left":
62381
62406
  border.style.left = undefined;
@@ -78669,6 +78694,7 @@ stores.inject(MyMetaStore, storeInstance);
78669
78694
  "getFigureUI",
78670
78695
  "getPositionAnchorOffset",
78671
78696
  "getGridOffset",
78697
+ "getMaximumSheetOffset",
78672
78698
  ];
78673
78699
  viewports = {};
78674
78700
  /**
@@ -80487,6 +80513,7 @@ stores.inject(MyMetaStore, storeInstance);
80487
80513
  .add("file", {
80488
80514
  name: _t("File"),
80489
80515
  sequence: 10,
80516
+ isReadonlyAllowed: true,
80490
80517
  })
80491
80518
  .addChild("settings", ["file"], {
80492
80519
  name: _t("Settings"),
@@ -80501,6 +80528,7 @@ stores.inject(MyMetaStore, storeInstance);
80501
80528
  .add("edit", {
80502
80529
  name: _t("Edit"),
80503
80530
  sequence: 20,
80531
+ isReadonlyAllowed: true,
80504
80532
  })
80505
80533
  .addChild("undo", ["edit"], {
80506
80534
  ...undo,
@@ -80585,6 +80613,7 @@ stores.inject(MyMetaStore, storeInstance);
80585
80613
  .add("view", {
80586
80614
  name: _t("View"),
80587
80615
  sequence: 30,
80616
+ isReadonlyAllowed: true,
80588
80617
  })
80589
80618
  .addChild("unfreeze_panes", ["view"], {
80590
80619
  ...unFreezePane,
@@ -80676,6 +80705,7 @@ stores.inject(MyMetaStore, storeInstance);
80676
80705
  .add("insert", {
80677
80706
  name: _t("Insert"),
80678
80707
  sequence: 40,
80708
+ isReadonlyAllowed: true,
80679
80709
  })
80680
80710
  .addChild("insert_row", ["insert"], {
80681
80711
  ...insertRow,
@@ -80787,7 +80817,11 @@ stores.inject(MyMetaStore, storeInstance);
80787
80817
  // ---------------------------------------------------------------------
80788
80818
  // FORMAT MENU ITEMS
80789
80819
  // ---------------------------------------------------------------------
80790
- .add("format", { name: _t("Format"), sequence: 50 })
80820
+ .add("format", {
80821
+ name: _t("Format"),
80822
+ sequence: 50,
80823
+ isReadonlyAllowed: true,
80824
+ })
80791
80825
  .addChild("format_number", ["format"], {
80792
80826
  ...formatNumberMenuItemSpec,
80793
80827
  name: _t("Number"),
@@ -80879,6 +80913,7 @@ stores.inject(MyMetaStore, storeInstance);
80879
80913
  .add("data", {
80880
80914
  name: _t("Data"),
80881
80915
  sequence: 60,
80916
+ isReadonlyAllowed: true,
80882
80917
  })
80883
80918
  .addChild("sort_range", ["data"], {
80884
80919
  ...sortRange,
@@ -81971,6 +82006,10 @@ stores.inject(MyMetaStore, storeInstance);
81971
82006
  useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
81972
82007
  const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
81973
82008
  return scrollY > 0;
82009
+ }, () => {
82010
+ const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
82011
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
82012
+ return scrollY < maxOffsetY;
81974
82013
  });
81975
82014
  }
81976
82015
  get gridContainer() {
@@ -84015,7 +84054,7 @@ stores.inject(MyMetaStore, storeInstance);
84015
84054
  border-radius: 4px;
84016
84055
  font-weight: 500;
84017
84056
  font-size: 14px;
84018
- height: 32px;
84057
+ min-height: 32px;
84019
84058
  line-height: 16px;
84020
84059
  flex-grow: 1;
84021
84060
  background-color: ${BUTTON_BG};
@@ -88968,9 +89007,9 @@ stores.inject(MyMetaStore, storeInstance);
88968
89007
  exports.tokenize = tokenize;
88969
89008
 
88970
89009
 
88971
- __info__.version = "19.0.9";
88972
- __info__.date = "2025-11-03T12:32:15.473Z";
88973
- __info__.hash = "10359f4";
89010
+ __info__.version = "19.0.11";
89011
+ __info__.date = "2025-11-24T07:46:47.685Z";
89012
+ __info__.hash = "f5bdbcc";
88974
89013
 
88975
89014
 
88976
89015
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);