@odoo/o-spreadsheet 18.3.8 → 18.3.10

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.3.8
6
- * @date 2025-06-12T09:51:55.929Z
7
- * @hash 32dedd1
5
+ * @version 18.3.10
6
+ * @date 2025-06-23T15:05:03.747Z
7
+ * @hash 748e300
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -141,6 +141,7 @@ const FROZEN_PANE_HEADER_BORDER_COLOR = "#BCBCBC";
141
141
  const FROZEN_PANE_BORDER_COLOR = "#DADFE8";
142
142
  const COMPOSER_ASSISTANT_COLOR = "#9B359B";
143
143
  const COLOR_TRANSPARENT = "#00000000";
144
+ const TABLE_HOVER_BACKGROUND_COLOR = "#017E8414";
144
145
  const CHART_WATERFALL_POSITIVE_COLOR = "#4EA7F2";
145
146
  const CHART_WATERFALL_NEGATIVE_COLOR = "#EA6175";
146
147
  const CHART_WATERFALL_SUBTOTAL_COLOR = "#AAAAAA";
@@ -7120,6 +7121,63 @@ function parseOSClipboardContent(content, clipboardId) {
7120
7121
  };
7121
7122
  return osClipboardContent;
7122
7123
  }
7124
+ /**
7125
+ * Applies each clipboard handler to paste its corresponding data into the target.
7126
+ */
7127
+ const applyClipboardHandlersPaste = (handlers, copiedData, target, options) => {
7128
+ handlers.forEach(({ handlerName, handler }) => {
7129
+ const data = copiedData[handlerName];
7130
+ if (data) {
7131
+ handler.paste(target, data, options);
7132
+ }
7133
+ });
7134
+ };
7135
+ /**
7136
+ * Returns the paste target based on clipboard handlers.
7137
+ * Also includes the full affected zone and the list of pasted zones for selection.
7138
+ */
7139
+ function getPasteTargetFromHandlers(sheetId, zones, copiedData, handlers, options) {
7140
+ let zone = undefined;
7141
+ let selectedZones = [];
7142
+ let target = {
7143
+ sheetId,
7144
+ zones,
7145
+ };
7146
+ for (const { handlerName, handler } of handlers) {
7147
+ const handlerData = copiedData[handlerName];
7148
+ if (!handlerData) {
7149
+ continue;
7150
+ }
7151
+ const currentTarget = handler.getPasteTarget(sheetId, zones, handlerData, options);
7152
+ if (currentTarget.figureId) {
7153
+ target.figureId = currentTarget.figureId;
7154
+ }
7155
+ for (const targetZone of currentTarget.zones) {
7156
+ selectedZones.push(targetZone);
7157
+ if (zone === undefined) {
7158
+ zone = targetZone;
7159
+ continue;
7160
+ }
7161
+ zone = union(zone, targetZone);
7162
+ }
7163
+ }
7164
+ return {
7165
+ target,
7166
+ zone,
7167
+ selectedZones,
7168
+ };
7169
+ }
7170
+ /**
7171
+ * Updates the selection after a paste operation.
7172
+ */
7173
+ const selectPastedZone = (selection, sourceZones, pastedZones) => {
7174
+ const anchorCell = {
7175
+ col: sourceZones[0].left,
7176
+ row: sourceZones[0].top,
7177
+ };
7178
+ selection.getBackToDefault();
7179
+ selection.selectZone({ cell: anchorCell, zone: union(...pastedZones) }, { scrollIntoView: false });
7180
+ };
7123
7181
 
7124
7182
  class ClipboardHandler {
7125
7183
  getters;
@@ -20951,6 +21009,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20951
21009
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
20952
21010
  continue;
20953
21011
  }
21012
+ const yAxisScale = chart.scales[dataset.yAxisID];
20954
21013
  for (let i = 0; i < dataset._parsed.length; i++) {
20955
21014
  const parsedValue = dataset._parsed[i];
20956
21015
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -20961,10 +21020,18 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20961
21020
  const xPosition = point.x;
20962
21021
  let yPosition = 0;
20963
21022
  if (chart.config.type === "line" || chart.config.type === "radar") {
20964
- yPosition = point.y - 10;
21023
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
20965
21024
  }
20966
21025
  else {
20967
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
21026
+ const yZeroLine = yAxisScale.getPixelForValue(0);
21027
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
21028
+ const textHeight = 12; // ChartJS default text height
21029
+ if (distanceFromAxisOrigin < textHeight) {
21030
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
21031
+ }
21032
+ else {
21033
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
21034
+ }
20968
21035
  }
20969
21036
  yPosition = Math.min(yPosition, yMax);
20970
21037
  yPosition = Math.max(yPosition, yMin);
@@ -20974,7 +21041,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20974
21041
  }
