@odoo/o-spreadsheet 17.4.3 → 17.4.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 +102 -97
- package/dist/o-spreadsheet.d.ts +2 -1
- package/dist/o-spreadsheet.esm.js +102 -97
- package/dist/o-spreadsheet.iife.js +102 -97
- package/dist/o-spreadsheet.iife.min.js +340 -340
- package/dist/o_spreadsheet.xml +3 -3
- 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 17.4.
|
|
6
|
-
* @date 2024-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.4
|
|
6
|
+
* @date 2024-08-09T12:24:07.798Z
|
|
7
|
+
* @hash a43e855
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -10577,6 +10577,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10577
10577
|
useLeftAxis ||= !useRightAxis;
|
|
10578
10578
|
return { useLeftAxis, useRightAxis };
|
|
10579
10579
|
}
|
|
10580
|
+
function formatTickValue(localeFormat) {
|
|
10581
|
+
return (value) => {
|
|
10582
|
+
value = Number(value);
|
|
10583
|
+
if (isNaN(value))
|
|
10584
|
+
return value;
|
|
10585
|
+
const { locale, format } = localeFormat;
|
|
10586
|
+
return formatValue(value, {
|
|
10587
|
+
locale,
|
|
10588
|
+
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
10589
|
+
});
|
|
10590
|
+
};
|
|
10591
|
+
}
|
|
10580
10592
|
|
|
10581
10593
|
/** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
|
|
10582
10594
|
const chartShowValuesPlugin = {
|
|
@@ -19125,6 +19137,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19125
19137
|
const pivot = this.getters.getPivot(pivotId);
|
|
19126
19138
|
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
|
|
19127
19139
|
addPivotDependencies(this, coreDefinition);
|
|
19140
|
+
pivot.init({ reload: pivot.needsReevaluation });
|
|
19128
19141
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19129
19142
|
if (error) {
|
|
19130
19143
|
return error;
|
|
@@ -19153,6 +19166,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19153
19166
|
const pivot = this.getters.getPivot(_pivotId);
|
|
19154
19167
|
const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
|
|
19155
19168
|
addPivotDependencies(this, coreDefinition);
|
|
19169
|
+
pivot.init({ reload: pivot.needsReevaluation });
|
|
19156
19170
|
const error = pivot.assertIsValid({ throwOnError: false });
|
|
19157
19171
|
if (error) {
|
|
19158
19172
|
return error;
|
|
@@ -20370,14 +20384,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20370
20384
|
}
|
|
20371
20385
|
const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
20372
20386
|
function createComputeFunction(descr, functionName) {
|
|
20373
|
-
function runtimeCompute(...args) {
|
|
20374
|
-
try {
|
|
20375
|
-
return vectorizedCompute.apply(this, args);
|
|
20376
|
-
}
|
|
20377
|
-
catch (e) {
|
|
20378
|
-
return handleError(e, functionName);
|
|
20379
|
-
}
|
|
20380
|
-
}
|
|
20381
20387
|
function vectorizedCompute(...args) {
|
|
20382
20388
|
let countVectorizableCol = 1;
|
|
20383
20389
|
let countVectorizableRow = 1;
|
|
@@ -20418,13 +20424,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20418
20424
|
}
|
|
20419
20425
|
}
|
|
20420
20426
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
20421
|
-
throw new BadExpressionError(_t("Function
|
|
20427
|
+
throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
|
|
20422
20428
|
}
|
|
20423
20429
|
}
|
|
20424
20430
|
//#endregion
|
|
20425
20431
|
if (countVectorizableCol === 1 && countVectorizableRow === 1) {
|
|
20426
20432
|
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
20427
|
-
return
|
|
20433
|
+
return errorHandlingCompute.apply(this, args);
|
|
20428
20434
|
}
|
|
20429
20435
|
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
20430
20436
|
switch (vectorArgsType?.[index]) {
|
|
@@ -20442,7 +20448,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20442
20448
|
if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
|
|
20443
20449
|
return notAvailableError;
|
|
20444
20450
|
}
|
|
20445
|
-
const singleCellComputeResult =
|
|
20451
|
+
const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
|
|
20446
20452
|
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
20447
20453
|
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
20448
20454
|
// we won't be able to return the values.
|
|
@@ -20457,6 +20463,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20457
20463
|
: singleCellComputeResult;
|
|
20458
20464
|
});
|
|
20459
20465
|
}
|
|
20466
|
+
function errorHandlingCompute(...args) {
|
|
20467
|
+
try {
|
|
20468
|
+
return computeFunctionToObject.apply(this, args);
|
|
20469
|
+
}
|
|
20470
|
+
catch (e) {
|
|
20471
|
+
return handleError(e, functionName);
|
|
20472
|
+
}
|
|
20473
|
+
}
|
|
20460
20474
|
function computeFunctionToObject(...args) {
|
|
20461
20475
|
const result = descr.compute.apply(this, args);
|
|
20462
20476
|
if (!isMatrix(result)) {
|
|
@@ -20472,7 +20486,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20472
20486
|
}
|
|
20473
20487
|
return matrixMap(result, (row) => ({ value: row }));
|
|
20474
20488
|
}
|
|
20475
|
-
return
|
|
20489
|
+
return vectorizedCompute;
|
|
20476
20490
|
}
|
|
20477
20491
|
function handleError(e, functionName) {
|
|
20478
20492
|
// the error could be an user error (instance of EvaluationError)
|
|
@@ -23693,23 +23707,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23693
23707
|
padding: { left: 20, right: 20, top: chart.title ? 10 : 25, bottom: 10 },
|
|
23694
23708
|
};
|
|
23695
23709
|
config.options.indexAxis = chart.horizontal ? "y" : "x";
|
|
23696
|
-
const formatCallback = (value) => {
|
|
23697
|
-
value = Number(value);
|
|
23698
|
-
if (isNaN(value))
|
|
23699
|
-
return value;
|
|
23700
|
-
const { locale, format } = localeFormat;
|
|
23701
|
-
return formatValue(value, {
|
|
23702
|
-
locale,
|
|
23703
|
-
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
23704
|
-
});
|
|
23705
|
-
};
|
|
23706
23710
|
config.options.scales = {};
|
|
23707
23711
|
const labelsAxis = { ticks: { padding: 5, color: fontColor } };
|
|
23708
23712
|
const valuesAxis = {
|
|
23709
23713
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
23710
23714
|
ticks: {
|
|
23711
23715
|
color: fontColor,
|
|
23712
|
-
callback:
|
|
23716
|
+
callback: formatTickValue(localeFormat),
|
|
23713
23717
|
},
|
|
23714
23718
|
};
|
|
23715
23719
|
const xAxis = chart.horizontal ? valuesAxis : labelsAxis;
|
|
@@ -23746,7 +23750,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23746
23750
|
showValues: chart.showValues,
|
|
23747
23751
|
background: chart.background,
|
|
23748
23752
|
horizontal: chart.horizontal,
|
|
23749
|
-
callback:
|
|
23753
|
+
callback: formatTickValue(localeFormat),
|
|
23750
23754
|
};
|
|
23751
23755
|
return config;
|
|
23752
23756
|
}
|
|
@@ -24025,21 +24029,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24025
24029
|
title: getChartAxisTitleRuntime(chart.axesDesign?.x),
|
|
24026
24030
|
},
|
|
24027
24031
|
};
|
|
24028
|
-
const formatCallback = (value) => {
|
|
24029
|
-
value = Number(value);
|
|
24030
|
-
if (isNaN(value))
|
|
24031
|
-
return value;
|
|
24032
|
-
const { locale, format } = options;
|
|
24033
|
-
return formatValue(value, {
|
|
24034
|
-
locale,
|
|
24035
|
-
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
24036
|
-
});
|
|
24037
|
-
};
|
|
24038
24032
|
const yAxis = {
|
|
24039
24033
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
24040
24034
|
ticks: {
|
|
24041
24035
|
color: fontColor,
|
|
24042
|
-
callback:
|
|
24036
|
+
callback: formatTickValue(options),
|
|
24043
24037
|
},
|
|
24044
24038
|
};
|
|
24045
24039
|
const { useLeftAxis, useRightAxis } = getDefinedAxis(chart.getDefinition());
|
|
@@ -24070,7 +24064,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24070
24064
|
config.options.plugins.chartShowValuesPlugin = {
|
|
24071
24065
|
showValues: chart.showValues,
|
|
24072
24066
|
background: chart.background,
|
|
24073
|
-
callback:
|
|
24067
|
+
callback: formatTickValue(options),
|
|
24074
24068
|
};
|
|
24075
24069
|
return config;
|
|
24076
24070
|
}
|
|
@@ -24345,30 +24339,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24345
24339
|
title: getChartAxisTitleRuntime(chart.axesDesign?.x),
|
|
24346
24340
|
},
|
|
24347
24341
|
};
|
|
24348
|
-
const formatCallback = (format) => {
|
|
24349
|
-
return (value) => {
|
|
24350
|
-
value = Number(value);
|
|
24351
|
-
if (isNaN(value))
|
|
24352
|
-
return value;
|
|
24353
|
-
const { locale } = localeFormat;
|
|
24354
|
-
return formatValue(value, {
|
|
24355
|
-
locale,
|
|
24356
|
-
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
24357
|
-
});
|
|
24358
|
-
};
|
|
24359
|
-
};
|
|
24360
24342
|
const leftVerticalAxis = {
|
|
24361
24343
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
24362
24344
|
ticks: {
|
|
24363
24345
|
color: fontColor,
|
|
24364
|
-
callback:
|
|
24346
|
+
callback: formatTickValue({ format: mainDataSetFormat, locale }),
|
|
24365
24347
|
},
|
|
24366
24348
|
};
|
|
24367
24349
|
const rightVerticalAxis = {
|
|
24368
24350
|
beginAtZero: true, // the origin of the y axis is always zero
|
|
24369
24351
|
ticks: {
|
|
24370
24352
|
color: fontColor,
|
|
24371
|
-
callback:
|
|
24353
|
+
callback: formatTickValue({ format: lineDataSetsFormat, locale }),
|
|
24372
24354
|
},
|
|
24373
24355
|
};
|
|
24374
24356
|
const definition = chart.getDefinition();
|
|
@@ -24393,7 +24375,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24393
24375
|
config.options.plugins.chartShowValuesPlugin = {
|
|
24394
24376
|
showValues: chart.showValues,
|
|
24395
24377
|
background: chart.background,
|
|
24396
|
-
callback:
|
|
24378
|
+
callback: formatTickValue({ format: mainDataSetFormat, locale }),
|
|
24397
24379
|
};
|
|
24398
24380
|
const colors = new ColorGenerator();
|
|
24399
24381
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
@@ -24925,7 +24907,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24925
24907
|
const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
|
|
24926
24908
|
return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
|
|
24927
24909
|
};
|
|
24928
|
-
config.options.plugins.chartShowValuesPlugin = {
|
|
24910
|
+
config.options.plugins.chartShowValuesPlugin = {
|
|
24911
|
+
showValues: chart.showValues,
|
|
24912
|
+
callback: formatTickValue(localeFormat),
|
|
24913
|
+
};
|
|
24929
24914
|
return config;
|
|
24930
24915
|
}
|
|
24931
24916
|
function getPieColors(colors, dataSetsValues) {
|
|
@@ -25509,6 +25494,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25509
25494
|
config.options.plugins.chartShowValuesPlugin = {
|
|
25510
25495
|
showValues: chart.showValues,
|
|
25511
25496
|
background: chart.background,
|
|
25497
|
+
callback: formatTickValue(localeFormat),
|
|
25512
25498
|
};
|
|
25513
25499
|
return config;
|
|
25514
25500
|
}
|
|
@@ -50413,7 +50399,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50413
50399
|
* @param sheetXC the string description of a range, in the form SheetName!XC:XC
|
|
50414
50400
|
*/
|
|
50415
50401
|
getRangeFromSheetXC(defaultSheetId, sheetXC) {
|
|
50416
|
-
if (!rangeReference.test(sheetXC)) {
|
|
50402
|
+
if (!rangeReference.test(sheetXC) || !this.getters.tryGetSheet(defaultSheetId)) {
|
|
50417
50403
|
return new RangeImpl({
|
|
50418
50404
|
sheetId: "",
|
|
50419
50405
|
zone: { left: -1, top: -1, right: -1, bottom: -1 },
|
|
@@ -54066,18 +54052,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54066
54052
|
this.evaluate(this.getAllCells());
|
|
54067
54053
|
console.info("evaluate all cells", performance.now() - start, "ms");
|
|
54068
54054
|
}
|
|
54069
|
-
|
|
54070
|
-
|
|
54071
|
-
|
|
54072
|
-
|
|
54073
|
-
|
|
54074
|
-
|
|
54075
|
-
|
|
54055
|
+
evaluateFormulaResult(sheetId, formulaString) {
|
|
54056
|
+
try {
|
|
54057
|
+
const compiledFormula = compile(formulaString);
|
|
54058
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
54059
|
+
this.updateCompilationParameters();
|
|
54060
|
+
const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
|
|
54061
|
+
if (isMatrix(result)) {
|
|
54062
|
+
return result;
|
|
54063
|
+
}
|
|
54064
|
+
if (result.value === null) {
|
|
54065
|
+
return { value: 0, format: result.format };
|
|
54066
|
+
}
|
|
54067
|
+
return result;
|
|
54076
54068
|
}
|
|
54077
|
-
|
|
54078
|
-
return
|
|
54069
|
+
catch (error) {
|
|
54070
|
+
return handleError(error, "");
|
|
54079
54071
|
}
|
|
54080
|
-
return result.value;
|
|
54081
54072
|
}
|
|
54082
54073
|
getAllCells() {
|
|
54083
54074
|
const positions = this.createEmptyPositionSet();
|
|
@@ -54440,6 +54431,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54440
54431
|
class EvaluationPlugin extends UIPlugin {
|
|
54441
54432
|
static getters = [
|
|
54442
54433
|
"evaluateFormula",
|
|
54434
|
+
"evaluateFormulaResult",
|
|
54443
54435
|
"getCorrespondingFormulaCell",
|
|
54444
54436
|
"getRangeFormattedValues",
|
|
54445
54437
|
"getRangeValues",
|
|
@@ -54499,12 +54491,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54499
54491
|
// Getters
|
|
54500
54492
|
// ---------------------------------------------------------------------------
|
|
54501
54493
|
evaluateFormula(sheetId, formulaString) {
|
|
54502
|
-
|
|
54503
|
-
|
|
54504
|
-
|
|
54505
|
-
catch (error) {
|
|
54506
|
-
return error.value || CellErrorType.GenericError;
|
|
54494
|
+
const result = this.evaluateFormulaResult(sheetId, formulaString);
|
|
54495
|
+
if (isMatrix(result)) {
|
|
54496
|
+
return matrixMap(result, (cell) => cell.value);
|
|
54507
54497
|
}
|
|
54498
|
+
return result.value;
|
|
54499
|
+
}
|
|
54500
|
+
evaluateFormulaResult(sheetId, formulaString) {
|
|
54501
|
+
return this.evaluator.evaluateFormulaResult(sheetId, formulaString);
|
|
54508
54502
|
}
|
|
54509
54503
|
/**
|
|
54510
54504
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -55887,28 +55881,33 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55887
55881
|
const pivotRow = position.row - mainPosition.row;
|
|
55888
55882
|
return pivotCells[pivotCol][pivotRow];
|
|
55889
55883
|
}
|
|
55890
|
-
|
|
55891
|
-
|
|
55884
|
+
try {
|
|
55885
|
+
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
55886
|
+
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
55887
|
+
return {
|
|
55888
|
+
type: "MEASURE_HEADER",
|
|
55889
|
+
domain,
|
|
55890
|
+
measure: args.at(-1)?.toString() || "",
|
|
55891
|
+
};
|
|
55892
|
+
}
|
|
55893
|
+
else if (functionName === "PIVOT.HEADER") {
|
|
55894
|
+
const domain = pivot.parseArgsToPivotDomain(args.slice(1).map((value) => ({ value })));
|
|
55895
|
+
return {
|
|
55896
|
+
type: "HEADER",
|
|
55897
|
+
domain,
|
|
55898
|
+
};
|
|
55899
|
+
}
|
|
55900
|
+
const [measure, ...domainArgs] = args.slice(1);
|
|
55901
|
+
const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
|
|
55892
55902
|
return {
|
|
55893
|
-
type: "
|
|
55903
|
+
type: "VALUE",
|
|
55894
55904
|
domain,
|
|
55895
|
-
measure:
|
|
55905
|
+
measure: measure?.toString() || "",
|
|
55896
55906
|
};
|
|
55897
55907
|
}
|
|
55898
|
-
|
|
55899
|
-
|
|
55900
|
-
return {
|
|
55901
|
-
type: "HEADER",
|
|
55902
|
-
domain,
|
|
55903
|
-
};
|
|
55908
|
+
catch (_) {
|
|
55909
|
+
return EMPTY_PIVOT_CELL;
|
|
55904
55910
|
}
|
|
55905
|
-
const [measure, ...domainArgs] = args.slice(1);
|
|
55906
|
-
const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
|
|
55907
|
-
return {
|
|
55908
|
-
type: "VALUE",
|
|
55909
|
-
domain,
|
|
55910
|
-
measure: measure?.toString() || "",
|
|
55911
|
-
};
|
|
55912
55911
|
}
|
|
55913
55912
|
getPivot(pivotId) {
|
|
55914
55913
|
return this.pivots[pivotId];
|
|
@@ -57776,6 +57775,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57776
57775
|
* evaluated and updated with the number type.
|
|
57777
57776
|
*/
|
|
57778
57777
|
setDecimal(sheetId, zones, step) {
|
|
57778
|
+
const positionsByFormat = {};
|
|
57779
57779
|
// Find the each cell with a number value and get the format
|
|
57780
57780
|
for (const zone of recomputeZones(zones)) {
|
|
57781
57781
|
for (const position of positions(zone)) {
|
|
@@ -57785,15 +57785,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57785
57785
|
// of the format
|
|
57786
57786
|
this.getters.getLocale();
|
|
57787
57787
|
const newFormat = changeDecimalPlaces(numberFormat, step);
|
|
57788
|
-
|
|
57789
|
-
|
|
57790
|
-
sheetId,
|
|
57791
|
-
target: [positionToZone(position)],
|
|
57792
|
-
format: newFormat,
|
|
57793
|
-
});
|
|
57788
|
+
positionsByFormat[newFormat] = positionsByFormat[newFormat] || [];
|
|
57789
|
+
positionsByFormat[newFormat].push(position);
|
|
57794
57790
|
}
|
|
57795
57791
|
}
|
|
57796
57792
|
}
|
|
57793
|
+
// consolidate all positions with the same format in bigger zones
|
|
57794
|
+
for (const newFormat in positionsByFormat) {
|
|
57795
|
+
const zones = recomputeZones(positionsByFormat[newFormat].map((position) => positionToZone(position)));
|
|
57796
|
+
this.dispatch("SET_FORMATTING", {
|
|
57797
|
+
sheetId,
|
|
57798
|
+
format: newFormat,
|
|
57799
|
+
target: zones,
|
|
57800
|
+
});
|
|
57801
|
+
}
|
|
57797
57802
|
}
|
|
57798
57803
|
/**
|
|
57799
57804
|
* Take a range of cells and return the format of the first cell containing a
|
|
@@ -68423,9 +68428,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68423
68428
|
exports.tokenize = tokenize;
|
|
68424
68429
|
|
|
68425
68430
|
|
|
68426
|
-
__info__.version = "17.4.
|
|
68427
|
-
__info__.date = "2024-08-
|
|
68428
|
-
__info__.hash = "
|
|
68431
|
+
__info__.version = "17.4.4";
|
|
68432
|
+
__info__.date = "2024-08-09T12:24:07.798Z";
|
|
68433
|
+
__info__.hash = "a43e855";
|
|
68429
68434
|
|
|
68430
68435
|
|
|
68431
68436
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|