@odoo/o-spreadsheet 18.5.0-alpha.2 → 18.5.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +386 -143
- package/dist/o-spreadsheet.d.ts +333 -162
- package/dist/o-spreadsheet.esm.js +386 -143
- package/dist/o-spreadsheet.iife.js +386 -143
- package/dist/o-spreadsheet.iife.min.js +453 -398
- package/dist/o_spreadsheet.xml +17 -14
- 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 18.5.0-alpha.
|
|
6
|
-
* @date 2025-07-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.5.0-alpha.4
|
|
6
|
+
* @date 2025-07-30T11:23:18.805Z
|
|
7
|
+
* @hash 34a4ab3
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2903,6 +2903,7 @@ const availableConditionalFormatOperators = new Set([
|
|
|
2903
2903
|
"isEmpty",
|
|
2904
2904
|
"isNotEqual",
|
|
2905
2905
|
"isEqual",
|
|
2906
|
+
"customFormula",
|
|
2906
2907
|
]);
|
|
2907
2908
|
|
|
2908
2909
|
const availableDataValidationOperators = new Set([
|
|
@@ -5035,11 +5036,11 @@ function isTextFormat(format) {
|
|
|
5035
5036
|
}
|
|
5036
5037
|
}
|
|
5037
5038
|
|
|
5038
|
-
function evaluateLiteral(literalCell, localeFormat) {
|
|
5039
|
+
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
5039
5040
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5040
5041
|
? literalCell.content
|
|
5041
5042
|
: literalCell.parsedValue;
|
|
5042
|
-
const functionResult = { value, format: localeFormat.format };
|
|
5043
|
+
const functionResult = { value, format: localeFormat.format, origin: position };
|
|
5043
5044
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5044
5045
|
}
|
|
5045
5046
|
function parseLiteral(content, locale) {
|
|
@@ -5061,10 +5062,11 @@ function parseLiteral(content, locale) {
|
|
|
5061
5062
|
}
|
|
5062
5063
|
return content;
|
|
5063
5064
|
}
|
|
5064
|
-
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
5065
|
+
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell, origin) {
|
|
5065
5066
|
const link = detectLink(functionResult.value);
|
|
5066
5067
|
if (!link) {
|
|
5067
|
-
|
|
5068
|
+
const evaluateCell = _createEvaluatedCell(functionResult, locale, cell);
|
|
5069
|
+
return addOrigin(evaluateCell, functionResult.origin ?? origin);
|
|
5068
5070
|
}
|
|
5069
5071
|
const value = parseLiteral(link.label, locale);
|
|
5070
5072
|
const format = functionResult.format ||
|
|
@@ -5075,10 +5077,10 @@ function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
|
5075
5077
|
value,
|
|
5076
5078
|
format,
|
|
5077
5079
|
};
|
|
5078
|
-
return {
|
|
5080
|
+
return addOrigin({
|
|
5079
5081
|
..._createEvaluatedCell(linkPayload, locale, cell),
|
|
5080
5082
|
link,
|
|
5081
|
-
};
|
|
5083
|
+
}, functionResult.origin ?? origin);
|
|
5082
5084
|
}
|
|
5083
5085
|
function _createEvaluatedCell(functionResult, locale, cell) {
|
|
5084
5086
|
let { value, format, message } = functionResult;
|
|
@@ -5168,6 +5170,17 @@ function errorCell(value, message) {
|
|
|
5168
5170
|
defaultAlign: "center",
|
|
5169
5171
|
};
|
|
5170
5172
|
}
|
|
5173
|
+
function addOrigin(cell, origin) {
|
|
5174
|
+
if (cell.value === null) {
|
|
5175
|
+
// ignore empty cells to allow sharing the same object instance
|
|
5176
|
+
return cell;
|
|
5177
|
+
}
|
|
5178
|
+
if ("origin" in cell) {
|
|
5179
|
+
return cell;
|
|
5180
|
+
}
|
|
5181
|
+
cell.origin = origin;
|
|
5182
|
+
return cell;
|
|
5183
|
+
}
|
|
5171
5184
|
|
|
5172
5185
|
function toCriterionDateNumber(dateValue) {
|
|
5173
5186
|
const today = DateTime.now();
|
|
@@ -7848,6 +7861,7 @@ function changeCFRuleLocale(rule, changeContentLocale) {
|
|
|
7848
7861
|
case "isGreaterOrEqualTo":
|
|
7849
7862
|
case "isLessThan":
|
|
7850
7863
|
case "isLessOrEqualTo":
|
|
7864
|
+
case "customFormula":
|
|
7851
7865
|
rule.values = rule.values.map((v) => changeContentLocale(v));
|
|
7852
7866
|
return rule;
|
|
7853
7867
|
case "beginsWithText":
|
|
@@ -8626,12 +8640,12 @@ const AGGREGATOR_NAMES = {
|
|
|
8626
8640
|
avg: _t("Average"),
|
|
8627
8641
|
sum: _t("Sum"),
|
|
8628
8642
|
};
|
|
8629
|
-
const
|
|
8643
|
+
const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8630
8644
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8631
|
-
integer:
|
|
8632
|
-
char:
|
|
8645
|
+
integer: DEFAULT_AGGREGATORS,
|
|
8646
|
+
char: DEFAULT_AGGREGATORS,
|
|
8647
|
+
datetime: DEFAULT_AGGREGATORS,
|
|
8633
8648
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8634
|
-
datetime: ["max", "min", "count_distinct", "count"],
|
|
8635
8649
|
};
|
|
8636
8650
|
const AGGREGATORS = {};
|
|
8637
8651
|
for (const type in AGGREGATORS_BY_FIELD_TYPE) {
|
|
@@ -10536,6 +10550,7 @@ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
|
|
|
10536
10550
|
/** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
|
|
10537
10551
|
const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
|
|
10538
10552
|
const FIRST_NUMFMT_ID = 164;
|
|
10553
|
+
const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
|
|
10539
10554
|
const FORCE_DEFAULT_ARGS_FUNCTIONS = {
|
|
10540
10555
|
FLOOR: [{ type: "NUMBER", value: 1 }],
|
|
10541
10556
|
CEILING: [{ type: "NUMBER", value: 1 }],
|
|
@@ -19035,13 +19050,19 @@ const COLUMN = {
|
|
|
19035
19050
|
if (isEvaluationError(cellReference?.value)) {
|
|
19036
19051
|
return cellReference;
|
|
19037
19052
|
}
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
return
|
|
19053
|
+
if (cellReference === undefined) {
|
|
19054
|
+
if (this.__originCellPosition?.col === undefined) {
|
|
19055
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19056
|
+
}
|
|
19057
|
+
return this.__originCellPosition.col + 1;
|
|
19058
|
+
}
|
|
19059
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19060
|
+
if (zone.left === zone.right) {
|
|
19061
|
+
return zone.left + 1;
|
|
19043
19062
|
}
|
|
19044
|
-
return
|
|
19063
|
+
return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
|
|
19064
|
+
value: zone.left + col + 1,
|
|
19065
|
+
}));
|
|
19045
19066
|
},
|
|
19046
19067
|
isExported: true,
|
|
19047
19068
|
};
|
|
@@ -19272,13 +19293,19 @@ const ROW = {
|
|
|
19272
19293
|
if (isEvaluationError(cellReference?.value)) {
|
|
19273
19294
|
return cellReference;
|
|
19274
19295
|
}
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19278
|
-
|
|
19279
|
-
return
|
|
19296
|
+
if (cellReference === undefined) {
|
|
19297
|
+
if (this.__originCellPosition?.row === undefined) {
|
|
19298
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19299
|
+
}
|
|
19300
|
+
return this.__originCellPosition.row + 1;
|
|
19280
19301
|
}
|
|
19281
|
-
|
|
19302
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19303
|
+
if (zone.top === zone.bottom) {
|
|
19304
|
+
return zone.top + 1;
|
|
19305
|
+
}
|
|
19306
|
+
return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
|
|
19307
|
+
value: zone.top + row + 1,
|
|
19308
|
+
}));
|
|
19282
19309
|
},
|
|
19283
19310
|
isExported: true,
|
|
19284
19311
|
};
|
|
@@ -22855,6 +22882,16 @@ class AbstractChart {
|
|
|
22855
22882
|
static getDefinitionFromContextCreation(context) {
|
|
22856
22883
|
throw new Error("This method should be implemented by sub class");
|
|
22857
22884
|
}
|
|
22885
|
+
getCommonDataSetAttributesForExcel(labelRange, dataSets, shouldRemoveFirstLabel) {
|
|
22886
|
+
const excelDataSets = dataSets
|
|
22887
|
+
.map((ds) => toExcelDataset(this.getters, ds))
|
|
22888
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
22889
|
+
const excelLabelRange = toExcelLabelRange(this.getters, labelRange, shouldRemoveFirstLabel);
|
|
22890
|
+
return {
|
|
22891
|
+
dataSets: excelDataSets,
|
|
22892
|
+
labelRange: excelLabelRange,
|
|
22893
|
+
};
|
|
22894
|
+
}
|
|
22858
22895
|
}
|
|
22859
22896
|
|
|
22860
22897
|
function getBaselineText(baseline, keyValue, baselineMode, humanize, locale) {
|
|
@@ -26337,6 +26374,7 @@ class BarChart extends AbstractChart {
|
|
|
26337
26374
|
labelRange: context.auxiliaryRange || undefined,
|
|
26338
26375
|
axesDesign: context.axesDesign,
|
|
26339
26376
|
showValues: context.showValues,
|
|
26377
|
+
horizontal: context.horizontal,
|
|
26340
26378
|
};
|
|
26341
26379
|
}
|
|
26342
26380
|
getContextCreation() {
|
|
@@ -26394,10 +26432,7 @@ class BarChart extends AbstractChart {
|
|
|
26394
26432
|
};
|
|
26395
26433
|
}
|
|
26396
26434
|
getDefinitionForExcel() {
|
|
26397
|
-
const dataSets = this.dataSets
|
|
26398
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26399
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26400
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26435
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26401
26436
|
const definition = this.getDefinition();
|
|
26402
26437
|
return {
|
|
26403
26438
|
...definition,
|
|
@@ -26985,10 +27020,7 @@ class ComboChart extends AbstractChart {
|
|
|
26985
27020
|
if (this.aggregated) {
|
|
26986
27021
|
return undefined;
|
|
26987
27022
|
}
|
|
26988
|
-
const dataSets = this.dataSets
|
|
26989
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26990
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26991
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27023
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26992
27024
|
const definition = this.getDefinition();
|
|
26993
27025
|
return {
|
|
26994
27026
|
...definition,
|
|
@@ -27727,10 +27759,7 @@ class LineChart extends AbstractChart {
|
|
|
27727
27759
|
return new LineChart(definition, this.sheetId, this.getters);
|
|
27728
27760
|
}
|
|
27729
27761
|
getDefinitionForExcel() {
|
|
27730
|
-
const dataSets = this.dataSets
|
|
27731
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27732
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27733
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27762
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27734
27763
|
const definition = this.getDefinition();
|
|
27735
27764
|
return {
|
|
27736
27765
|
...definition,
|
|
@@ -27818,7 +27847,8 @@ class PieChart extends AbstractChart {
|
|
|
27818
27847
|
type: "pie",
|
|
27819
27848
|
labelRange: context.auxiliaryRange || undefined,
|
|
27820
27849
|
aggregated: context.aggregated ?? false,
|
|
27821
|
-
isDoughnut:
|
|
27850
|
+
isDoughnut: context.isDoughnut,
|
|
27851
|
+
pieHolePercentage: context.pieHolePercentage,
|
|
27822
27852
|
showValues: context.showValues,
|
|
27823
27853
|
};
|
|
27824
27854
|
}
|
|
@@ -27866,10 +27896,7 @@ class PieChart extends AbstractChart {
|
|
|
27866
27896
|
return new PieChart(definition, sheetId, this.getters);
|
|
27867
27897
|
}
|
|
27868
27898
|
getDefinitionForExcel() {
|
|
27869
|
-
const dataSets = this.dataSets
|
|
27870
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27871
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27872
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27899
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27873
27900
|
return {
|
|
27874
27901
|
...this.getDefinition(),
|
|
27875
27902
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
@@ -28014,8 +28041,22 @@ class PyramidChart extends AbstractChart {
|
|
|
28014
28041
|
showValues: this.showValues,
|
|
28015
28042
|
};
|
|
28016
28043
|
}
|
|
28017
|
-
getDefinitionForExcel() {
|
|
28018
|
-
|
|
28044
|
+
getDefinitionForExcel(getters) {
|
|
28045
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28046
|
+
const definition = this.getDefinition();
|
|
28047
|
+
const chartData = getPyramidChartData(definition, this.dataSets, this.labelRange, getters);
|
|
28048
|
+
const { dataSetsValues } = chartData;
|
|
28049
|
+
const maxValue = Math.max(...dataSetsValues.map((dataSet) => Math.max(...dataSet.data.map(Math.abs))));
|
|
28050
|
+
return {
|
|
28051
|
+
...definition,
|
|
28052
|
+
horizontal: true,
|
|
28053
|
+
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
28054
|
+
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
28055
|
+
dataSets,
|
|
28056
|
+
labelRange,
|
|
28057
|
+
verticalAxis: getDefinedAxis(definition),
|
|
28058
|
+
maxValue,
|
|
28059
|
+
};
|
|
28019
28060
|
}
|
|
28020
28061
|
updateRanges(applyChange) {
|
|
28021
28062
|
const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
|
|
@@ -28158,10 +28199,7 @@ class RadarChart extends AbstractChart {
|
|
|
28158
28199
|
if (this.aggregated) {
|
|
28159
28200
|
return undefined;
|
|
28160
28201
|
}
|
|
28161
|
-
const dataSets = this.dataSets
|
|
28162
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
28163
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
28164
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28202
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28165
28203
|
const definition = this.getDefinition();
|
|
28166
28204
|
return {
|
|
28167
28205
|
...definition,
|
|
@@ -30479,28 +30517,17 @@ class MenuPopover extends owl.Component {
|
|
|
30479
30517
|
}
|
|
30480
30518
|
}
|
|
30481
30519
|
|
|
30482
|
-
class
|
|
30483
|
-
|
|
30484
|
-
|
|
30485
|
-
static props = { figureUI: Object };
|
|
30520
|
+
class ChartDashboardMenuStore extends SpreadsheetStore {
|
|
30521
|
+
chartId;
|
|
30522
|
+
mutators = ["reset"];
|
|
30486
30523
|
originalChartDefinition;
|
|
30487
|
-
|
|
30488
|
-
|
|
30489
|
-
|
|
30490
|
-
|
|
30491
|
-
this.fullScreenFigureStore = useStore(FullScreenChartStore);
|
|
30492
|
-
this.originalChartDefinition = this.env.model.getters.getChartDefinition(this.props.figureUI.id);
|
|
30493
|
-
owl.onWillUpdateProps(({ figureUI }) => {
|
|
30494
|
-
if (figureUI.id !== this.props.figureUI.id) {
|
|
30495
|
-
this.originalChartDefinition = this.env.model.getters.getChartDefinition(figureUI.id);
|
|
30496
|
-
}
|
|
30497
|
-
});
|
|
30498
|
-
}
|
|
30499
|
-
getMenuItems() {
|
|
30500
|
-
return [this.fullScreenMenuItem, ...this.changeChartTypeMenuItems].filter(isDefined);
|
|
30524
|
+
constructor(get, chartId) {
|
|
30525
|
+
super(get);
|
|
30526
|
+
this.chartId = chartId;
|
|
30527
|
+
this.originalChartDefinition = this.getters.getChartDefinition(this.chartId);
|
|
30501
30528
|
}
|
|
30502
30529
|
get changeChartTypeMenuItems() {
|
|
30503
|
-
const definition = this.
|
|
30530
|
+
const definition = this.getters.getChartDefinition(this.chartId);
|
|
30504
30531
|
if (!["line", "bar", "pie"].includes(definition.type)) {
|
|
30505
30532
|
return [];
|
|
30506
30533
|
}
|
|
@@ -30509,27 +30536,19 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
30509
30536
|
return {
|
|
30510
30537
|
id: item.chartType,
|
|
30511
30538
|
label: item.displayName,
|
|
30512
|
-
onClick: () => this.
|
|
30513
|
-
isSelected: item.chartType === this.
|
|
30539
|
+
onClick: () => this.updateType(item.chartType),
|
|
30540
|
+
isSelected: item.chartType === this.getters.getChartDefinition(this.chartId).type,
|
|
30514
30541
|
iconClass: this.getIconClasses(item.chartType),
|
|
30515
30542
|
};
|
|
30516
30543
|
});
|
|
30517
30544
|
}
|
|
30518
|
-
|
|
30519
|
-
|
|
30520
|
-
|
|
30521
|
-
}
|
|
30522
|
-
if (type.includes("line")) {
|
|
30523
|
-
return "fa fa-line-chart";
|
|
30524
|
-
}
|
|
30525
|
-
if (type.includes("pie")) {
|
|
30526
|
-
return "fa fa-pie-chart";
|
|
30527
|
-
}
|
|
30528
|
-
return "";
|
|
30545
|
+
reset(chartId) {
|
|
30546
|
+
this.chartId = chartId;
|
|
30547
|
+
this.originalChartDefinition = this.getters.getChartDefinition(chartId);
|
|
30529
30548
|
}
|
|
30530
|
-
|
|
30531
|
-
const figureId = this.
|
|
30532
|
-
const currentDefinition = this.
|
|
30549
|
+
updateType(type) {
|
|
30550
|
+
const figureId = this.chartId;
|
|
30551
|
+
const currentDefinition = this.getters.getChartDefinition(figureId);
|
|
30533
30552
|
if (currentDefinition.type === type) {
|
|
30534
30553
|
return;
|
|
30535
30554
|
}
|
|
@@ -30540,7 +30559,7 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
30540
30559
|
else {
|
|
30541
30560
|
const newChartInfo = chartSubtypeRegistry.get(type);
|
|
30542
30561
|
const ChartClass = chartRegistry.get(newChartInfo.chartType);
|
|
30543
|
-
const chartCreationContext = this.
|
|
30562
|
+
const chartCreationContext = this.getters.getContextCreationChart(figureId);
|
|
30544
30563
|
if (!chartCreationContext)
|
|
30545
30564
|
return;
|
|
30546
30565
|
definition = {
|
|
@@ -30548,14 +30567,45 @@ class ChartDashboardMenu extends owl.Component {
|
|
|
30548
30567
|
...newChartInfo.subtypeDefinition,
|
|
30549
30568
|
};
|
|
30550
30569
|
}
|
|
30551
|
-
this.
|
|
30570
|
+
this.model.dispatch("UPDATE_CHART", {
|
|
30552
30571
|
definition,
|
|
30553
30572
|
figureId,
|
|
30554
|
-
sheetId: this.
|
|
30573
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
30555
30574
|
});
|
|
30556
30575
|
}
|
|
30557
|
-
|
|
30558
|
-
|
|
30576
|
+
getIconClasses(type) {
|
|
30577
|
+
if (type.includes("bar")) {
|
|
30578
|
+
return "fa fa-bar-chart";
|
|
30579
|
+
}
|
|
30580
|
+
if (type.includes("line")) {
|
|
30581
|
+
return "fa fa-line-chart";
|
|
30582
|
+
}
|
|
30583
|
+
if (type.includes("pie")) {
|
|
30584
|
+
return "fa fa-pie-chart";
|
|
30585
|
+
}
|
|
30586
|
+
return "";
|
|
30587
|
+
}
|
|
30588
|
+
}
|
|
30589
|
+
|
|
30590
|
+
class ChartDashboardMenu extends owl.Component {
|
|
30591
|
+
static template = "o-spreadsheet-ChartDashboardMenu";
|
|
30592
|
+
static components = { MenuPopover };
|
|
30593
|
+
static props = { figureUI: Object };
|
|
30594
|
+
fullScreenFigureStore;
|
|
30595
|
+
store;
|
|
30596
|
+
menuState = owl.useState({ isOpen: false, anchorRect: null, menuItems: [] });
|
|
30597
|
+
setup() {
|
|
30598
|
+
super.setup();
|
|
30599
|
+
this.store = useLocalStore(ChartDashboardMenuStore, this.props.figureUI.id);
|
|
30600
|
+
this.fullScreenFigureStore = useStore(FullScreenChartStore);
|
|
30601
|
+
owl.onWillUpdateProps(({ figureUI }) => {
|
|
30602
|
+
if (figureUI.id !== this.props.figureUI.id) {
|
|
30603
|
+
this.store.reset(figureUI.id);
|
|
30604
|
+
}
|
|
30605
|
+
});
|
|
30606
|
+
}
|
|
30607
|
+
getMenuItems() {
|
|
30608
|
+
return [this.fullScreenMenuItem, ...this.store.changeChartTypeMenuItems].filter(isDefined);
|
|
30559
30609
|
}
|
|
30560
30610
|
get backgroundColor() {
|
|
30561
30611
|
const color = this.env.model.getters.getChartDefinition(this.props.figureUI.id).background;
|
|
@@ -31697,7 +31747,7 @@ criterionEvaluatorRegistry.add("isValueInRange", {
|
|
|
31697
31747
|
}
|
|
31698
31748
|
const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
|
|
31699
31749
|
return criterionValues
|
|
31700
|
-
.map((value) => value.toLowerCase())
|
|
31750
|
+
.map((value) => value.value.toLowerCase())
|
|
31701
31751
|
.includes(value.toString().toLowerCase());
|
|
31702
31752
|
},
|
|
31703
31753
|
getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
|
|
@@ -32608,6 +32658,9 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32608
32658
|
get isAutoCompleteDisplayed() {
|
|
32609
32659
|
return !!this.autoComplete.provider;
|
|
32610
32660
|
}
|
|
32661
|
+
get canBeToggled() {
|
|
32662
|
+
return this.autoComplete.provider?.canBeToggled ?? true;
|
|
32663
|
+
}
|
|
32611
32664
|
cycleReferences() {
|
|
32612
32665
|
const locale = this.getters.getLocale();
|
|
32613
32666
|
const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
|
|
@@ -33137,6 +33190,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33137
33190
|
proposals,
|
|
33138
33191
|
selectProposal: provider.selectProposal,
|
|
33139
33192
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33193
|
+
canBeToggled: provider.canBeToggled,
|
|
33140
33194
|
};
|
|
33141
33195
|
}
|
|
33142
33196
|
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
@@ -33159,6 +33213,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33159
33213
|
proposals,
|
|
33160
33214
|
selectProposal: provider.selectProposal,
|
|
33161
33215
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33216
|
+
canBeToggled: provider.canBeToggled,
|
|
33162
33217
|
};
|
|
33163
33218
|
}
|
|
33164
33219
|
}
|
|
@@ -33729,9 +33784,13 @@ class Composer extends owl.Component {
|
|
|
33729
33784
|
}
|
|
33730
33785
|
}
|
|
33731
33786
|
closeAssistant() {
|
|
33787
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33788
|
+
return;
|
|
33732
33789
|
this.assistant.forcedClosed = true;
|
|
33733
33790
|
}
|
|
33734
33791
|
openAssistant() {
|
|
33792
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33793
|
+
return;
|
|
33735
33794
|
this.assistant.forcedClosed = false;
|
|
33736
33795
|
}
|
|
33737
33796
|
onWheel(event) {
|
|
@@ -33921,7 +33980,7 @@ class Composer extends owl.Component {
|
|
|
33921
33980
|
return [...new Set(argsToFocus)];
|
|
33922
33981
|
}
|
|
33923
33982
|
autoComplete(value) {
|
|
33924
|
-
if (!value || this.assistant.forcedClosed) {
|
|
33983
|
+
if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
|
|
33925
33984
|
return;
|
|
33926
33985
|
}
|
|
33927
33986
|
this.props.composerStore.insertAutoCompleteValue(value);
|
|
@@ -37499,7 +37558,7 @@ const CF_OPERATOR_TYPE_CONVERSION_MAP = {
|
|
|
37499
37558
|
/** Conversion map CF types in XLSX <=> Cf types in o_spreadsheet */
|
|
37500
37559
|
const CF_TYPE_CONVERSION_MAP = {
|
|
37501
37560
|
aboveAverage: undefined,
|
|
37502
|
-
expression:
|
|
37561
|
+
expression: "customFormula",
|
|
37503
37562
|
cellIs: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37504
37563
|
colorScale: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37505
37564
|
dataBar: undefined,
|
|
@@ -38103,7 +38162,6 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38103
38162
|
case "containsErrors":
|
|
38104
38163
|
case "notContainsErrors":
|
|
38105
38164
|
case "duplicateValues":
|
|
38106
|
-
case "expression":
|
|
38107
38165
|
case "top10":
|
|
38108
38166
|
case "uniqueValues":
|
|
38109
38167
|
case "timePeriod":
|
|
@@ -38136,6 +38194,12 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38136
38194
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38137
38195
|
values.push(rule.text);
|
|
38138
38196
|
break;
|
|
38197
|
+
case "expression":
|
|
38198
|
+
if (!rule.formula?.length)
|
|
38199
|
+
continue;
|
|
38200
|
+
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38201
|
+
values.push(`=${rule.formula[0]}`);
|
|
38202
|
+
break;
|
|
38139
38203
|
case "containsBlanks":
|
|
38140
38204
|
case "notContainsBlanks":
|
|
38141
38205
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
@@ -38365,6 +38429,8 @@ function convertOperator(operator) {
|
|
|
38365
38429
|
return "equal";
|
|
38366
38430
|
case "isNotEqual":
|
|
38367
38431
|
return "notEqual";
|
|
38432
|
+
case "customFormula":
|
|
38433
|
+
return "";
|
|
38368
38434
|
}
|
|
38369
38435
|
}
|
|
38370
38436
|
// -------------------------------------
|
|
@@ -38700,6 +38766,9 @@ function convertChartData(chartData) {
|
|
|
38700
38766
|
aggregated: false,
|
|
38701
38767
|
cumulative: chartData.cumulative || false,
|
|
38702
38768
|
labelsAsText: false,
|
|
38769
|
+
horizontal: chartData.horizontal,
|
|
38770
|
+
isDoughnut: chartData.isDoughnut,
|
|
38771
|
+
pieHolePercentage: chartData.pieHolePercentage,
|
|
38703
38772
|
};
|
|
38704
38773
|
try {
|
|
38705
38774
|
const ChartClass = chartRegistry.get(chartData.type);
|
|
@@ -39976,6 +40045,12 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39976
40045
|
const barChartGrouping = this.extractChildAttr(rootChartElement, "c:grouping", "val", {
|
|
39977
40046
|
default: "clustered",
|
|
39978
40047
|
}).asString();
|
|
40048
|
+
const chartDirection = this.extractChildAttr(rootChartElement, "c:barDir", "val", {
|
|
40049
|
+
default: "col",
|
|
40050
|
+
}).asString();
|
|
40051
|
+
const chartHoleSize = this.extractChildAttr(rootChartElement, "c:holeSize", "val", {
|
|
40052
|
+
default: "0",
|
|
40053
|
+
}).asNum();
|
|
39979
40054
|
return {
|
|
39980
40055
|
title: { text: chartTitle },
|
|
39981
40056
|
type: CHART_TYPE_CONVERSION_MAP[chartType],
|
|
@@ -39989,6 +40064,9 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39989
40064
|
}).asString()],
|
|
39990
40065
|
stacked: barChartGrouping === "stacked",
|
|
39991
40066
|
fontColor: "000000",
|
|
40067
|
+
horizontal: chartDirection === "bar",
|
|
40068
|
+
isDoughnut: chartHoleSize > 0,
|
|
40069
|
+
pieHolePercentage: chartHoleSize,
|
|
39992
40070
|
};
|
|
39993
40071
|
})[0];
|
|
39994
40072
|
}
|
|
@@ -50979,6 +51057,9 @@ class PieChartDesignPanel extends owl.Component {
|
|
|
50979
51057
|
pieHolePercentage,
|
|
50980
51058
|
});
|
|
50981
51059
|
}
|
|
51060
|
+
get defaultHoleSize() {
|
|
51061
|
+
return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
|
|
51062
|
+
}
|
|
50982
51063
|
}
|
|
50983
51064
|
|
|
50984
51065
|
class RadarChartDesignPanel extends owl.Component {
|
|
@@ -52043,7 +52124,8 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
52043
52124
|
static props = {
|
|
52044
52125
|
editedCf: Object,
|
|
52045
52126
|
onCancel: Function,
|
|
52046
|
-
|
|
52127
|
+
onExit: Function,
|
|
52128
|
+
isNewCf: Boolean,
|
|
52047
52129
|
};
|
|
52048
52130
|
static components = {
|
|
52049
52131
|
SelectionInput,
|
|
@@ -52068,6 +52150,7 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
52068
52150
|
currentCFType: this.props.editedCf.rule.type,
|
|
52069
52151
|
ranges: this.props.editedCf.ranges,
|
|
52070
52152
|
rules: this.getDefaultRules(),
|
|
52153
|
+
hasEditedCf: this.props.isNewCf,
|
|
52071
52154
|
});
|
|
52072
52155
|
switch (this.props.editedCf.rule.type) {
|
|
52073
52156
|
case "CellIsRule":
|
|
@@ -52119,6 +52202,9 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
52119
52202
|
ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
|
|
52120
52203
|
sheetId,
|
|
52121
52204
|
});
|
|
52205
|
+
if (result.isSuccessful) {
|
|
52206
|
+
this.state.hasEditedCf = true;
|
|
52207
|
+
}
|
|
52122
52208
|
const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
|
|
52123
52209
|
if (!newCf.suppressErrors) {
|
|
52124
52210
|
this.state.errors = reasons;
|
|
@@ -52140,7 +52226,15 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
52140
52226
|
onSave() {
|
|
52141
52227
|
const result = this.updateConditionalFormat({});
|
|
52142
52228
|
if (result.length === 0) {
|
|
52143
|
-
this.props.
|
|
52229
|
+
this.props.onExit();
|
|
52230
|
+
}
|
|
52231
|
+
}
|
|
52232
|
+
onCancel() {
|
|
52233
|
+
if (this.state.hasEditedCf) {
|
|
52234
|
+
this.props.onCancel();
|
|
52235
|
+
}
|
|
52236
|
+
else {
|
|
52237
|
+
this.props.onExit();
|
|
52144
52238
|
}
|
|
52145
52239
|
}
|
|
52146
52240
|
getDefaultRules() {
|
|
@@ -55702,9 +55796,15 @@ class SpreadsheetPivot {
|
|
|
55702
55796
|
return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
|
|
55703
55797
|
}
|
|
55704
55798
|
filterDataEntriesFromDomainNode(dataEntries, domain) {
|
|
55705
|
-
const { field, value } = domain;
|
|
55799
|
+
const { field, value, type } = domain;
|
|
55706
55800
|
const { nameWithGranularity } = this.getDimension(field);
|
|
55707
|
-
return dataEntries.filter((entry) =>
|
|
55801
|
+
return dataEntries.filter((entry) => {
|
|
55802
|
+
const cellValue = entry[nameWithGranularity]?.value;
|
|
55803
|
+
if (type === "char") {
|
|
55804
|
+
return String(cellValue) === String(value);
|
|
55805
|
+
}
|
|
55806
|
+
return cellValue === value;
|
|
55807
|
+
});
|
|
55708
55808
|
}
|
|
55709
55809
|
getDimension(nameWithGranularity) {
|
|
55710
55810
|
return this.definition.getDimension(nameWithGranularity);
|
|
@@ -65656,7 +65756,7 @@ class SpreadingRelation {
|
|
|
65656
65756
|
const EMPTY_ARRAY = [];
|
|
65657
65757
|
|
|
65658
65758
|
const MAX_ITERATION = 30;
|
|
65659
|
-
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
65759
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell({ ...new CircularDependencyError(), origin: undefined }));
|
|
65660
65760
|
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
65661
65761
|
class Evaluator {
|
|
65662
65762
|
context;
|
|
@@ -65890,11 +65990,12 @@ class Evaluator {
|
|
|
65890
65990
|
this.cellsBeingComputed.add(cellId);
|
|
65891
65991
|
return cell.isFormula
|
|
65892
65992
|
? this.computeFormulaCell(position, cell)
|
|
65893
|
-
: evaluateLiteral(cell, localeFormat);
|
|
65993
|
+
: evaluateLiteral(cell, localeFormat, position);
|
|
65894
65994
|
}
|
|
65895
65995
|
catch (e) {
|
|
65896
65996
|
e.value = e?.value || CellErrorType.GenericError;
|
|
65897
65997
|
e.message = e?.message || implementationErrorMessage;
|
|
65998
|
+
e.origin = position;
|
|
65898
65999
|
return createEvaluatedCell(e);
|
|
65899
66000
|
}
|
|
65900
66001
|
finally {
|
|
@@ -65911,7 +66012,7 @@ class Evaluator {
|
|
|
65911
66012
|
computeFormulaCell(formulaPosition, cellData) {
|
|
65912
66013
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
65913
66014
|
if (!isMatrix(formulaReturn)) {
|
|
65914
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
66015
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData, formulaPosition);
|
|
65915
66016
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65916
66017
|
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
65917
66018
|
}
|
|
@@ -65987,7 +66088,7 @@ class Evaluator {
|
|
|
65987
66088
|
const spreadValues = (i, j) => {
|
|
65988
66089
|
const position = { sheetId, col: i + col, row: j + row };
|
|
65989
66090
|
const cell = this.getters.getCell(position);
|
|
65990
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
66091
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell, position);
|
|
65991
66092
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65992
66093
|
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
65993
66094
|
}
|
|
@@ -66660,7 +66761,7 @@ class EvaluationChartPlugin extends CoreViewPlugin {
|
|
|
66660
66761
|
continue;
|
|
66661
66762
|
}
|
|
66662
66763
|
const figureId = figure.id;
|
|
66663
|
-
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel();
|
|
66764
|
+
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel(this.getters);
|
|
66664
66765
|
if (figureData) {
|
|
66665
66766
|
figures.push({
|
|
66666
66767
|
...figure,
|
|
@@ -67029,8 +67130,16 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
|
67029
67130
|
}
|
|
67030
67131
|
getDataValidationRangeValues(sheetId, criterion) {
|
|
67031
67132
|
const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
|
|
67032
|
-
const
|
|
67033
|
-
|
|
67133
|
+
const values = [];
|
|
67134
|
+
const labelsSet = new Set();
|
|
67135
|
+
for (const p of positions(range.zone)) {
|
|
67136
|
+
const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
|
|
67137
|
+
if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
|
|
67138
|
+
labelsSet.add(cell.formattedValue);
|
|
67139
|
+
values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
|
|
67140
|
+
}
|
|
67141
|
+
}
|
|
67142
|
+
return values;
|
|
67034
67143
|
}
|
|
67035
67144
|
isCellValidCheckbox(cellPosition) {
|
|
67036
67145
|
if (!this.getters.isMainCellPosition(cellPosition)) {
|
|
@@ -67573,6 +67682,23 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67573
67682
|
static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
|
|
67574
67683
|
tallestCellInRow = {};
|
|
67575
67684
|
ctx = document.createElement("canvas").getContext("2d");
|
|
67685
|
+
beforeHandle(cmd) {
|
|
67686
|
+
switch (cmd.type) {
|
|
67687
|
+
// Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
|
|
67688
|
+
// "UPDATE_CELL" uses the Sheet core plugin to access row data.
|
|
67689
|
+
// If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
|
|
67690
|
+
// size updates may apply to incorrect (pre-insert) rows.
|
|
67691
|
+
case "ADD_COLUMNS_ROWS":
|
|
67692
|
+
if (cmd.dimension === "COL") {
|
|
67693
|
+
return;
|
|
67694
|
+
}
|
|
67695
|
+
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67696
|
+
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67697
|
+
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67698
|
+
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67699
|
+
break;
|
|
67700
|
+
}
|
|
67701
|
+
}
|
|
67576
67702
|
handle(cmd) {
|
|
67577
67703
|
switch (cmd.type) {
|
|
67578
67704
|
case "START":
|
|
@@ -67602,16 +67728,6 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67602
67728
|
this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
|
|
67603
67729
|
break;
|
|
67604
67730
|
}
|
|
67605
|
-
case "ADD_COLUMNS_ROWS": {
|
|
67606
|
-
if (cmd.dimension === "COL") {
|
|
67607
|
-
return;
|
|
67608
|
-
}
|
|
67609
|
-
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67610
|
-
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67611
|
-
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67612
|
-
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67613
|
-
break;
|
|
67614
|
-
}
|
|
67615
67731
|
case "RESIZE_COLUMNS_ROWS":
|
|
67616
67732
|
{
|
|
67617
67733
|
const sheetId = cmd.sheetId;
|
|
@@ -74160,6 +74276,14 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74160
74276
|
const isBasedBefore = cmd.base < start;
|
|
74161
74277
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
74162
74278
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
74279
|
+
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74280
|
+
const originalSize = Object.fromEntries(toRemove.map((element) => {
|
|
74281
|
+
const size = isCol
|
|
74282
|
+
? this.getters.getColSize(cmd.sheetId, element)
|
|
74283
|
+
: this.getters.getUserRowSize(cmd.sheetId, element);
|
|
74284
|
+
const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
|
|
74285
|
+
return [element, isDefaultCol ? undefined : size];
|
|
74286
|
+
}));
|
|
74163
74287
|
const target = [
|
|
74164
74288
|
{
|
|
74165
74289
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -74190,13 +74314,12 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74190
74314
|
const col = selection.left;
|
|
74191
74315
|
const row = selection.top;
|
|
74192
74316
|
this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
|
|
74193
|
-
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74194
74317
|
let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
74195
74318
|
const resizingGroups = {};
|
|
74196
74319
|
for (const element of toRemove) {
|
|
74197
|
-
const size =
|
|
74320
|
+
const size = originalSize[element];
|
|
74198
74321
|
const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
|
|
74199
|
-
if (size !== currentSize) {
|
|
74322
|
+
if (size && size !== currentSize) {
|
|
74200
74323
|
resizingGroups[size] ??= [];
|
|
74201
74324
|
resizingGroups[size].push(currentIndex);
|
|
74202
74325
|
currentIndex += 1;
|
|
@@ -75622,6 +75745,7 @@ const coreViewsPluginRegistry = new Registry()
|
|
|
75622
75745
|
|
|
75623
75746
|
autoCompleteProviders.add("dataValidation", {
|
|
75624
75747
|
displayAllOnInitialContent: true,
|
|
75748
|
+
canBeToggled: false,
|
|
75625
75749
|
getProposals(tokenAtCursor, content) {
|
|
75626
75750
|
if (isFormula(content)) {
|
|
75627
75751
|
return [];
|
|
@@ -75637,25 +75761,30 @@ autoCompleteProviders.add("dataValidation", {
|
|
|
75637
75761
|
}
|
|
75638
75762
|
const sheetId = this.composer.currentEditedCell.sheetId;
|
|
75639
75763
|
const values = rule.criterion.type === "isValueInRange"
|
|
75640
|
-
?
|
|
75641
|
-
: rule.criterion.values;
|
|
75764
|
+
? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
|
|
75765
|
+
: rule.criterion.values.map((value) => ({ label: value, value }));
|
|
75642
75766
|
const isChip = rule.criterion.displayStyle === "chip";
|
|
75643
75767
|
if (!isChip) {
|
|
75644
|
-
return values.map((value) => ({
|
|
75768
|
+
return values.map((value) => ({
|
|
75769
|
+
text: value.value,
|
|
75770
|
+
fuzzySearchKey: value.label,
|
|
75771
|
+
htmlContent: [{ value: value.label }],
|
|
75772
|
+
}));
|
|
75645
75773
|
}
|
|
75646
75774
|
const colors = rule.criterion.colors;
|
|
75647
75775
|
return values.map((value) => {
|
|
75648
|
-
const color = colors?.[value];
|
|
75776
|
+
const color = colors?.[value.value];
|
|
75649
75777
|
return {
|
|
75650
|
-
text: value,
|
|
75778
|
+
text: value.value,
|
|
75651
75779
|
htmlContent: [
|
|
75652
75780
|
{
|
|
75653
|
-
value,
|
|
75781
|
+
value: value.label,
|
|
75654
75782
|
color: color ? chipTextColor(color) : undefined,
|
|
75655
75783
|
backgroundColor: color || GRAY_200,
|
|
75656
75784
|
classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
|
|
75657
75785
|
},
|
|
75658
75786
|
],
|
|
75787
|
+
fuzzySearchKey: value.label,
|
|
75659
75788
|
};
|
|
75660
75789
|
});
|
|
75661
75790
|
},
|
|
@@ -77187,14 +77316,12 @@ class BottomBarSheet extends owl.Component {
|
|
|
77187
77316
|
this.editionState = "initializing";
|
|
77188
77317
|
}
|
|
77189
77318
|
stopEdition() {
|
|
77190
|
-
|
|
77191
|
-
if (!this.state.isEditing || !input)
|
|
77319
|
+
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
77192
77320
|
return;
|
|
77193
77321
|
this.state.isEditing = false;
|
|
77194
77322
|
this.editionState = "initializing";
|
|
77195
|
-
|
|
77323
|
+
this.sheetNameRef.el.blur();
|
|
77196
77324
|
const inputValue = this.getInputContent() || "";
|
|
77197
|
-
input.innerText = inputValue;
|
|
77198
77325
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
77199
77326
|
}
|
|
77200
77327
|
cancelEdition() {
|
|
@@ -81612,6 +81739,9 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81612
81739
|
case "combo":
|
|
81613
81740
|
plot = addComboChart(chart.data);
|
|
81614
81741
|
break;
|
|
81742
|
+
case "pyramid":
|
|
81743
|
+
plot = addPyramidChart(chart.data);
|
|
81744
|
+
break;
|
|
81615
81745
|
case "line":
|
|
81616
81746
|
plot = addLineChart(chart.data);
|
|
81617
81747
|
break;
|
|
@@ -81619,12 +81749,12 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81619
81749
|
plot = addScatterChart(chart.data);
|
|
81620
81750
|
break;
|
|
81621
81751
|
case "pie":
|
|
81622
|
-
plot = addDoughnutChart(chart.data, chartSheetIndex, data
|
|
81752
|
+
plot = addDoughnutChart(chart.data, chartSheetIndex, data);
|
|
81623
81753
|
break;
|
|
81624
81754
|
case "radar":
|
|
81625
81755
|
plot = addRadarChart(chart.data);
|
|
81626
81756
|
}
|
|
81627
|
-
let position = "
|
|
81757
|
+
let position = "none";
|
|
81628
81758
|
switch (chart.data.legendPosition) {
|
|
81629
81759
|
case "bottom":
|
|
81630
81760
|
position = "b";
|
|
@@ -81654,7 +81784,7 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81654
81784
|
${plot}
|
|
81655
81785
|
${shapeProperty({ backgroundColor: chart.data.backgroundColor })}
|
|
81656
81786
|
</c:plotArea>
|
|
81657
|
-
${addLegend(position, fontColor)}
|
|
81787
|
+
${position !== "none" ? addLegend(position, fontColor) : ""}
|
|
81658
81788
|
</c:chart>
|
|
81659
81789
|
</c:chartSpace>
|
|
81660
81790
|
`;
|
|
@@ -81812,6 +81942,7 @@ function addBarChart(chart) {
|
|
|
81812
81942
|
//
|
|
81813
81943
|
// overlap and gapWitdh seems to be by default at -20 and 20 in chart.js.
|
|
81814
81944
|
// See https://www.chartjs.org/docs/latest/charts/bar.html and https://www.chartjs.org/docs/latest/charts/bar.html#barpercentage-vs-categorypercentage
|
|
81945
|
+
const chartDirection = chart.horizontal ? "bar" : "col";
|
|
81815
81946
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81816
81947
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
81817
81948
|
const leftDataSetsNodes = [];
|
|
@@ -81848,7 +81979,7 @@ function addBarChart(chart) {
|
|
|
81848
81979
|
${leftDataSetsNodes.length
|
|
81849
81980
|
? escapeXml /*xml*/ `
|
|
81850
81981
|
<c:barChart>
|
|
81851
|
-
<c:barDir val="
|
|
81982
|
+
<c:barDir val="${chartDirection}"/>
|
|
81852
81983
|
<c:grouping val="${grouping}"/>
|
|
81853
81984
|
<c:overlap val="${overlap}"/>
|
|
81854
81985
|
<c:gapWidth val="70"/>
|
|
@@ -81858,8 +81989,12 @@ function addBarChart(chart) {
|
|
|
81858
81989
|
<c:axId val="${catAxId}" />
|
|
81859
81990
|
<c:axId val="${valAxId}" />
|
|
81860
81991
|
</c:barChart>
|
|
81861
|
-
${
|
|
81862
|
-
|
|
81992
|
+
${chartDirection === "col"
|
|
81993
|
+
? addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor)
|
|
81994
|
+
: addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, undefined, "maxMin")}
|
|
81995
|
+
${chartDirection === "col"
|
|
81996
|
+
? addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)
|
|
81997
|
+
: addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, undefined, undefined, "max")}
|
|
81863
81998
|
`
|
|
81864
81999
|
: ""}
|
|
81865
82000
|
${rightDataSetsNodes.length
|
|
@@ -81985,7 +82120,7 @@ function addComboChart(chart) {
|
|
|
81985
82120
|
: ""}
|
|
81986
82121
|
${!useRightAxisForBarSerie || leftDataSetsNodes.length
|
|
81987
82122
|
? escapeXml /*xml*/ `
|
|
81988
|
-
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor,
|
|
82123
|
+
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor, 0)}
|
|
81989
82124
|
${addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)}
|
|
81990
82125
|
`
|
|
81991
82126
|
: ""}
|
|
@@ -81997,6 +82132,94 @@ function addComboChart(chart) {
|
|
|
81997
82132
|
: ""}
|
|
81998
82133
|
`;
|
|
81999
82134
|
}
|
|
82135
|
+
function addPyramidChart(chart) {
|
|
82136
|
+
const dataSets = chart.dataSets;
|
|
82137
|
+
const dataSetsColors = dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82138
|
+
const colors = new ColorGenerator(dataSets.length, dataSetsColors);
|
|
82139
|
+
const leftDataSet = dataSets[0];
|
|
82140
|
+
const rightDataSet = dataSets[1];
|
|
82141
|
+
const firstColor = toXlsxHexColor(colors.next());
|
|
82142
|
+
const secondColor = toXlsxHexColor(colors.next());
|
|
82143
|
+
const { maxValue, majorUnit } = getPyramidChartHorizontalAxisConfig(chart.maxValue);
|
|
82144
|
+
const labelRangeEl = chart.labelRange
|
|
82145
|
+
? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>`
|
|
82146
|
+
: "";
|
|
82147
|
+
const leftBarDataSetNode = escapeXml /*xml*/ `
|
|
82148
|
+
<c:ser>
|
|
82149
|
+
<c:idx val="0"/>
|
|
82150
|
+
<c:order val="0"/>
|
|
82151
|
+
<c:invertIfNegative val="0" />
|
|
82152
|
+
${extractDataSetLabel(leftDataSet.label)}
|
|
82153
|
+
${shapeProperty({
|
|
82154
|
+
backgroundColor: firstColor,
|
|
82155
|
+
line: { color: firstColor },
|
|
82156
|
+
})}
|
|
82157
|
+
${labelRangeEl}
|
|
82158
|
+
<!-- x-coordinate values -->
|
|
82159
|
+
<c:val>
|
|
82160
|
+
${numberRef(leftDataSet.range)}
|
|
82161
|
+
</c:val>
|
|
82162
|
+
</c:ser>
|
|
82163
|
+
`;
|
|
82164
|
+
const rightBarDataSetNode = escapeXml /*xml*/ `
|
|
82165
|
+
<c:ser>
|
|
82166
|
+
<c:idx val="1"/>
|
|
82167
|
+
<c:order val="1"/>
|
|
82168
|
+
<c:invertIfNegative val="0" />
|
|
82169
|
+
${extractDataSetLabel(rightDataSet.label)}
|
|
82170
|
+
${shapeProperty({
|
|
82171
|
+
backgroundColor: secondColor,
|
|
82172
|
+
line: { color: secondColor },
|
|
82173
|
+
})}
|
|
82174
|
+
${chart.labelRange ? escapeXml /*xml*/ `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""}
|
|
82175
|
+
<!-- x-coordinate values -->
|
|
82176
|
+
<c:val>
|
|
82177
|
+
${numberRef(rightDataSet.range)}
|
|
82178
|
+
</c:val>
|
|
82179
|
+
</c:ser>
|
|
82180
|
+
`;
|
|
82181
|
+
return escapeXml /*xml*/ `
|
|
82182
|
+
<c:barChart>
|
|
82183
|
+
<c:barDir val="bar"/>
|
|
82184
|
+
<c:grouping val="clustered"/>
|
|
82185
|
+
<c:varyColors val="0" />
|
|
82186
|
+
${leftBarDataSetNode}
|
|
82187
|
+
<c:gapWidth val="50" />
|
|
82188
|
+
<c:axId val="${catAxId}" />
|
|
82189
|
+
<c:axId val="${valAxId}" />
|
|
82190
|
+
</c:barChart>
|
|
82191
|
+
<c:barChart>
|
|
82192
|
+
<c:barDir val="bar"/>
|
|
82193
|
+
<c:grouping val="clustered"/>
|
|
82194
|
+
<c:varyColors val="0" />
|
|
82195
|
+
${rightBarDataSetNode}
|
|
82196
|
+
<c:gapWidth val="50" />
|
|
82197
|
+
<c:axId val="${secondaryCatAxId}" />
|
|
82198
|
+
<c:axId val="${secondaryValAxId}" />
|
|
82199
|
+
</c:barChart>
|
|
82200
|
+
${addAx("r", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, 0, "maxMin", "autoZero", "high")}
|
|
82201
|
+
${addAx("b", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, 0, "maxMin", "max", "nextTo", maxValue, majorUnit, "#0;#0")}
|
|
82202
|
+
${addAx("t", "c:valAx", secondaryValAxId, secondaryCatAxId, undefined, chart.fontColor, 1)}
|
|
82203
|
+
${addAx("l", "c:catAx", secondaryCatAxId, secondaryValAxId, undefined, chart.fontColor, 1, "maxMin")}
|
|
82204
|
+
`;
|
|
82205
|
+
}
|
|
82206
|
+
function getPyramidChartHorizontalAxisConfig(maxValue) {
|
|
82207
|
+
const adjustMaxToDivisibleBy = (value, divisor) => {
|
|
82208
|
+
let adjusted = Math.ceil(value);
|
|
82209
|
+
while (adjusted % divisor !== 0) {
|
|
82210
|
+
adjusted++;
|
|
82211
|
+
}
|
|
82212
|
+
return adjusted;
|
|
82213
|
+
};
|
|
82214
|
+
const tickCount = 4;
|
|
82215
|
+
const interval = tickCount - 1;
|
|
82216
|
+
const adjustedMax = adjustMaxToDivisibleBy(maxValue, interval);
|
|
82217
|
+
const majorUnit = adjustedMax / interval;
|
|
82218
|
+
return {
|
|
82219
|
+
maxValue: adjustedMax,
|
|
82220
|
+
majorUnit,
|
|
82221
|
+
};
|
|
82222
|
+
}
|
|
82000
82223
|
function addLineChart(chart) {
|
|
82001
82224
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82002
82225
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
@@ -82189,7 +82412,7 @@ function addRadarChart(chart) {
|
|
|
82189
82412
|
`}
|
|
82190
82413
|
`;
|
|
82191
82414
|
}
|
|
82192
|
-
function addDoughnutChart(chart, chartSheetIndex, data
|
|
82415
|
+
function addDoughnutChart(chart, chartSheetIndex, data) {
|
|
82193
82416
|
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
82194
82417
|
const colors = new ColorGenerator(maxLength);
|
|
82195
82418
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
@@ -82227,7 +82450,7 @@ function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSiz
|
|
|
82227
82450
|
return escapeXml /*xml*/ `
|
|
82228
82451
|
<c:doughnutChart>
|
|
82229
82452
|
<c:varyColors val="1" />
|
|
82230
|
-
<c:holeSize val="${
|
|
82453
|
+
<c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
|
|
82231
82454
|
${insertDataLabels()}
|
|
82232
82455
|
${joinXmlNodes(dataSetsNodes)}
|
|
82233
82456
|
</c:doughnutChart>
|
|
@@ -82246,25 +82469,35 @@ function insertDataLabels({ showLeaderLines } = { showLeaderLines: false }) {
|
|
|
82246
82469
|
</dLbls>
|
|
82247
82470
|
`;
|
|
82248
82471
|
}
|
|
82249
|
-
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0) {
|
|
82472
|
+
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
|
|
82250
82473
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
82251
82474
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
82252
82475
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
82253
82476
|
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
82477
|
+
const crossBetweenEl = axisName === "c:valAx" ? escapeXml `<c:crossBetween val="between" />` : "";
|
|
82478
|
+
const maxValueEl = maxValue ? escapeXml `<c:max val="${maxValue}" />` : "";
|
|
82479
|
+
const minValueEl = maxValue ? escapeXml `<c:min val="${-maxValue}" />` : "";
|
|
82480
|
+
const majorUnitEl = majorUnit ? escapeXml `<c:majorUnit val="${majorUnit}" />` : "";
|
|
82254
82481
|
return escapeXml /*xml*/ `
|
|
82255
82482
|
<${axisName}>
|
|
82256
82483
|
<c:axId val="${axId}"/>
|
|
82257
82484
|
<c:crossAx val="${crossAxId}"/> <!-- reference to the other axe of the chart -->
|
|
82258
|
-
<c:crosses val="${position === "b" || position === "l" ? "min" : "max"}"/>
|
|
82485
|
+
<c:crosses val="${crossPosition || (position === "b" || position === "l" ? "min" : "max")}"/>
|
|
82486
|
+
<c:auto val="1"/>
|
|
82487
|
+
${crossBetweenEl}
|
|
82259
82488
|
<c:delete val="${deleteAxis}"/> <!-- by default, axis are not displayed -->
|
|
82260
82489
|
<c:scaling>
|
|
82261
|
-
<c:orientation val="
|
|
82490
|
+
<c:orientation val="${orientation}" />
|
|
82491
|
+
${maxValueEl}
|
|
82492
|
+
${minValueEl}
|
|
82262
82493
|
</c:scaling>
|
|
82494
|
+
${majorUnitEl}
|
|
82263
82495
|
<c:axPos val="${position}" />
|
|
82496
|
+
<c:tickLblPos val="${tickLabelPosition}" />
|
|
82264
82497
|
${insertMajorGridLines()}
|
|
82265
82498
|
<c:majorTickMark val="out" />
|
|
82266
82499
|
<c:minorTickMark val="none" />
|
|
82267
|
-
<c:numFmt formatCode="
|
|
82500
|
+
<c:numFmt formatCode="${format}" sourceLinked="${format === "General" ? "1" : "0"}" />
|
|
82268
82501
|
<c:title>
|
|
82269
82502
|
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
82270
82503
|
</c:title>
|
|
@@ -82459,7 +82692,10 @@ function addConditionalFormatting(dxfs, conditionalFormats) {
|
|
|
82459
82692
|
function addCellIsRule(cf, rule, dxfs) {
|
|
82460
82693
|
const ruleAttributes = commonCfAttributes(cf);
|
|
82461
82694
|
const operator = convertOperator(rule.operator);
|
|
82462
|
-
ruleAttributes.push(...cellRuleTypeAttributes(rule)
|
|
82695
|
+
ruleAttributes.push(...cellRuleTypeAttributes(rule));
|
|
82696
|
+
if (operator.length) {
|
|
82697
|
+
ruleAttributes.push(["operator", operator]);
|
|
82698
|
+
}
|
|
82463
82699
|
const formulas = cellRuleFormula(cf.ranges, rule).map((formula) => escapeXml /*xml*/ `<formula>${formula}</formula>`);
|
|
82464
82700
|
const dxf = {
|
|
82465
82701
|
font: {
|
|
@@ -82505,6 +82741,8 @@ function cellRuleFormula(ranges, rule) {
|
|
|
82505
82741
|
case "isLessThan":
|
|
82506
82742
|
case "isLessOrEqualTo":
|
|
82507
82743
|
return [values[0]];
|
|
82744
|
+
case "customFormula":
|
|
82745
|
+
return values[0].startsWith("=") ? [values[0].slice(1)] : [values[0]];
|
|
82508
82746
|
case "isBetween":
|
|
82509
82747
|
case "isNotBetween":
|
|
82510
82748
|
return [values[0], values[1]];
|
|
@@ -82533,6 +82771,8 @@ function cellRuleTypeAttributes(rule) {
|
|
|
82533
82771
|
case "isBetween":
|
|
82534
82772
|
case "isNotBetween":
|
|
82535
82773
|
return [["type", "cellIs"]];
|
|
82774
|
+
case "customFormula":
|
|
82775
|
+
return [["type", "expression"]];
|
|
82536
82776
|
}
|
|
82537
82777
|
}
|
|
82538
82778
|
function addDataBarRule(cf, rule) {
|
|
@@ -84518,6 +84758,8 @@ const components = {
|
|
|
84518
84758
|
WaterfallChartDesignPanel,
|
|
84519
84759
|
ComboChartDesignPanel,
|
|
84520
84760
|
FunnelChartDesignPanel,
|
|
84761
|
+
SunburstChartDesignPanel,
|
|
84762
|
+
TreeMapChartDesignPanel,
|
|
84521
84763
|
ChartTypePicker,
|
|
84522
84764
|
FigureComponent,
|
|
84523
84765
|
MenuPopover,
|
|
@@ -84547,6 +84789,7 @@ const hooks = {
|
|
|
84547
84789
|
};
|
|
84548
84790
|
const stores = {
|
|
84549
84791
|
useStoreProvider,
|
|
84792
|
+
ChartDashboardMenuStore,
|
|
84550
84793
|
DependencyContainer,
|
|
84551
84794
|
CellPopoverStore,
|
|
84552
84795
|
ComposerFocusStore,
|
|
@@ -84633,6 +84876,6 @@ exports.tokenColors = tokenColors;
|
|
|
84633
84876
|
exports.tokenize = tokenize;
|
|
84634
84877
|
|
|
84635
84878
|
|
|
84636
|
-
__info__.version = "18.5.0-alpha.
|
|
84637
|
-
__info__.date = "2025-07-
|
|
84638
|
-
__info__.hash = "
|
|
84879
|
+
__info__.version = "18.5.0-alpha.4";
|
|
84880
|
+
__info__.date = "2025-07-30T11:23:18.805Z";
|
|
84881
|
+
__info__.hash = "34a4ab3";
|