20975
21042
  for (const otherPosition of textsPositions[xPosition] || []) {
20976
21043
  if (Math.abs(otherPosition - yPosition) < 13) {
20977
- yPosition = otherPosition - 13;
21044
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
20978
21045
  }
20979
21046
  }
20980
21047
  textsPositions[xPosition].push(yPosition);
@@ -20993,6 +21060,8 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
20993
21060
  if (isTrendLineAxis(dataset.xAxisID)) {
20994
21061
  return; // ignore trend lines
20995
21062
  }
21063
+ const xAxisScale = chart.scales[dataset.xAxisID];
21064
+ const xZeroLine = xAxisScale.getPixelForValue(0);
20996
21065
  for (let i = 0; i < dataset._parsed.length; i++) {
20997
21066
  const value = Number(dataset._parsed[i].x);
20998
21067
  if (isNaN(value)) {
@@ -21001,17 +21070,27 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
21001
21070
  const displayValue = options.callback(value, dataset, i);
21002
21071
  const point = dataset.data[i];
21003
21072
  const yPosition = point.y;
21004
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21005
- xPosition = Math.min(xPosition, xMax);
21006
- xPosition = Math.max(xPosition, xMin);
21073
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21074
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
21075
+ const PADDING = 3;
21076
+ let xPosition;
21077
+ if (distanceFromAxisOrigin < textWidth) {
21078
+ xPosition =
21079
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
21080
+ }
21081
+ else {
21082
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21083
+ xPosition = Math.min(xPosition, xMax);
21084
+ xPosition = Math.max(xPosition, xMin);
21085
+ }
21007
21086
  // Avoid overlapping texts with same Y
21008
21087
  if (!textsPositions[yPosition]) {
21009
21088
  textsPositions[yPosition] = [];
21010
21089
  }
21011
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21012
21090
  for (const otherPosition of textsPositions[yPosition]) {
21013
21091
  if (Math.abs(otherPosition - xPosition) < textWidth) {
21014
- xPosition = otherPosition + textWidth + 3;
21092
+ xPosition =
21093
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
21015
21094
  }
21016
21095
  }
21017
21096
  textsPositions[yPosition].push(xPosition);
@@ -26398,7 +26477,9 @@ function getPyramidChartShowValues(definition, args) {
26398
26477
  background: definition.background,
26399
26478
  callback: (value, dataset) => {
26400
26479
  value = Math.abs(Number(value));
26401
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26480
+ return value === 0
26481
+ ? ""
26482
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26402
26483
  },
26403
26484
  };
26404
26485
  }
@@ -37131,6 +37212,10 @@ const REMOVE_ROWS_ACTION = (env) => {
37131
37212
  });
37132
37213
  };
37133
37214
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
37215
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
37216
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
37217
+ return false;
37218
+ }
37134
37219
  const sheetId = env.model.getters.getActiveSheetId();
