@odoo/o-spreadsheet 19.0.10 → 19.0.12
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.
- package/dist/o-spreadsheet.cjs.js +344 -220
- package/dist/o-spreadsheet.d.ts +47 -14
- package/dist/o-spreadsheet.esm.js +344 -220
- package/dist/o-spreadsheet.iife.js +344 -220
- package/dist/o-spreadsheet.iife.min.js +432 -432
- package/dist/o_spreadsheet.xml +50 -10
- package/package.json +1 -1
|
@@ -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.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.12
|
|
6
|
+
* @date 2025-12-02T05:34:17.495Z
|
|
7
|
+
* @hash 32203f1
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -181,7 +181,6 @@ const invalidateEvaluationCommands = new Set([
|
|
|
181
181
|
"REDO",
|
|
182
182
|
"ADD_MERGE",
|
|
183
183
|
"REMOVE_MERGE",
|
|
184
|
-
"DUPLICATE_SHEET",
|
|
185
184
|
"UPDATE_LOCALE",
|
|
186
185
|
"ADD_PIVOT",
|
|
187
186
|
"UPDATE_PIVOT",
|
|
@@ -862,7 +861,7 @@ const PIVOT_TABLE_CONFIG = {
|
|
|
862
861
|
};
|
|
863
862
|
const PIVOT_INDENT = 15;
|
|
864
863
|
const PIVOT_COLLAPSE_ICON_SIZE = 12;
|
|
865
|
-
const PIVOT_MAX_NUMBER_OF_CELLS =
|
|
864
|
+
const PIVOT_MAX_NUMBER_OF_CELLS = 5e5;
|
|
866
865
|
const DEFAULT_CURRENCY = {
|
|
867
866
|
symbol: "$",
|
|
868
867
|
position: "before",
|
|
@@ -13348,7 +13347,7 @@ const SUBTOTAL = {
|
|
|
13348
13347
|
if (!acceptHiddenCells && this.getters.isRowHiddenByUser(sheetId, row))
|
|
13349
13348
|
continue;
|
|
13350
13349
|
for (let col = left; col <= right; col++) {
|
|
13351
|
-
const cell = this.getters.
|
|
13350
|
+
const cell = this.getters.getCorrespondingFormulaCell({ sheetId, col, row });
|
|
13352
13351
|
if (!cell || !isSubtotalCell(cell)) {
|
|
13353
13352
|
evaluatedCellToKeep.push(this.getters.getEvaluatedCell({ sheetId, col, row }));
|
|
13354
13353
|
}
|
|
@@ -19344,7 +19343,7 @@ function getTokenNextReferenceType(xc) {
|
|
|
19344
19343
|
function setXcToFixedReferenceType(xc, referenceType) {
|
|
19345
19344
|
let sheetName;
|
|
19346
19345
|
({ sheetName, xc } = splitReference(xc));
|
|
19347
|
-
sheetName = sheetName ? sheetName + "!" : "";
|
|
19346
|
+
sheetName = sheetName ? getCanonicalSymbolName(sheetName) + "!" : "";
|
|
19348
19347
|
xc = xc.replace(/\$/g, "");
|
|
19349
19348
|
const splitIndex = xc.indexOf(":");
|
|
19350
19349
|
if (splitIndex >= 0) {
|
|
@@ -23877,6 +23876,9 @@ function getTreeMapGroupColors(definition, tree) {
|
|
|
23877
23876
|
}));
|
|
23878
23877
|
}
|
|
23879
23878
|
function getTreeMapColorScale(tree, coloringOption) {
|
|
23879
|
+
if (tree.length === 0) {
|
|
23880
|
+
return undefined;
|
|
23881
|
+
}
|
|
23880
23882
|
const treeNodesByLevel = pyramidizeTree(tree);
|
|
23881
23883
|
const nodes = treeNodesByLevel[treeNodesByLevel.length - 1];
|
|
23882
23884
|
const minValue = Math.min(...nodes.map((node) => node.value));
|
|
@@ -25562,11 +25564,18 @@ function chartToImageUrl(runtime, figure, type) {
|
|
|
25562
25564
|
// we have to add the canvas to the DOM otherwise it won't be rendered
|
|
25563
25565
|
document.body.append(div);
|
|
25564
25566
|
if ("chartJsConfig" in runtime) {
|
|
25567
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
25568
|
+
if (!extensionsLoaded) {
|
|
25569
|
+
registerChartJSExtensions();
|
|
25570
|
+
}
|
|
25565
25571
|
const config = deepCopy(runtime.chartJsConfig);
|
|
25566
25572
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
25567
25573
|
const chart = new window.Chart(canvas, config);
|
|
25568
25574
|
imageContent = chart.toBase64Image();
|
|
25569
25575
|
chart.destroy();
|
|
25576
|
+
if (!extensionsLoaded) {
|
|
25577
|
+
unregisterChartJsExtensions();
|
|
25578
|
+
}
|
|
25570
25579
|
}
|
|
25571
25580
|
else if (type === "scorecard") {
|
|
25572
25581
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -25596,11 +25605,18 @@ async function chartToImageFile(runtime, figure, type) {
|
|
|
25596
25605
|
document.body.append(div);
|
|
25597
25606
|
let chartBlob = null;
|
|
25598
25607
|
if ("chartJsConfig" in runtime) {
|
|
25608
|
+
const extensionsLoaded = areChartJSExtensionsLoaded();
|
|
25609
|
+
if (!extensionsLoaded) {
|
|
25610
|
+
registerChartJSExtensions();
|
|
25611
|
+
}
|
|
25599
25612
|
const config = deepCopy(runtime.chartJsConfig);
|
|
25600
25613
|
config.plugins = [backgroundColorChartJSPlugin];
|
|
25601
25614
|
const chart = new window.Chart(canvas, config);
|
|
25602
25615
|
chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
25603
25616
|
chart.destroy();
|
|
25617
|
+
if (!extensionsLoaded) {
|
|
25618
|
+
unregisterChartJsExtensions();
|
|
25619
|
+
}
|
|
25604
25620
|
}
|
|
25605
25621
|
else if (type === "scorecard") {
|
|
25606
25622
|
const design = getScorecardConfiguration(figure, runtime);
|
|
@@ -27726,29 +27742,19 @@ class ZoomableChartStore extends SpreadsheetStore {
|
|
|
27726
27742
|
}
|
|
27727
27743
|
resetAxisLimits(chartId, limits) {
|
|
27728
27744
|
for (const axisId of ZOOMABLE_AXIS_IDS) {
|
|
27729
|
-
if (limits
|
|
27730
|
-
|
|
27731
|
-
this.originalAxisLimits[chartId]
|
|
27732
|
-
|
|
27733
|
-
|
|
27734
|
-
};
|
|
27735
|
-
}
|
|
27736
|
-
this.originalAxisLimits[chartId][axisId]["min"] = limits[axisId].min;
|
|
27737
|
-
this.originalAxisLimits[chartId][axisId]["max"] = limits[axisId].max;
|
|
27745
|
+
if (limits[axisId]) {
|
|
27746
|
+
this.originalAxisLimits[chartId] = {
|
|
27747
|
+
...this.originalAxisLimits[chartId],
|
|
27748
|
+
[axisId]: { ...limits[axisId] },
|
|
27749
|
+
};
|
|
27738
27750
|
}
|
|
27739
|
-
else {
|
|
27740
|
-
|
|
27741
|
-
delete this.originalAxisLimits[chartId][axisId];
|
|
27742
|
-
}
|
|
27751
|
+
else if (this.originalAxisLimits[chartId]?.[axisId]) {
|
|
27752
|
+
delete this.originalAxisLimits[chartId][axisId];
|
|
27743
27753
|
}
|
|
27744
27754
|
}
|
|
27745
27755
|
return "noStateChange";
|
|
27746
27756
|
}
|
|
27747
27757
|
updateAxisLimits(chartId, limits) {
|
|
27748
|
-
if (limits === undefined) {
|
|
27749
|
-
delete this.currentAxesLimits[chartId];
|
|
27750
|
-
return "noStateChange";
|
|
27751
|
-
}
|
|
27752
27758
|
let { min, max } = limits;
|
|
27753
27759
|
if (min > max) {
|
|
27754
27760
|
[min, max] = [max, min];
|
|
@@ -27764,26 +27770,14 @@ class ZoomableChartStore extends SpreadsheetStore {
|
|
|
27764
27770
|
* for the current trend line axes.
|
|
27765
27771
|
*/
|
|
27766
27772
|
updateTrendLineConfiguration(chartId) {
|
|
27767
|
-
if (!this.originalAxisLimits[chartId]) {
|
|
27773
|
+
if (!this.originalAxisLimits[chartId]?.x || !this.currentAxesLimits[chartId]?.x) {
|
|
27768
27774
|
return "noStateChange";
|
|
27769
27775
|
}
|
|
27770
27776
|
const chartLimits = this.originalAxisLimits[chartId].x;
|
|
27771
|
-
if (chartLimits === undefined) {
|
|
27772
|
-
return "noStateChange";
|
|
27773
|
-
}
|
|
27774
27777
|
for (const axisId of TREND_LINE_AXES_IDS) {
|
|
27775
27778
|
if (!this.originalAxisLimits[chartId][axisId]) {
|
|
27776
27779
|
continue;
|
|
27777
27780
|
}
|
|
27778
|
-
if (!this.currentAxesLimits[chartId]?.[axisId]) {
|
|
27779
|
-
this.currentAxesLimits[chartId] = {
|
|
27780
|
-
...this.currentAxesLimits[chartId],
|
|
27781
|
-
[axisId]: {},
|
|
27782
|
-
};
|
|
27783
|
-
}
|
|
27784
|
-
if (this.currentAxesLimits[chartId]?.x === undefined) {
|
|
27785
|
-
return "noStateChange";
|
|
27786
|
-
}
|
|
27787
27781
|
const realRange = chartLimits.max - chartLimits.min;
|
|
27788
27782
|
const trendingLimits = this.originalAxisLimits[chartId][axisId];
|
|
27789
27783
|
const trendingRange = trendingLimits.max - trendingLimits.min;
|
|
@@ -27791,8 +27785,10 @@ class ZoomableChartStore extends SpreadsheetStore {
|
|
|
27791
27785
|
const intercept = trendingLimits.min - chartLimits.min * slope;
|
|
27792
27786
|
const newXMin = this.currentAxesLimits[chartId].x.min;
|
|
27793
27787
|
const newXMax = this.currentAxesLimits[chartId].x.max;
|
|
27794
|
-
this.currentAxesLimits[chartId][axisId]
|
|
27795
|
-
|
|
27788
|
+
this.currentAxesLimits[chartId][axisId] = {
|
|
27789
|
+
min: newXMin * slope + intercept,
|
|
27790
|
+
max: newXMax * slope + intercept,
|
|
27791
|
+
};
|
|
27796
27792
|
}
|
|
27797
27793
|
return "noStateChange";
|
|
27798
27794
|
}
|
|
@@ -27861,8 +27857,9 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27861
27857
|
hasLinearScale;
|
|
27862
27858
|
isBarChart;
|
|
27863
27859
|
chartId = "";
|
|
27864
|
-
datasetBoundaries = {
|
|
27860
|
+
datasetBoundaries = { min: 0, max: 0 };
|
|
27865
27861
|
removeEventListeners = () => { };
|
|
27862
|
+
isMasterChartAllowed = false;
|
|
27866
27863
|
setup() {
|
|
27867
27864
|
this.store = useStore(ZoomableChartStore);
|
|
27868
27865
|
super.setup();
|
|
@@ -27878,12 +27875,19 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27878
27875
|
height:${height};
|
|
27879
27876
|
`;
|
|
27880
27877
|
}
|
|
27878
|
+
get masterChartContainerStyle() {
|
|
27879
|
+
const runtime = this.env.model.getters.getChartRuntime(this.props.chartId);
|
|
27880
|
+
if (runtime && !runtime.chartJsConfig.data.datasets.some((ds) => ds.data.length > 1)) {
|
|
27881
|
+
return "opacity: 0.3;";
|
|
27882
|
+
}
|
|
27883
|
+
return "";
|
|
27884
|
+
}
|
|
27881
27885
|
get sliceable() {
|
|
27882
27886
|
if (this.props.isFullScreen) {
|
|
27883
27887
|
return true;
|
|
27884
27888
|
}
|
|
27885
27889
|
const definition = this.env.model.getters.getChartDefinition(this.props.chartId);
|
|
27886
|
-
return ("zoomable" in definition && definition
|
|
27890
|
+
return ("zoomable" in definition && definition.zoomable) ?? false;
|
|
27887
27891
|
}
|
|
27888
27892
|
get axisOffset() {
|
|
27889
27893
|
return !this.hasLinearScale && this.isBarChart ? 0.5 : 0;
|
|
@@ -27908,15 +27912,13 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27908
27912
|
if (!this.sliceable) {
|
|
27909
27913
|
return chartData;
|
|
27910
27914
|
}
|
|
27911
|
-
|
|
27912
|
-
const
|
|
27913
|
-
|
|
27914
|
-
|
|
27915
|
-
|
|
27916
|
-
|
|
27917
|
-
|
|
27918
|
-
if (xAxis?.max !== undefined) {
|
|
27919
|
-
xScale.max = this.hasLinearScale ? xAxis.max : Math.floor(xAxis.max) - this.axisOffset;
|
|
27915
|
+
let x = chartData.options.scales.x;
|
|
27916
|
+
const limits = this.store.currentAxesLimits[this.chartId]?.x;
|
|
27917
|
+
if (limits) {
|
|
27918
|
+
x = {
|
|
27919
|
+
...x,
|
|
27920
|
+
...this.getStoredBoundaries(),
|
|
27921
|
+
};
|
|
27920
27922
|
}
|
|
27921
27923
|
return {
|
|
27922
27924
|
...chartData,
|
|
@@ -27924,7 +27926,7 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27924
27926
|
...chartData.options,
|
|
27925
27927
|
scales: {
|
|
27926
27928
|
...chartData.options.scales,
|
|
27927
|
-
x
|
|
27929
|
+
x,
|
|
27928
27930
|
},
|
|
27929
27931
|
layout: {
|
|
27930
27932
|
...chartData.options.layout,
|
|
@@ -27939,9 +27941,19 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27939
27941
|
getAxisLimitsFromDataset(chartData) {
|
|
27940
27942
|
const data = chartData.data.datasets.map((ds) => ds.data).flat();
|
|
27941
27943
|
const xValues = data.map((d, i) => (typeof d === "object" && d !== null ? d.x : i));
|
|
27942
|
-
const
|
|
27943
|
-
const
|
|
27944
|
-
return {
|
|
27944
|
+
const min = Math.min(...xValues);
|
|
27945
|
+
const max = Math.max(...xValues);
|
|
27946
|
+
return { min, max };
|
|
27947
|
+
}
|
|
27948
|
+
setMasterChartCursor(runtime) {
|
|
27949
|
+
const masterElement = this.masterChartCanvas?.el;
|
|
27950
|
+
if (runtime && !runtime.chartJsConfig.data.datasets.some((ds) => ds.data.length > 1)) {
|
|
27951
|
+
masterElement.style.cursor = "not-allowed";
|
|
27952
|
+
this.isMasterChartAllowed = false;
|
|
27953
|
+
return;
|
|
27954
|
+
}
|
|
27955
|
+
masterElement.style.cursor = "default";
|
|
27956
|
+
this.isMasterChartAllowed = true;
|
|
27945
27957
|
}
|
|
27946
27958
|
createChart(chartRuntime) {
|
|
27947
27959
|
const chartData = chartRuntime.chartJsConfig;
|
|
@@ -27953,12 +27965,14 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27953
27965
|
chartRuntime.chartJsConfig = updatedData;
|
|
27954
27966
|
}
|
|
27955
27967
|
super.createChart(chartRuntime);
|
|
27956
|
-
this.hasLinearScale = this.chart?.scales?.x
|
|
27968
|
+
this.hasLinearScale = this.chart?.scales?.x?.type === "linear";
|
|
27957
27969
|
if (!this.sliceable || !("masterChartConfig" in chartRuntime)) {
|
|
27970
|
+
this.isMasterChartAllowed = false;
|
|
27958
27971
|
return;
|
|
27959
27972
|
}
|
|
27960
27973
|
this.masterChart?.destroy();
|
|
27961
|
-
const masterChartCtx = this.masterChartCanvas
|
|
27974
|
+
const masterChartCtx = (this.masterChartCanvas?.el).getContext("2d");
|
|
27975
|
+
this.setMasterChartCursor(chartRuntime);
|
|
27962
27976
|
this.masterChart = new window.Chart(masterChartCtx, this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]));
|
|
27963
27977
|
this.resetAxesLimits();
|
|
27964
27978
|
if (this.chart?.options) {
|
|
@@ -27967,11 +27981,10 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27967
27981
|
}
|
|
27968
27982
|
updateChartJs(chartRuntime) {
|
|
27969
27983
|
const chartData = chartRuntime.chartJsConfig;
|
|
27970
|
-
const
|
|
27971
|
-
if (this.datasetBoundaries.
|
|
27972
|
-
this.datasetBoundaries.xMax !== newDatasetBoundaries.xMax) {
|
|
27984
|
+
const { min, max } = this.getAxisLimitsFromDataset(chartData);
|
|
27985
|
+
if (this.datasetBoundaries.min !== min || this.datasetBoundaries.max !== max) {
|
|
27973
27986
|
this.store.clearAxisLimits(this.chartId);
|
|
27974
|
-
this.datasetBoundaries =
|
|
27987
|
+
this.datasetBoundaries = { min, max };
|
|
27975
27988
|
}
|
|
27976
27989
|
this.isBarChart = chartData?.type === "bar";
|
|
27977
27990
|
this.chartId = `${chartData.type}-${this.props.chartId}`;
|
|
@@ -27980,9 +27993,10 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27980
27993
|
chartRuntime.chartJsConfig = updatedData;
|
|
27981
27994
|
}
|
|
27982
27995
|
super.updateChartJs(chartRuntime);
|
|
27983
|
-
this.hasLinearScale = this.chart?.scales?.x
|
|
27996
|
+
this.hasLinearScale = this.chart?.scales?.x?.type === "linear";
|
|
27984
27997
|
if (!this.sliceable || !("masterChartConfig" in chartRuntime)) {
|
|
27985
27998
|
this.masterChart = undefined;
|
|
27999
|
+
this.isMasterChartAllowed = false;
|
|
27986
28000
|
}
|
|
27987
28001
|
else {
|
|
27988
28002
|
const masterChartConfig = this.getMasterChartConfiguration(chartRuntime["masterChartConfig"]);
|
|
@@ -27995,6 +28009,7 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
27995
28009
|
this.masterChart.config.options = masterChartConfig.options;
|
|
27996
28010
|
this.masterChart.update();
|
|
27997
28011
|
}
|
|
28012
|
+
this.setMasterChartCursor(chartRuntime);
|
|
27998
28013
|
}
|
|
27999
28014
|
this.resetAxesLimits();
|
|
28000
28015
|
if (this.chart?.options) {
|
|
@@ -28005,18 +28020,15 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28005
28020
|
if (!this.chart) {
|
|
28006
28021
|
return;
|
|
28007
28022
|
}
|
|
28008
|
-
const
|
|
28009
|
-
if (
|
|
28023
|
+
const storedLimits = this.store.originalAxisLimits[this.chartId]?.x;
|
|
28024
|
+
if (!storedLimits) {
|
|
28010
28025
|
let scales = this.masterChart
|
|
28011
28026
|
? this.masterChart.scales
|
|
28012
28027
|
: this.chart.scales;
|
|
28013
|
-
if (!this.hasLinearScale && scales
|
|
28028
|
+
if (!this.hasLinearScale && scales.x) {
|
|
28014
28029
|
scales = {
|
|
28015
28030
|
...scales,
|
|
28016
|
-
x:
|
|
28017
|
-
min: Math.ceil(scales.x.min) - this.axisOffset,
|
|
28018
|
-
max: Math.floor(scales.x.max) + this.axisOffset,
|
|
28019
|
-
},
|
|
28031
|
+
x: this.adjustBoundaries(scales.x),
|
|
28020
28032
|
};
|
|
28021
28033
|
}
|
|
28022
28034
|
this.store.resetAxisLimits(this.chartId, scales);
|
|
@@ -28031,13 +28043,13 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28031
28043
|
}
|
|
28032
28044
|
updateTrendingLineAxes() {
|
|
28033
28045
|
this.store.updateTrendLineConfiguration(this.chartId);
|
|
28034
|
-
const
|
|
28046
|
+
const limits = this.store.currentAxesLimits[this.chartId];
|
|
28035
28047
|
for (const axisId of [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
|
|
28036
|
-
if (!this.chart?.config
|
|
28048
|
+
if (!this.chart?.config?.options?.scales?.[axisId] || !limits?.[axisId]) {
|
|
28037
28049
|
continue;
|
|
28038
28050
|
}
|
|
28039
|
-
this.chart.config.options.scales[axisId].min =
|
|
28040
|
-
this.chart.config.options.scales[axisId].max =
|
|
28051
|
+
this.chart.config.options.scales[axisId].min = limits[axisId].min;
|
|
28052
|
+
this.chart.config.options.scales[axisId].max = limits[axisId].max;
|
|
28041
28053
|
}
|
|
28042
28054
|
}
|
|
28043
28055
|
get upperBound() {
|
|
@@ -28080,29 +28092,71 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28080
28092
|
offset +
|
|
28081
28093
|
((scale.max + 2 * offset - scale.min) * (position - left)) / (right - left));
|
|
28082
28094
|
}
|
|
28083
|
-
|
|
28095
|
+
/**
|
|
28096
|
+
* Compute min and max from the store, adjusting them if needed for non linear scales.
|
|
28097
|
+
* Getting the value from the store, we have to ensure that the values are integers for
|
|
28098
|
+
* non linear scales (bar and category). To select a bar in the chart, we have to include
|
|
28099
|
+
* the whole bar, which means that for the i-th bar, the selected min should be <= i and
|
|
28100
|
+
* the selected max should be >= i, so using the Math.floor and Math.ceil functions is
|
|
28101
|
+
* the right way to do it.
|
|
28102
|
+
* Sometimes, we can get a minimal value > the maximal value, which arise when the user
|
|
28103
|
+
* select a very small area in the master chart, and hasn't selected the middle of a bar
|
|
28104
|
+
* or a group of bars (in case of more than one data series).
|
|
28105
|
+
* Assuming we have to select the middle of a bar/a groupe of bars, we will reject the
|
|
28106
|
+
* coming value afterward. In this case, we do not update the chart because it would lead
|
|
28107
|
+
* to an empty chart.
|
|
28108
|
+
*/
|
|
28109
|
+
getStoredBoundaries() {
|
|
28110
|
+
let { min, max } = this.store.currentAxesLimits[this.chartId].x;
|
|
28084
28111
|
if (!this.hasLinearScale) {
|
|
28085
|
-
|
|
28086
|
-
|
|
28112
|
+
min = Math.ceil(min);
|
|
28113
|
+
max = Math.floor(max);
|
|
28087
28114
|
}
|
|
28088
|
-
|
|
28089
|
-
|
|
28090
|
-
|
|
28115
|
+
return { min, max };
|
|
28116
|
+
}
|
|
28117
|
+
/**
|
|
28118
|
+
* Adjust the min and max values of an axis if needed for non linear scales.
|
|
28119
|
+
* Here, after rounding (see docstring of getStoredBoundaries), we adjust the min by
|
|
28120
|
+
* substracting the axis offset, and we add it to the max, because when computing from the
|
|
28121
|
+
* scale, chartJs use integer values as the limits for non linear scales. If we have a min
|
|
28122
|
+
* value of 1, it means we want to start displaying from 0.5, and if we have a max value of
|
|
28123
|
+
* 4, it means we want to display until 4.5.
|
|
28124
|
+
* Here, we don't have to check if min > max because we are computing from the scale, and
|
|
28125
|
+
* chartJs ensures that this won't happen, even after our adjustments.
|
|
28126
|
+
*/
|
|
28127
|
+
adjustBoundaries({ min, max }) {
|
|
28128
|
+
if (!this.hasLinearScale) {
|
|
28129
|
+
min = Math.ceil(min) - this.axisOffset;
|
|
28130
|
+
max = Math.floor(max) + this.axisOffset;
|
|
28131
|
+
}
|
|
28132
|
+
return { min, max };
|
|
28133
|
+
}
|
|
28134
|
+
updateAxisLimits(xMin, xMax) {
|
|
28135
|
+
if (xMin === xMax) {
|
|
28136
|
+
return;
|
|
28137
|
+
}
|
|
28138
|
+
if (!this.chart) {
|
|
28139
|
+
return;
|
|
28091
28140
|
}
|
|
28092
28141
|
this.store.updateAxisLimits(this.chartId, { min: xMin, max: xMax });
|
|
28093
|
-
this.
|
|
28142
|
+
const { min, max } = this.getStoredBoundaries();
|
|
28143
|
+
if (max > min || (this.isBarChart && max === min)) {
|
|
28144
|
+
this.chart.config.options.scales.x.min = min;
|
|
28145
|
+
this.chart.config.options.scales.x.max = max;
|
|
28146
|
+
this.updateTrendingLineAxes();
|
|
28147
|
+
this.chart.update();
|
|
28148
|
+
}
|
|
28094
28149
|
this.masterChart?.update();
|
|
28095
|
-
this.chart?.update();
|
|
28096
28150
|
}
|
|
28097
|
-
|
|
28151
|
+
onMasterChartPointerDown(ev) {
|
|
28098
28152
|
this.removeEventListeners();
|
|
28099
28153
|
const position = ev.offsetX;
|
|
28100
28154
|
if (!this.masterChart?.chartArea || !this.chart?.scales?.x) {
|
|
28101
28155
|
return;
|
|
28102
28156
|
}
|
|
28103
28157
|
const { left, right, top, bottom } = this.masterChart.chartArea;
|
|
28104
|
-
const
|
|
28105
|
-
const
|
|
28158
|
+
const upperBound = this.upperBound ?? right;
|
|
28159
|
+
const lowerBound = this.lowerBound ?? left;
|
|
28106
28160
|
if (position < left - 5 || position > right + 5 || ev.offsetY < top || ev.offsetY > bottom) {
|
|
28107
28161
|
return;
|
|
28108
28162
|
}
|
|
@@ -28110,8 +28164,10 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28110
28164
|
ev.stopPropagation();
|
|
28111
28165
|
let startingPositionOnChart, windowSize, startX;
|
|
28112
28166
|
const startingEventPosition = ev.clientX - (this.masterChartCanvas.el?.getBoundingClientRect().left ?? 0);
|
|
28113
|
-
if ((
|
|
28114
|
-
|
|
28167
|
+
if ((lowerBound !== left || upperBound !== right) &&
|
|
28168
|
+
position > lowerBound + 5 &&
|
|
28169
|
+
position < upperBound - 5) {
|
|
28170
|
+
startingPositionOnChart = ev.offsetX - lowerBound;
|
|
28115
28171
|
this.mode = "moveInMaster";
|
|
28116
28172
|
const currentLimits = this.store.currentAxesLimits[this.chartId]?.x;
|
|
28117
28173
|
windowSize =
|
|
@@ -28120,31 +28176,29 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28120
28176
|
}
|
|
28121
28177
|
else {
|
|
28122
28178
|
this.mode = "selectInMaster";
|
|
28123
|
-
if (Math.abs(position -
|
|
28124
|
-
startingPositionOnChart =
|
|
28179
|
+
if (Math.abs(position - lowerBound) < 5) {
|
|
28180
|
+
startingPositionOnChart = upperBound;
|
|
28125
28181
|
}
|
|
28126
|
-
else if (Math.abs(position -
|
|
28127
|
-
startingPositionOnChart =
|
|
28182
|
+
else if (Math.abs(position - upperBound) < 5) {
|
|
28183
|
+
startingPositionOnChart = lowerBound;
|
|
28128
28184
|
}
|
|
28129
28185
|
else {
|
|
28130
28186
|
startingPositionOnChart = clip(position, left, right);
|
|
28131
28187
|
}
|
|
28132
28188
|
startX = this.computeCoordinate(startingPositionOnChart);
|
|
28133
28189
|
}
|
|
28134
|
-
const
|
|
28135
|
-
const
|
|
28190
|
+
const storedMin = this.store.originalAxisLimits[this.chartId].x.min;
|
|
28191
|
+
const storedMax = this.store.originalAxisLimits[this.chartId].x.max;
|
|
28136
28192
|
const computeNewAxisLimits = (position) => {
|
|
28137
|
-
let xMin, xMax;
|
|
28138
|
-
const { left, right } = this.masterChart.chartArea;
|
|
28139
28193
|
if (this.mode === "moveInMaster") {
|
|
28140
|
-
|
|
28141
|
-
if (
|
|
28142
|
-
|
|
28194
|
+
let min = this.computeCoordinate(position - startingPositionOnChart);
|
|
28195
|
+
if (min < storedMin) {
|
|
28196
|
+
min = storedMin;
|
|
28143
28197
|
}
|
|
28144
|
-
else if (
|
|
28145
|
-
|
|
28198
|
+
else if (min > storedMax - windowSize) {
|
|
28199
|
+
min = storedMax - windowSize;
|
|
28146
28200
|
}
|
|
28147
|
-
|
|
28201
|
+
return { min, max: min + windowSize };
|
|
28148
28202
|
}
|
|
28149
28203
|
else if (this.mode === "selectInMaster") {
|
|
28150
28204
|
const upperBound = clip(position, left, right);
|
|
@@ -28153,54 +28207,52 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28153
28207
|
if (startX === undefined || endX === undefined) {
|
|
28154
28208
|
return {};
|
|
28155
28209
|
}
|
|
28156
|
-
|
|
28157
|
-
|
|
28210
|
+
return {
|
|
28211
|
+
min: Math.min(startX, endX),
|
|
28212
|
+
max: Math.max(startX, endX),
|
|
28213
|
+
};
|
|
28158
28214
|
}
|
|
28159
28215
|
}
|
|
28160
|
-
return {
|
|
28216
|
+
return {};
|
|
28161
28217
|
};
|
|
28162
|
-
const
|
|
28218
|
+
const onMasterChartDrag = (ev) => {
|
|
28163
28219
|
const position = ev.clientX - (this.masterChartCanvas.el?.getBoundingClientRect().left ?? 0);
|
|
28164
28220
|
if (Math.abs(position - startingEventPosition) < 5) {
|
|
28165
28221
|
return;
|
|
28166
28222
|
}
|
|
28167
|
-
const { min
|
|
28168
|
-
if (
|
|
28169
|
-
this.updateAxisLimits(
|
|
28223
|
+
const { min, max } = computeNewAxisLimits(position);
|
|
28224
|
+
if (min !== undefined && max !== undefined) {
|
|
28225
|
+
this.updateAxisLimits(min, max);
|
|
28170
28226
|
}
|
|
28171
28227
|
};
|
|
28172
|
-
const
|
|
28228
|
+
const onMasterChartPointerUp = (ev) => {
|
|
28173
28229
|
this.removeEventListeners();
|
|
28174
|
-
|
|
28175
|
-
if (
|
|
28176
|
-
|
|
28177
|
-
|
|
28178
|
-
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
}
|
|
28183
|
-
else {
|
|
28184
|
-
xMin = Math.ceil(xMin) - this.axisOffset;
|
|
28185
|
-
xMax = Math.floor(xMax) + this.axisOffset;
|
|
28186
|
-
}
|
|
28187
|
-
}
|
|
28188
|
-
this.updateAxisLimits(xMin, xMax);
|
|
28230
|
+
let { min, max } = this.chart.scales.x;
|
|
28231
|
+
if (!this.hasLinearScale) {
|
|
28232
|
+
if (this.mode === "moveInMaster") {
|
|
28233
|
+
min = Math.round(min) - this.axisOffset;
|
|
28234
|
+
max = min + windowSize;
|
|
28235
|
+
}
|
|
28236
|
+
else {
|
|
28237
|
+
({ min, max } = this.adjustBoundaries({ min, max }));
|
|
28189
28238
|
}
|
|
28190
28239
|
}
|
|
28240
|
+
this.updateAxisLimits(min, max);
|
|
28191
28241
|
this.mode = undefined;
|
|
28192
28242
|
};
|
|
28193
28243
|
this.removeEventListeners = () => {
|
|
28194
|
-
window.removeEventListener("pointermove",
|
|
28195
|
-
window.removeEventListener("pointerup",
|
|
28244
|
+
window.removeEventListener("pointermove", onMasterChartDrag, true);
|
|
28245
|
+
window.removeEventListener("pointerup", onMasterChartPointerUp, true);
|
|
28196
28246
|
};
|
|
28197
|
-
window.addEventListener("pointermove",
|
|
28198
|
-
window.addEventListener("pointerup",
|
|
28247
|
+
window.addEventListener("pointermove", onMasterChartDrag, true);
|
|
28248
|
+
window.addEventListener("pointerup", onMasterChartPointerUp, true);
|
|
28199
28249
|
}
|
|
28200
|
-
|
|
28201
|
-
const { offsetX: x, offsetY: y } = ev;
|
|
28250
|
+
onMasterChartPointerMove(ev) {
|
|
28251
|
+
const { offsetX: x, offsetY: y, target } = ev;
|
|
28252
|
+
if (!target || !this.isMasterChartAllowed) {
|
|
28253
|
+
return;
|
|
28254
|
+
}
|
|
28202
28255
|
if (this.mode === undefined) {
|
|
28203
|
-
const target = ev.target;
|
|
28204
28256
|
if (!this.masterChart?.chartArea) {
|
|
28205
28257
|
target["style"].cursor = "default";
|
|
28206
28258
|
return;
|
|
@@ -28222,14 +28274,14 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28222
28274
|
}
|
|
28223
28275
|
}
|
|
28224
28276
|
}
|
|
28225
|
-
|
|
28277
|
+
onMasterChartMouseLeave(ev) {
|
|
28226
28278
|
const target = ev.target;
|
|
28227
|
-
if (!target) {
|
|
28279
|
+
if (!target || !this.isMasterChartAllowed) {
|
|
28228
28280
|
return;
|
|
28229
28281
|
}
|
|
28230
28282
|
target["style"].cursor = "default";
|
|
28231
28283
|
}
|
|
28232
|
-
|
|
28284
|
+
onMasterChartDoubleClick(ev) {
|
|
28233
28285
|
this.mode = undefined;
|
|
28234
28286
|
const position = ev.offsetX;
|
|
28235
28287
|
if (!this.masterChart?.chartArea || !this.chart?.scales.x) {
|
|
@@ -28246,33 +28298,25 @@ class ZoomableChartJsComponent extends ChartJsComponent {
|
|
|
28246
28298
|
}
|
|
28247
28299
|
ev.preventDefault();
|
|
28248
28300
|
ev.stopPropagation();
|
|
28249
|
-
let { min
|
|
28301
|
+
let { min, max } = this.store.currentAxesLimits[this.chartId]?.x ?? this.chart.scales.x;
|
|
28250
28302
|
const originalAxisLimits = this.store.originalAxisLimits[this.chartId].x;
|
|
28251
28303
|
if (!originalAxisLimits) {
|
|
28252
28304
|
return;
|
|
28253
28305
|
}
|
|
28254
|
-
let originalXMin = originalAxisLimits.min;
|
|
28255
|
-
let originalXMax = originalAxisLimits.max;
|
|
28256
|
-
if (this.hasLinearScale) {
|
|
28257
|
-
originalXMin = Math.ceil(originalXMin) - this.axisOffset;
|
|
28258
|
-
originalXMax = Math.floor(originalXMax) + this.axisOffset;
|
|
28259
|
-
}
|
|
28260
28306
|
if (Math.abs(position - lowerBound) < 5) {
|
|
28261
|
-
|
|
28262
|
-
xMin = originalXMin;
|
|
28307
|
+
min = originalAxisLimits.min;
|
|
28263
28308
|
}
|
|
28264
28309
|
else if (Math.abs(position - upperBound) < 5) {
|
|
28265
|
-
|
|
28310
|
+
max = originalAxisLimits.max;
|
|
28266
28311
|
}
|
|
28267
28312
|
else if (lowerBound < position && position < upperBound) {
|
|
28268
|
-
|
|
28269
|
-
|
|
28270
|
-
xMax = originalXMax;
|
|
28313
|
+
min = originalAxisLimits.min;
|
|
28314
|
+
max = originalAxisLimits.max;
|
|
28271
28315
|
}
|
|
28272
28316
|
else {
|
|
28273
28317
|
return;
|
|
28274
28318
|
}
|
|
28275
|
-
this.updateAxisLimits(
|
|
28319
|
+
this.updateAxisLimits(min, max);
|
|
28276
28320
|
}
|
|
28277
28321
|
}
|
|
28278
28322
|
|
|
@@ -34403,7 +34447,8 @@ class Composer extends Component {
|
|
|
34403
34447
|
assistantStyle["max-height"] = `${availableSpaceAbove - CLOSE_ICON_RADIUS}px`;
|
|
34404
34448
|
// render top
|
|
34405
34449
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
34406
|
-
assistantStyle.
|
|
34450
|
+
assistantStyle.top = `-3px`;
|
|
34451
|
+
assistantStyle.transform = `translate(0, -100%)`;
|
|
34407
34452
|
}
|
|
34408
34453
|
if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
|
|
34409
34454
|
// render left
|
|
@@ -34523,16 +34568,12 @@ class Composer extends Component {
|
|
|
34523
34568
|
processTabKey(ev, direction) {
|
|
34524
34569
|
ev.preventDefault();
|
|
34525
34570
|
ev.stopPropagation();
|
|
34526
|
-
|
|
34527
|
-
this.props.composerStore.autoCompleteOrStop(direction);
|
|
34528
|
-
}
|
|
34571
|
+
this.props.composerStore.autoCompleteOrStop(direction, this.assistant.forcedClosed);
|
|
34529
34572
|
}
|
|
34530
34573
|
processEnterKey(ev, direction) {
|
|
34531
34574
|
ev.preventDefault();
|
|
34532
34575
|
ev.stopPropagation();
|
|
34533
|
-
|
|
34534
|
-
this.props.composerStore.autoCompleteOrStop(direction);
|
|
34535
|
-
}
|
|
34576
|
+
this.props.composerStore.autoCompleteOrStop(direction, this.assistant.forcedClosed);
|
|
34536
34577
|
}
|
|
34537
34578
|
processNewLineEvent(ev) {
|
|
34538
34579
|
ev.preventDefault();
|
|
@@ -34708,7 +34749,6 @@ class Composer extends Component {
|
|
|
34708
34749
|
return;
|
|
34709
34750
|
}
|
|
34710
34751
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
34711
|
-
this.props.composerStore.stopComposerRangeSelection();
|
|
34712
34752
|
const isCurrentlyInactive = this.props.composerStore.editionMode === "inactive";
|
|
34713
34753
|
this.props.onComposerContentFocused(newSelection);
|
|
34714
34754
|
if (!isCurrentlyInactive) {
|
|
@@ -35199,6 +35239,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35199
35239
|
}
|
|
35200
35240
|
this.selectionStart = start;
|
|
35201
35241
|
this.selectionEnd = end;
|
|
35242
|
+
this.stopComposerRangeSelection();
|
|
35202
35243
|
this.computeFormulaCursorContext();
|
|
35203
35244
|
this.computeParenthesisRelatedToCursor();
|
|
35204
35245
|
this.updateAutoCompleteProvider();
|
|
@@ -35869,10 +35910,13 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
35869
35910
|
hideHelp() {
|
|
35870
35911
|
this.autoComplete.hide();
|
|
35871
35912
|
}
|
|
35872
|
-
autoCompleteOrStop(direction) {
|
|
35913
|
+
autoCompleteOrStop(direction, assistantForcedClosed = false) {
|
|
35873
35914
|
if (this.editionMode !== "inactive") {
|
|
35874
35915
|
const autoComplete = this.autoComplete;
|
|
35875
|
-
|
|
35916
|
+
const suppressAutocomplete = assistantForcedClosed && this.canBeToggled;
|
|
35917
|
+
if (!suppressAutocomplete &&
|
|
35918
|
+
autoComplete.provider &&
|
|
35919
|
+
autoComplete.selectedIndex !== undefined) {
|
|
35876
35920
|
const autoCompleteValue = autoComplete.provider.proposals[autoComplete.selectedIndex]?.text;
|
|
35877
35921
|
if (autoCompleteValue) {
|
|
35878
35922
|
this.autoComplete.provider?.selectProposal(autoCompleteValue);
|
|
@@ -44192,18 +44236,22 @@ function dropCommands(initialMessages, commandType) {
|
|
|
44192
44236
|
return messages;
|
|
44193
44237
|
}
|
|
44194
44238
|
function fixChartDefinitions(data, initialMessages) {
|
|
44239
|
+
/**
|
|
44240
|
+
* Revisions created after version 18.5.1 contain the full chart definition in the command
|
|
44241
|
+
* if the data was alreay updated to 18.5.1, then those older revision cannot (by definition) be reaplied
|
|
44242
|
+
* and should not be replayed.
|
|
44243
|
+
* FIXME: every command should be versionned when upgraded to allow finer tuning.
|
|
44244
|
+
*/
|
|
44245
|
+
if (!data.version || compareVersions(String(data.version), "18.5.1") >= 0) {
|
|
44246
|
+
return initialMessages;
|
|
44247
|
+
}
|
|
44195
44248
|
const messages = [];
|
|
44196
44249
|
const map = {};
|
|
44197
44250
|
for (const sheet of data.sheets || []) {
|
|
44198
44251
|
sheet.figures?.forEach((figure) => {
|
|
44199
44252
|
if (figure.tag === "chart") {
|
|
44200
44253
|
// chart definition
|
|
44201
|
-
|
|
44202
|
-
map[figure.data.chartId] = figure.data;
|
|
44203
|
-
}
|
|
44204
|
-
else {
|
|
44205
|
-
map[figure.id] = figure.data;
|
|
44206
|
-
}
|
|
44254
|
+
map[figure.id] = figure.data;
|
|
44207
44255
|
}
|
|
44208
44256
|
});
|
|
44209
44257
|
}
|
|
@@ -47786,7 +47834,6 @@ const dateGranularities = [
|
|
|
47786
47834
|
pivotRegistry.add("SPREADSHEET", {
|
|
47787
47835
|
ui: SpreadsheetPivot,
|
|
47788
47836
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
47789
|
-
externalData: false,
|
|
47790
47837
|
dateGranularities: [...dateGranularities],
|
|
47791
47838
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
47792
47839
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
@@ -51563,10 +51610,11 @@ class AbstractResizer extends Component {
|
|
|
51563
51610
|
this.state.waitingForMove = false;
|
|
51564
51611
|
}
|
|
51565
51612
|
onMouseMove(ev) {
|
|
51566
|
-
if (this.env.isMobile()
|
|
51567
|
-
|
|
51568
|
-
|
|
51569
|
-
|
|
51613
|
+
if (this.env.isMobile() ||
|
|
51614
|
+
this.env.model.getters.isReadonly() ||
|
|
51615
|
+
this.state.isResizing ||
|
|
51616
|
+
this.state.isMoving ||
|
|
51617
|
+
this.state.isSelecting) {
|
|
51570
51618
|
return;
|
|
51571
51619
|
}
|
|
51572
51620
|
this._computeHandleDisplay(ev);
|
|
@@ -51633,6 +51681,10 @@ class AbstractResizer extends Component {
|
|
|
51633
51681
|
if (index < 0) {
|
|
51634
51682
|
return;
|
|
51635
51683
|
}
|
|
51684
|
+
if (this.env.model.getters.isReadonly()) {
|
|
51685
|
+
this._selectElement(index, false);
|
|
51686
|
+
return;
|
|
51687
|
+
}
|
|
51636
51688
|
if (this.state.waitingForMove) {
|
|
51637
51689
|
if (!this.env.model.getters.isGridSelectionActive()) {
|
|
51638
51690
|
this._selectElement(index, false);
|
|
@@ -52994,7 +53046,7 @@ const friction = 0.95;
|
|
|
52994
53046
|
const verticalScrollFactor = 1;
|
|
52995
53047
|
const horizontalScrollFactor = 1;
|
|
52996
53048
|
const resetTimeoutDuration = 100;
|
|
52997
|
-
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
53049
|
+
function useTouchScroll(ref, updateScroll, canMoveUp, canMoveDown) {
|
|
52998
53050
|
let lastX = 0;
|
|
52999
53051
|
let lastY = 0;
|
|
53000
53052
|
let velocityX = 0;
|
|
@@ -53031,7 +53083,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
53031
53083
|
lastX = clientX;
|
|
53032
53084
|
lastY = clientY;
|
|
53033
53085
|
lastTime = currentTime;
|
|
53034
|
-
if (canMoveUp()) {
|
|
53086
|
+
if ((deltaY < 0 && canMoveUp()) || (deltaY > 0 && canMoveDown())) {
|
|
53035
53087
|
if (event.cancelable) {
|
|
53036
53088
|
event.preventDefault();
|
|
53037
53089
|
}
|
|
@@ -53817,7 +53869,9 @@ class FontSizeEditor extends Component {
|
|
|
53817
53869
|
inputRef = useRef("inputFontSize");
|
|
53818
53870
|
rootEditorRef = useRef("FontSizeEditor");
|
|
53819
53871
|
fontSizeListRef = useRef("fontSizeList");
|
|
53872
|
+
DOMFocusableElementStore;
|
|
53820
53873
|
setup() {
|
|
53874
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
53821
53875
|
useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
53822
53876
|
}
|
|
53823
53877
|
get popoverProps() {
|
|
@@ -53871,6 +53925,13 @@ class FontSizeEditor extends Component {
|
|
|
53871
53925
|
}
|
|
53872
53926
|
this.props.onToggle?.();
|
|
53873
53927
|
}
|
|
53928
|
+
if (ev.key === "Tab") {
|
|
53929
|
+
ev.preventDefault();
|
|
53930
|
+
ev.stopPropagation();
|
|
53931
|
+
this.closeFontList();
|
|
53932
|
+
this.DOMFocusableElementStore.focus();
|
|
53933
|
+
return;
|
|
53934
|
+
}
|
|
53874
53935
|
}
|
|
53875
53936
|
}
|
|
53876
53937
|
|
|
@@ -55206,19 +55267,6 @@ class ChartWithAxisDesignPanel extends Component {
|
|
|
55206
55267
|
}
|
|
55207
55268
|
}
|
|
55208
55269
|
|
|
55209
|
-
class ChartShowDataMarkers extends Component {
|
|
55210
|
-
static template = "o-spreadsheet-ChartShowDataMarkers";
|
|
55211
|
-
static components = {
|
|
55212
|
-
Checkbox,
|
|
55213
|
-
};
|
|
55214
|
-
static props = {
|
|
55215
|
-
chartId: String,
|
|
55216
|
-
definition: Object,
|
|
55217
|
-
updateChart: Function,
|
|
55218
|
-
canUpdateChart: Function,
|
|
55219
|
-
};
|
|
55220
|
-
}
|
|
55221
|
-
|
|
55222
55270
|
class GenericZoomableChartDesignPanel extends ChartWithAxisDesignPanel {
|
|
55223
55271
|
static template = "o-spreadsheet-GenericZoomableChartDesignPanel";
|
|
55224
55272
|
static components = {
|
|
@@ -55232,6 +55280,26 @@ class GenericZoomableChartDesignPanel extends ChartWithAxisDesignPanel {
|
|
|
55232
55280
|
}
|
|
55233
55281
|
}
|
|
55234
55282
|
|
|
55283
|
+
class BarChartDesignPanel extends GenericZoomableChartDesignPanel {
|
|
55284
|
+
static template = "o-spreadsheet-BarChartDesignPanel";
|
|
55285
|
+
get isZoomable() {
|
|
55286
|
+
return !this.props.definition.horizontal;
|
|
55287
|
+
}
|
|
55288
|
+
}
|
|
55289
|
+
|
|
55290
|
+
class ChartShowDataMarkers extends Component {
|
|
55291
|
+
static template = "o-spreadsheet-ChartShowDataMarkers";
|
|
55292
|
+
static components = {
|
|
55293
|
+
Checkbox,
|
|
55294
|
+
};
|
|
55295
|
+
static props = {
|
|
55296
|
+
chartId: String,
|
|
55297
|
+
definition: Object,
|
|
55298
|
+
updateChart: Function,
|
|
55299
|
+
canUpdateChart: Function,
|
|
55300
|
+
};
|
|
55301
|
+
}
|
|
55302
|
+
|
|
55235
55303
|
class ComboChartDesignPanel extends GenericZoomableChartDesignPanel {
|
|
55236
55304
|
static template = "o-spreadsheet-ComboChartDesignPanel";
|
|
55237
55305
|
static components = {
|
|
@@ -56160,7 +56228,7 @@ chartSidePanelComponentRegistry
|
|
|
56160
56228
|
})
|
|
56161
56229
|
.add("bar", {
|
|
56162
56230
|
configuration: BarConfigPanel,
|
|
56163
|
-
design:
|
|
56231
|
+
design: BarChartDesignPanel,
|
|
56164
56232
|
})
|
|
56165
56233
|
.add("combo", {
|
|
56166
56234
|
configuration: GenericChartConfigPanel,
|
|
@@ -59269,7 +59337,6 @@ function insertTokenAfterArgSeparator(tokenAtCursor, value) {
|
|
|
59269
59337
|
// replace the whole token
|
|
59270
59338
|
start = tokenAtCursor.start;
|
|
59271
59339
|
}
|
|
59272
|
-
this.composer.stopComposerRangeSelection();
|
|
59273
59340
|
this.composer.changeComposerCursorSelection(start, end);
|
|
59274
59341
|
this.composer.replaceComposerCursorSelection(value);
|
|
59275
59342
|
}
|
|
@@ -59287,7 +59354,6 @@ function insertTokenAfterLeftParenthesis(tokenAtCursor, value) {
|
|
|
59287
59354
|
// replace the whole token
|
|
59288
59355
|
start = tokenAtCursor.start;
|
|
59289
59356
|
}
|
|
59290
|
-
this.composer.stopComposerRangeSelection();
|
|
59291
59357
|
this.composer.changeComposerCursorSelection(start, end);
|
|
59292
59358
|
this.composer.replaceComposerCursorSelection(value);
|
|
59293
59359
|
}
|
|
@@ -60748,6 +60814,7 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60748
60814
|
getPanelProps(panelInfo) {
|
|
60749
60815
|
const state = this.computeState(panelInfo);
|
|
60750
60816
|
if (state.isOpen) {
|
|
60817
|
+
panelInfo.currentPanelProps = state.props ?? panelInfo.currentPanelProps;
|
|
60751
60818
|
return state.props ?? {};
|
|
60752
60819
|
}
|
|
60753
60820
|
return {};
|
|
@@ -60759,11 +60826,11 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60759
60826
|
}
|
|
60760
60827
|
return undefined;
|
|
60761
60828
|
}
|
|
60762
|
-
open(componentTag,
|
|
60829
|
+
open(componentTag, currentPanelProps = {}) {
|
|
60763
60830
|
if (this.screenWidthStore.isSmall) {
|
|
60764
60831
|
return;
|
|
60765
60832
|
}
|
|
60766
|
-
const newPanelInfo = {
|
|
60833
|
+
const newPanelInfo = { currentPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
|
|
60767
60834
|
const state = this.computeState(newPanelInfo);
|
|
60768
60835
|
if (!state.isOpen) {
|
|
60769
60836
|
return;
|
|
@@ -60787,8 +60854,8 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60787
60854
|
}
|
|
60788
60855
|
this._openPanel("secondaryPanel", newPanelInfo, state);
|
|
60789
60856
|
}
|
|
60790
|
-
replace(componentTag, currentPanelKey,
|
|
60791
|
-
const newPanelInfo = {
|
|
60857
|
+
replace(componentTag, currentPanelKey, currentPanelProps = {}) {
|
|
60858
|
+
const newPanelInfo = { currentPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
|
|
60792
60859
|
const state = this.computeState(newPanelInfo);
|
|
60793
60860
|
if (!state.isOpen) {
|
|
60794
60861
|
return;
|
|
@@ -60818,10 +60885,10 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60818
60885
|
_openPanel(panel, newPanel, state) {
|
|
60819
60886
|
const currentPanel = this[panel];
|
|
60820
60887
|
if (currentPanel && newPanel.componentTag !== currentPanel.componentTag) {
|
|
60821
|
-
currentPanel.
|
|
60888
|
+
currentPanel.currentPanelProps?.onCloseSidePanel?.();
|
|
60822
60889
|
}
|
|
60823
60890
|
this[panel] = {
|
|
60824
|
-
|
|
60891
|
+
currentPanelProps: state.props ?? {},
|
|
60825
60892
|
componentTag: newPanel.componentTag,
|
|
60826
60893
|
size: currentPanel?.size || DEFAULT_SIDE_PANEL_SIZE,
|
|
60827
60894
|
isCollapsed: currentPanel?.isCollapsed || false,
|
|
@@ -60843,16 +60910,16 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60843
60910
|
close() {
|
|
60844
60911
|
if (this.mainPanel?.isPinned) {
|
|
60845
60912
|
if (this.secondaryPanel) {
|
|
60846
|
-
this.secondaryPanel.
|
|
60913
|
+
this.secondaryPanel.currentPanelProps.onCloseSidePanel?.();
|
|
60847
60914
|
this.secondaryPanel = undefined;
|
|
60848
60915
|
}
|
|
60849
60916
|
return;
|
|
60850
60917
|
}
|
|
60851
|
-
this.mainPanel?.
|
|
60918
|
+
this.mainPanel?.currentPanelProps.onCloseSidePanel?.();
|
|
60852
60919
|
this.mainPanel = undefined;
|
|
60853
60920
|
}
|
|
60854
60921
|
closeMainPanel() {
|
|
60855
|
-
this.mainPanel?.
|
|
60922
|
+
this.mainPanel?.currentPanelProps.onCloseSidePanel?.();
|
|
60856
60923
|
this.mainPanel = this.secondaryPanel || undefined;
|
|
60857
60924
|
this.secondaryPanel = undefined;
|
|
60858
60925
|
}
|
|
@@ -60884,7 +60951,7 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60884
60951
|
}
|
|
60885
60952
|
this.mainPanel.isPinned = !this.mainPanel.isPinned;
|
|
60886
60953
|
if (!this.mainPanel.isPinned && this.secondaryPanel) {
|
|
60887
|
-
this.secondaryPanel?.
|
|
60954
|
+
this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
|
|
60888
60955
|
this.mainPanel = this.secondaryPanel;
|
|
60889
60956
|
this.secondaryPanel = undefined;
|
|
60890
60957
|
}
|
|
@@ -60903,7 +60970,7 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60903
60970
|
panelInfo.size = COLLAPSED_SIDE_PANEL_SIZE;
|
|
60904
60971
|
}
|
|
60905
60972
|
}
|
|
60906
|
-
computeState({ componentTag, initialPanelProps }) {
|
|
60973
|
+
computeState({ componentTag, currentPanelProps: initialPanelProps, }) {
|
|
60907
60974
|
const customComputeState = sidePanelRegistry.get(componentTag).computeState;
|
|
60908
60975
|
const state = customComputeState
|
|
60909
60976
|
? customComputeState(this.getters, initialPanelProps)
|
|
@@ -60913,7 +60980,7 @@ class SidePanelStore extends SpreadsheetStore {
|
|
|
60913
60980
|
changeSpreadsheetWidth(width) {
|
|
60914
60981
|
this.availableWidth = width - MIN_SHEET_VIEW_WIDTH;
|
|
60915
60982
|
if (this.secondaryPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
|
|
60916
|
-
this.secondaryPanel?.
|
|
60983
|
+
this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
|
|
60917
60984
|
this.secondaryPanel = undefined;
|
|
60918
60985
|
}
|
|
60919
60986
|
if (this.mainPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
|
|
@@ -61073,6 +61140,10 @@ class Grid extends Component {
|
|
|
61073
61140
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
61074
61141
|
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
61075
61142
|
return scrollY > 0;
|
|
61143
|
+
}, () => {
|
|
61144
|
+
const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
|
|
61145
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
61146
|
+
return scrollY < maxOffsetY;
|
|
61076
61147
|
});
|
|
61077
61148
|
}
|
|
61078
61149
|
get highlights() {
|
|
@@ -62365,22 +62436,34 @@ class BordersPlugin extends CorePlugin {
|
|
|
62365
62436
|
addBorder(sheetId, zone, newBorder, force = false) {
|
|
62366
62437
|
const borders = [];
|
|
62367
62438
|
const plannedBorder = newBorder ? { zone, style: newBorder } : undefined;
|
|
62368
|
-
|
|
62369
|
-
|
|
62370
|
-
|
|
62371
|
-
|
|
62372
|
-
|
|
62439
|
+
// For each side, decide if we must clear the border on the *adjacent*
|
|
62440
|
+
// existing cell when we draw on the opposite side of the new zone.
|
|
62441
|
+
//
|
|
62442
|
+
// Example:
|
|
62443
|
+
// - newBorder.right is set → we draw border on the RIGHT side of `zone`
|
|
62444
|
+
// - the cell on the right may already have a LEFT border on that edge
|
|
62445
|
+
// In that case we clear that LEFT border, so only the new RIGHT border
|
|
62446
|
+
// remains on the shared edge.
|
|
62447
|
+
//
|
|
62448
|
+
// existingBorderSideToClear[side] = true means we should clear the border on that
|
|
62449
|
+
// side of the existing adjacent zone before adding the new border.
|
|
62450
|
+
const existingBorderSideToClear = {
|
|
62451
|
+
left: force || !!newBorder?.right,
|
|
62452
|
+
right: force || !!newBorder?.left,
|
|
62453
|
+
top: force || !!newBorder?.bottom,
|
|
62454
|
+
bottom: force || !!newBorder?.top,
|
|
62373
62455
|
};
|
|
62374
62456
|
let editingZone = [zone];
|
|
62375
62457
|
for (const existingBorder of this.borders[sheetId] ?? []) {
|
|
62376
62458
|
const inter = intersection(existingBorder.zone, zone);
|
|
62377
62459
|
if (!inter) {
|
|
62378
|
-
//
|
|
62460
|
+
// Check if the existing border is adjacent to the new zone
|
|
62379
62461
|
const adjacentEdge = adjacent(existingBorder.zone, zone);
|
|
62380
|
-
if (adjacentEdge &&
|
|
62462
|
+
if (adjacentEdge && existingBorderSideToClear[adjacentEdge.position]) {
|
|
62381
62463
|
for (const newZone of splitIfAdjacent(existingBorder.zone, zone)) {
|
|
62382
62464
|
const border = this.computeBorderFromZone(newZone, existingBorder);
|
|
62383
62465
|
const adjacentEdge = adjacent(newZone, zone);
|
|
62466
|
+
// Clear the existing border on the side that touches the new zone
|
|
62384
62467
|
switch (adjacentEdge?.position) {
|
|
62385
62468
|
case "left":
|
|
62386
62469
|
border.style.left = undefined;
|
|
@@ -64237,7 +64320,8 @@ class FigurePlugin extends CorePlugin {
|
|
|
64237
64320
|
}
|
|
64238
64321
|
break;
|
|
64239
64322
|
case "DUPLICATE_SHEET": {
|
|
64240
|
-
for (const
|
|
64323
|
+
for (const figure of this.getFigures(cmd.sheetId)) {
|
|
64324
|
+
const figureId = figure.id;
|
|
64241
64325
|
const fig = this.figures[cmd.sheetId]?.[figureId];
|
|
64242
64326
|
if (!fig) {
|
|
64243
64327
|
continue;
|
|
@@ -67715,10 +67799,17 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
67715
67799
|
if (!pivot) {
|
|
67716
67800
|
continue;
|
|
67717
67801
|
}
|
|
67718
|
-
|
|
67802
|
+
const def = deepCopy(pivot.definition);
|
|
67803
|
+
for (const measure of def.measures) {
|
|
67719
67804
|
if (measure.computedBy?.formula === formulaString) {
|
|
67720
|
-
const measureIndex =
|
|
67721
|
-
|
|
67805
|
+
const measureIndex = def.measures.indexOf(measure);
|
|
67806
|
+
if (measureIndex !== -1) {
|
|
67807
|
+
def.measures[measureIndex].computedBy = {
|
|
67808
|
+
formula: newFormulaString,
|
|
67809
|
+
sheetId,
|
|
67810
|
+
};
|
|
67811
|
+
}
|
|
67812
|
+
this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
|
|
67722
67813
|
}
|
|
67723
67814
|
}
|
|
67724
67815
|
}
|
|
@@ -67879,6 +67970,9 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
|
|
|
67879
67970
|
const { sheetId, zone } = definition.dataSet;
|
|
67880
67971
|
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
67881
67972
|
const adaptedRange = adaptPivotRange(range, applyChange);
|
|
67973
|
+
if (adaptedRange === range) {
|
|
67974
|
+
return;
|
|
67975
|
+
}
|
|
67882
67976
|
const dataSet = adaptedRange && {
|
|
67883
67977
|
sheetId: adaptedRange.sheetId,
|
|
67884
67978
|
zone: adaptedRange.zone,
|
|
@@ -72198,9 +72292,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
72198
72292
|
handle(cmd) {
|
|
72199
72293
|
if (invalidateEvaluationCommands.has(cmd.type)) {
|
|
72200
72294
|
for (const pivotId of this.getters.getPivotIds()) {
|
|
72201
|
-
|
|
72202
|
-
this.setupPivot(pivotId, { recreate: true });
|
|
72203
|
-
}
|
|
72295
|
+
this.setupPivot(pivotId, { recreate: true });
|
|
72204
72296
|
}
|
|
72205
72297
|
}
|
|
72206
72298
|
switch (cmd.type) {
|
|
@@ -72422,7 +72514,7 @@ class PivotUIPlugin extends CoreViewPlugin {
|
|
|
72422
72514
|
pivot.init({ reload: true });
|
|
72423
72515
|
}
|
|
72424
72516
|
setupPivot(pivotId, { recreate } = { recreate: false }) {
|
|
72425
|
-
const definition = this.getters.getPivotCoreDefinition(pivotId);
|
|
72517
|
+
const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
|
|
72426
72518
|
if (!(pivotId in this.pivots)) {
|
|
72427
72519
|
const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
|
|
72428
72520
|
this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
|
|
@@ -78674,6 +78766,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
78674
78766
|
"getFigureUI",
|
|
78675
78767
|
"getPositionAnchorOffset",
|
|
78676
78768
|
"getGridOffset",
|
|
78769
|
+
"getMaximumSheetOffset",
|
|
78677
78770
|
];
|
|
78678
78771
|
viewports = {};
|
|
78679
78772
|
/**
|
|
@@ -81928,16 +82021,18 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
81928
82021
|
get clickableCells() {
|
|
81929
82022
|
const cells = [];
|
|
81930
82023
|
const getters = this.getters;
|
|
81931
|
-
const sheetId = getters.getActiveSheetId();
|
|
81932
82024
|
for (const position of this.getters.getVisibleCellPositions()) {
|
|
81933
82025
|
const item = this.getClickableItem(position);
|
|
81934
82026
|
if (!item) {
|
|
81935
82027
|
continue;
|
|
81936
82028
|
}
|
|
81937
82029
|
const title = typeof item.title === "function" ? item.title(position, getters) : item.title;
|
|
81938
|
-
const
|
|
82030
|
+
const rect = this.getClickableCellRect(position);
|
|
82031
|
+
if (!rect) {
|
|
82032
|
+
continue;
|
|
82033
|
+
}
|
|
81939
82034
|
cells.push({
|
|
81940
|
-
coordinates:
|
|
82035
|
+
coordinates: rect,
|
|
81941
82036
|
position,
|
|
81942
82037
|
action: item.execute,
|
|
81943
82038
|
title: title || "",
|
|
@@ -81947,6 +82042,31 @@ class ClickableCellsStore extends SpreadsheetStore {
|
|
|
81947
82042
|
}
|
|
81948
82043
|
return cells;
|
|
81949
82044
|
}
|
|
82045
|
+
getClickableCellRect(position) {
|
|
82046
|
+
const zone = this.getters.expandZone(position.sheetId, positionToZone(position));
|
|
82047
|
+
const clickableRect = this.getters.getVisibleRect(zone);
|
|
82048
|
+
const icons = this.getters.getCellIcons(position);
|
|
82049
|
+
const iconsAtPosition = {
|
|
82050
|
+
center: icons.find((icon) => icon.horizontalAlign === "center"),
|
|
82051
|
+
left: icons.find((icon) => icon.horizontalAlign === "left"),
|
|
82052
|
+
right: icons.find((icon) => icon.horizontalAlign === "right"),
|
|
82053
|
+
};
|
|
82054
|
+
if (iconsAtPosition.center?.onClick) {
|
|
82055
|
+
return undefined;
|
|
82056
|
+
}
|
|
82057
|
+
if (iconsAtPosition.right?.onClick) {
|
|
82058
|
+
const cellRect = this.getters.getRect(zone);
|
|
82059
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.right, cellRect);
|
|
82060
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.right.margin;
|
|
82061
|
+
}
|
|
82062
|
+
if (iconsAtPosition.left?.onClick) {
|
|
82063
|
+
const cellRect = this.getters.getRect(zone);
|
|
82064
|
+
const iconRect = this.getters.getCellIconRect(iconsAtPosition.left, cellRect);
|
|
82065
|
+
clickableRect.x += iconRect.width + iconsAtPosition.left.margin;
|
|
82066
|
+
clickableRect.width -= iconRect.width + iconsAtPosition.left.margin;
|
|
82067
|
+
}
|
|
82068
|
+
return clickableRect;
|
|
82069
|
+
}
|
|
81950
82070
|
}
|
|
81951
82071
|
|
|
81952
82072
|
css /* scss */ `
|
|
@@ -81985,6 +82105,10 @@ class SpreadsheetDashboard extends Component {
|
|
|
81985
82105
|
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
81986
82106
|
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
81987
82107
|
return scrollY > 0;
|
|
82108
|
+
}, () => {
|
|
82109
|
+
const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
|
|
82110
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
82111
|
+
return scrollY < maxOffsetY;
|
|
81988
82112
|
});
|
|
81989
82113
|
}
|
|
81990
82114
|
get gridContainer() {
|
|
@@ -82700,7 +82824,7 @@ class SmallBottomBar extends Component {
|
|
|
82700
82824
|
height: this.focus === "inactive" ? "26px" : "fit-content",
|
|
82701
82825
|
"max-height": `130px`,
|
|
82702
82826
|
}),
|
|
82703
|
-
showAssistant:
|
|
82827
|
+
showAssistant: false, // Hide assistant in small composer as it gets cropped ATM
|
|
82704
82828
|
placeholder: this.composerStore.placeholder,
|
|
82705
82829
|
};
|
|
82706
82830
|
}
|
|
@@ -84029,7 +84153,7 @@ css /* scss */ `
|
|
|
84029
84153
|
border-radius: 4px;
|
|
84030
84154
|
font-weight: 500;
|
|
84031
84155
|
font-size: 14px;
|
|
84032
|
-
height: 32px;
|
|
84156
|
+
min-height: 32px;
|
|
84033
84157
|
line-height: 16px;
|
|
84034
84158
|
flex-grow: 1;
|
|
84035
84159
|
background-color: ${BUTTON_BG};
|
|
@@ -88932,6 +89056,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
88932
89056
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
88933
89057
|
|
|
88934
89058
|
|
|
88935
|
-
__info__.version = "19.0.
|
|
88936
|
-
__info__.date = "2025-
|
|
88937
|
-
__info__.hash = "
|
|
89059
|
+
__info__.version = "19.0.12";
|
|
89060
|
+
__info__.date = "2025-12-02T05:34:17.495Z";
|
|
89061
|
+
__info__.hash = "32203f1";
|