37135
37220
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
37136
37221
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -40028,11 +40113,11 @@ class OTRegistry extends Registry {
40028
40113
  * transformation function given
40029
40114
  */
40030
40115
  addTransformation(executed, toTransforms, fn) {
40031
- for (let toTransform of toTransforms) {
40032
- if (!this.content[toTransform]) {
40033
- this.content[toTransform] = new Map();
40034
- }
40035
- this.content[toTransform].set(executed, fn);
40116
+ if (!this.content[executed]) {
40117
+ this.content[executed] = new Map();
40118
+ }
40119
+ for (const toTransform of toTransforms) {
40120
+ this.content[executed].set(toTransform, fn);
40036
40121
  }
40037
40122
  return this;
40038
40123
  }
@@ -40041,7 +40126,7 @@ class OTRegistry extends Registry {
40041
40126
  * that the executed command happened.
40042
40127
  */
40043
40128
  getTransformation(toTransform, executed) {
40044
- return this.content[toTransform] && this.content[toTransform].get(executed);
40129
+ return this.content[executed] && this.content[executed].get(toTransform);
40045
40130
  }
40046
40131
  }
40047
40132
  const otRegistry = new OTRegistry();
@@ -43331,6 +43416,12 @@ class Composer extends Component {
43331
43416
  useEffect(() => {
43332
43417
  this.processTokenAtCursor();
43333
43418
  }, () => [this.props.composerStore.editionMode !== "inactive"]);
43419
+ useEffect(() => {
43420
+ this.contentHelper.scrollSelectionIntoView();
43421
+ }, () => [
43422
+ this.props.composerStore.composerSelection.start,
43423
+ this.props.composerStore.composerSelection.end,
43424
+ ]);
43334
43425
  }
43335
43426
  // ---------------------------------------------------------------------------
43336
43427
  // Handlers
@@ -43553,6 +43644,7 @@ class Composer extends Component {
43553
43644
  // not main button, probably a context menu
43554
43645
  return;
43555
43646
  }
43647
+ this.debouncedHover.stopDebounce();
43556
43648
  this.contentHelper.removeSelection();
43557
43649
  }
43558
43650
  onMouseup() {
@@ -43631,7 +43723,6 @@ class Composer extends Component {
43631
43723
  const { start, end } = this.props.composerStore.composerSelection;
43632
43724
  this.contentHelper.selectRange(start, end);
43633
43725
  }
43634
- this.contentHelper.scrollSelectionIntoView();
43635
43726
  }
43636
43727
  this.shouldProcessInputEvents = true;
43637
43728
  }
@@ -49788,7 +49879,7 @@ class SpreadsheetPivot {
49788
49879
  }
49789
49880
  getTypeFromZone(sheetId, zone) {
49790
49881
  const cells = this.getters.getEvaluatedCellsInZone(sheetId, zone);
49791
- const nonEmptyCells = cells.filter((cell) => cell.type !== CellValueType.empty);
49882
+ const nonEmptyCells = cells.filter((cell) => !(cell.type === CellValueType.empty || cell.value === ""));
49792
49883
  if (nonEmptyCells.length === 0) {
49793
49884
  return "integer";
49794
49885
  }
@@ -53505,15 +53596,16 @@ class GridAddRowsFooter extends Component {
53505
53596
  }
53506
53597
  }
53507
53598
 
53599
+ const PAINT_FORMAT_HANDLER_KEYS = [
53600
+ "cell",
53601
+ "border",
53602
+ "table",
53603
+ "conditionalFormat",
53604
+ "merge",
53605
+ ];
53508
53606
  class PaintFormatStore extends SpreadsheetStore {
53509
53607
  mutators = ["activate", "cancel", "pasteFormat"];
53510
53608
  highlightStore = this.get(HighlightStore);
53511
- clipboardHandlers = [
53512
- new CellClipboardHandler(this.getters, this.model.dispatch),
53513
- new BorderClipboardHandler(this.getters, this.model.dispatch),
53514
- new TableClipboardHandler(this.getters, this.model.dispatch),
53515
- new ConditionalFormatClipboardHandler(this.getters, this.model.dispatch),
53516
- ];
53517
53609
  status = "inactive";
53518
53610
  copiedData;
53519
53611
  constructor(get) {
@@ -53544,24 +53636,38 @@ class PaintFormatStore extends SpreadsheetStore {
53544
53636
  get isActive() {
53545
53637
  return this.status !== "inactive";
53546
53638
  }
53639
+ get clipboardHandlers() {
53640
+ return PAINT_FORMAT_HANDLER_KEYS.map((handlerName) => {
53641
+ const HandlerClass = clipboardHandlersRegistries.cellHandlers.get(handlerName);
53642
+ return {
53643
+ handlerName,
53644
+ handler: new HandlerClass(this.getters, this.model.dispatch),
53645
+ };
53646
+ });
53647
+ }
53547
53648
  copyFormats() {
53548
53649
  const sheetId = this.getters.getActiveSheetId();
53549
53650
  const zones = this.getters.getSelectedZones();
53550
- const copiedData = {};
53551
- for (const handler of this.clipboardHandlers) {
53552
- Object.assign(copiedData, handler.copy(getClipboardDataPositions(sheetId, zones), false));
53651
+ const copiedData = { zones, sheetId };
53652
+ for (const { handlerName, handler } of this.clipboardHandlers) {
53653
+ const handlerResult = handler.copy(getClipboardDataPositions(sheetId, zones), false);
53654
+ if (handlerResult !== undefined) {
53655
+ copiedData[handlerName] = handlerResult;
53656
+ }
53553
53657
  }
53554
53658
  return copiedData;
53555
53659
  }
53556
53660
  paintFormat(sheetId, target) {
53557
- if (this.copiedData) {
53558
- for (const handler of this.clipboardHandlers) {
53559
- handler.paste({ zones: target, sheetId }, this.copiedData, {
53560
- isCutOperation: false,
53561
- pasteOption: "onlyFormat",
53562
- });
53563
- }
53661
+ if (!this.copiedData) {
53662
+ return;
53564
53663
  }
53664
+ const options = {
53665
+ isCutOperation: false,
53666
+ pasteOption: "onlyFormat",
53667
+ };
53668
+ const { target: pasteTarget, selectedZones } = getPasteTargetFromHandlers(sheetId, target, this.copiedData, this.clipboardHandlers, options);
53669
+ applyClipboardHandlersPaste(this.clipboardHandlers, this.copiedData, pasteTarget, options);
53670
+ selectPastedZone(this.model.selection, target, selectedZones);
53565
53671
  if (this.status === "oneOff") {
53566
53672
  this.cancel();
53567
53673
  }
@@ -53608,12 +53714,8 @@ class HoveredTableStore extends SpreadsheetStore {
53608
53714
  this.row = undefined;
53609
53715
  }
53610
53716
  computeOverlay() {
53611
- if (!this.getters.isDashboard()) {
53612
- return;
53613
- }
53614
53717
  this.overlayColors = new PositionMap();
53615
- const col = this.col;
53616
- const row = this.row;
53718
+ const { col, row } = this;
53617
53719
  if (col === undefined || row === undefined) {
53618
53720
  return;
53619
53721
  }
@@ -53622,9 +53724,16 @@ class HoveredTableStore extends SpreadsheetStore {
53622
53724
  if (!table) {
53623
53725
  return;
53624
53726
  }
53625
- const { left, right } = table.range.zone;
53626
- for (let c = left; c <= right; c++) {
53627
- this.overlayColors.set({ sheetId, col: c, row }, setColorAlpha("#017E84", 0.08));
53727
+ const { left, right, top } = table.range.zone;
53728
+ const isTableHeader = row < top + table.config.numberOfHeaders;
53729
+ const doesTableRowHaveContent = range(left, right + 1).some((col) => {
53730
+ return (!this.getters.isColHidden(sheetId, col) &&
53731
+ this.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue);
53732
+ });
53733
+ if (!isTableHeader && doesTableRowHaveContent) {
53734
+ for (let col = left; col <= right; col++) {
53735
+ this.overlayColors.set({ sheetId, col, row }, TABLE_HOVER_BACKGROUND_COLOR);
53736
+ }
53628
53737
  }
53629
53738
  }
53630
53739
  }
@@ -58971,7 +59080,7 @@ class DataValidationPlugin extends CorePlugin {
58971
59080
  else if (newRule.criterion.type === "isValueInList") {
58972
59081
  newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
58973
59082
  }
58974
- const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
59083
+ const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules, newRule.id);
58975
59084
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
58976
59085
  if (ruleIndex !== -1) {
58977
59086
  adaptedRules[ruleIndex] = newRule;
@@ -58981,9 +59090,12 @@ class DataValidationPlugin extends CorePlugin {
58981
59090
  this.history.update("rules", sheetId, [...adaptedRules, newRule]);
58982
59091
  }
58983
59092
  }
58984
- removeRangesFromRules(sheetId, ranges, rules) {
59093
+ removeRangesFromRules(sheetId, ranges, rules, editingRuleId) {
58985
59094
  rules = deepCopy(rules);
58986
59095
  for (const rule of rules) {
59096
+ if (rule.id === editingRuleId) {
59097
+ continue; // Skip the rule being edited to preserve its place in the list
59098
+ }
58987
59099
  rule.ranges = this.getters.recomputeRanges(rule.ranges, ranges);
58988
59100
  }
58989
59101
  return rules.filter((rule) => rule.ranges.length > 0);
@@ -67776,10 +67888,20 @@ function adaptTransform(toTransform, executed) {
67776
67888
  */
67777
67889
  function transformAll(toTransform, executed) {
67778
67890
  let transformedCommands = [...toTransform];
67891
+ const possibleTransformations = new Set(otRegistry.getKeys());
67779
67892
  for (const executedCommand of executed) {
67780
- transformedCommands = transformedCommands
67781
- .map((cmd) => transform(cmd, executedCommand))
67782
- .filter(isDefined);
67893
+ // If the executed command is not in the registry, we skip it
67894
+ // because we know there won't be any transformation impacting the
67895
+ // commands to transform.
67896
+ if (possibleTransformations.has(executedCommand.type)) {
67897
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
67898
+ const transformed = transform(cmd, executedCommand);
67899
+ if (transformed) {
67900
+ acc.push(transformed);
67901
+ }
67902
+ return acc;
67903
+ }, []);
67904
+ }
67783
67905
  }
67784
67906
  return transformedCommands;
67785
67907
  }
@@ -69481,7 +69603,7 @@ class SheetUIPlugin extends UIPlugin {
69481
69603
  }
69482
69604
  const position = this.getters.getCellPosition(cell.id);
69483
69605
  const colSize = this.getters.getColSize(sheetId, position.col);
69484
- if (cell.isFormula) {
69606
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
69485
69607
  const content = this.getters.getEvaluatedCell(position).formattedValue;
69486
69608
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
69487
69609
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -70801,49 +70923,17 @@ class ClipboardPlugin extends UIPlugin {
70801
70923
  if (!copiedData) {
70802
70924
  return;
70803
70925
  }
70804
- let zone = undefined;
70805
- let selectedZones = [];
70806
70926
  const sheetId = this.getters.getActiveSheetId();
70807
- let target = {
70808
- sheetId,
70809
- zones,
70810
- };
70811
70927
  const handlers = this.selectClipboardHandlers(copiedData);
70812
- for (const { handlerName, handler } of handlers) {
70813
- const handlerData = copiedData[handlerName];
70814
- if (!handlerData) {
70815
- continue;
70816
- }
70817
- const currentTarget = handler.getPasteTarget(sheetId, zones, handlerData, options);
70818
- if (currentTarget.figureId) {
70819
- target.figureId = currentTarget.figureId;
70820
- }
70821
- for (const targetZone of currentTarget.zones) {
70822
- selectedZones.push(targetZone);
70823
- if (zone === undefined) {
70824
- zone = targetZone;
70825
- continue;
70826
- }
70827
- zone = union(zone, targetZone);
70828
- }
70829
- }
70928
+ const { target, zone, selectedZones } = getPasteTargetFromHandlers(sheetId, zones, copiedData, handlers, options);
70830
70929
  if (zone !== undefined) {
70831
- this.addMissingDimensions(this.getters.getActiveSheetId(), zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
70930
+ this.addMissingDimensions(sheetId, zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
70832
70931
  }
70833
- handlers.forEach(({ handlerName, handler }) => {
70834
- const handlerData = copiedData[handlerName];
70835
- if (handlerData) {
70836
- handler.paste(target, handlerData, options);
70837
- }
70838
- });
70932
+ applyClipboardHandlersPaste(handlers, copiedData, target, options);
70839
70933
  if (!options?.selectTarget) {
70840
70934
  return;
70841
70935
  }
70842
- const selection = zones[0];
70843
- const col = selection.left;
70844
- const row = selection.top;
70845
- this.selection.getBackToDefault();
70846
- this.selection.selectZone({ cell: { col, row }, zone: union(...selectedZones) }, { scrollIntoView: false });
70936
+ selectPastedZone(this.selection, zones, selectedZones);
70847
70937
  }
70848
70938
  /**
70849
70939
  * Add columns and/or rows to ensure that col + width and row + height are still
@@ -80620,6 +80710,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
80620
80710
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
80621
80711
 
80622
80712
 
80623
- __info__.version = "18.3.8";
80624
- __info__.date = "2025-06-12T09:51:55.929Z";
80625
- __info__.hash = "32dedd1";
80713
+ __info__.version = "18.3.10";
80714
+ __info__.date = "2025-06-23T15:05:03.747Z";
80715
+ __info__.hash = "748e300";