@odoo/o-spreadsheet 18.4.9 → 18.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +90 -56
- package/dist/o-spreadsheet.d.ts +4 -3
- package/dist/o-spreadsheet.esm.js +90 -56
- package/dist/o-spreadsheet.iife.js +90 -56
- package/dist/o-spreadsheet.iife.min.js +5 -5
- package/dist/o_spreadsheet.xml +10 -7
- package/package.json +16 -3
|
@@ -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.4.
|
|
6
|
-
* @date 2025-09-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.4.11
|
|
6
|
+
* @date 2025-09-19T07:25:39.033Z
|
|
7
|
+
* @hash c7e71ac
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -890,8 +890,19 @@
|
|
|
890
890
|
},
|
|
891
891
|
}[funcName];
|
|
892
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* Removes the specified indexes from the array.
|
|
895
|
+
* Sparse (empty) elements are transformed to undefined (unless their index is explicitly removed).
|
|
896
|
+
*/
|
|
893
897
|
function removeIndexesFromArray(array, indexes) {
|
|
894
|
-
|
|
898
|
+
const toRemove = new Set(indexes);
|
|
899
|
+
const newArray = [];
|
|
900
|
+
for (let i = 0; i < array.length; i++) {
|
|
901
|
+
if (!toRemove.has(i)) {
|
|
902
|
+
newArray.push(array[i]);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return newArray;
|
|
895
906
|
}
|
|
896
907
|
function insertItemsAtIndex(array, items, index) {
|
|
897
908
|
const newArray = [...array];
|
|
@@ -7355,7 +7366,7 @@
|
|
|
7355
7366
|
this.getters = getters;
|
|
7356
7367
|
this.dispatch = dispatch;
|
|
7357
7368
|
}
|
|
7358
|
-
copy(data, isCutOperation) {
|
|
7369
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
7359
7370
|
return;
|
|
7360
7371
|
}
|
|
7361
7372
|
paste(target, clippedContent, options) { }
|
|
@@ -7374,7 +7385,7 @@
|
|
|
7374
7385
|
}
|
|
7375
7386
|
|
|
7376
7387
|
class AbstractCellClipboardHandler extends ClipboardHandler {
|
|
7377
|
-
copy(data) {
|
|
7388
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
7378
7389
|
return;
|
|
7379
7390
|
}
|
|
7380
7391
|
pasteFromCopy(sheetId, target, content, options) {
|
|
@@ -8904,7 +8915,7 @@
|
|
|
8904
8915
|
}
|
|
8905
8916
|
return "Success" /* CommandResult.Success */;
|
|
8906
8917
|
}
|
|
8907
|
-
copy(data) {
|
|
8918
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
8908
8919
|
const sheetId = data.sheetId;
|
|
8909
8920
|
const { clippedZones, rowsIndexes, columnsIndexes } = data;
|
|
8910
8921
|
const clippedCells = [];
|
|
@@ -8917,7 +8928,7 @@
|
|
|
8917
8928
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
8918
8929
|
const pivotId = this.getters.getPivotIdFromPosition(position);
|
|
8919
8930
|
const spreader = this.getters.getArrayFormulaSpreadingOn(position);
|
|
8920
|
-
if (pivotId && spreader) {
|
|
8931
|
+
if (mode !== "shiftCells" && pivotId && spreader) {
|
|
8921
8932
|
const pivotZone = this.getters.getSpreadZone(spreader);
|
|
8922
8933
|
if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
|
|
8923
8934
|
pivotZone &&
|
|
@@ -8935,7 +8946,7 @@
|
|
|
8935
8946
|
};
|
|
8936
8947
|
}
|
|
8937
8948
|
}
|
|
8938
|
-
else {
|
|
8949
|
+
else if (mode !== "shiftCells") {
|
|
8939
8950
|
if (spreader && !deepEquals(spreader, position)) {
|
|
8940
8951
|
const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
|
|
8941
8952
|
const content = isSpreaderCopied
|
|
@@ -9633,7 +9644,7 @@
|
|
|
9633
9644
|
}
|
|
9634
9645
|
|
|
9635
9646
|
class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
9636
|
-
copy(data, isCutOperation) {
|
|
9647
|
+
copy(data, isCutOperation, mode = "copyPaste") {
|
|
9637
9648
|
const sheetId = data.sheetId;
|
|
9638
9649
|
const { rowsIndexes, columnsIndexes, zones } = data;
|
|
9639
9650
|
const copiedTablesIds = new Set();
|
|
@@ -9671,11 +9682,13 @@
|
|
|
9671
9682
|
type: coreTable.type,
|
|
9672
9683
|
};
|
|
9673
9684
|
}
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9685
|
+
if (mode !== "shiftCells") {
|
|
9686
|
+
tableCellsInRow.push({
|
|
9687
|
+
table: copiedTable,
|
|
9688
|
+
style: this.getTableStyleToCopy(position),
|
|
9689
|
+
isWholeTableCopied: copiedTablesIds.has(table.id),
|
|
9690
|
+
});
|
|
9691
|
+
}
|
|
9679
9692
|
}
|
|
9680
9693
|
}
|
|
9681
9694
|
return {
|
|
@@ -15202,8 +15215,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
15202
15215
|
}
|
|
15203
15216
|
|
|
15204
15217
|
function sortMatrix(matrix, locale, ...criteria) {
|
|
15205
|
-
for (
|
|
15206
|
-
|
|
15218
|
+
for (let i = 0; i < criteria.length; i++) {
|
|
15219
|
+
const param = i % 2 === 0 ? "sort_column" : "is_ascending";
|
|
15220
|
+
assert(criteria[i] !== undefined, _t("Value for parameter %s is missing in [[FUNCTION_NAME]].", param));
|
|
15207
15221
|
}
|
|
15208
15222
|
const sortingOrders = [];
|
|
15209
15223
|
const sortColumns = [];
|
|
@@ -37513,7 +37527,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37513
37527
|
];
|
|
37514
37528
|
const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
|
|
37515
37529
|
const SUPPORTED_FONTS = ["Arial"];
|
|
37516
|
-
const SUPPORTED_FILL_PATTERNS = ["solid"];
|
|
37530
|
+
const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
|
|
37517
37531
|
const SUPPORTED_CF_TYPES = [
|
|
37518
37532
|
"expression",
|
|
37519
37533
|
"cellIs",
|
|
@@ -37713,7 +37727,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37713
37727
|
};
|
|
37714
37728
|
/** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
|
|
37715
37729
|
const XLSX_FORMATS_CONVERSION_MAP = {
|
|
37716
|
-
0: "",
|
|
37730
|
+
0: "General",
|
|
37717
37731
|
1: "0",
|
|
37718
37732
|
2: "0.00",
|
|
37719
37733
|
3: "#,#00",
|
|
@@ -38039,11 +38053,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
38039
38053
|
* Excel format are defined in openXML §18.8.31
|
|
38040
38054
|
*/
|
|
38041
38055
|
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
38042
|
-
if (numFmtId === 0) {
|
|
38043
|
-
return undefined;
|
|
38044
|
-
}
|
|
38045
38056
|
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
38046
38057
|
const format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
|
|
38058
|
+
if (format === "General") {
|
|
38059
|
+
return undefined;
|
|
38060
|
+
}
|
|
38047
38061
|
if (format) {
|
|
38048
38062
|
try {
|
|
38049
38063
|
let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
@@ -40621,10 +40635,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40621
40635
|
});
|
|
40622
40636
|
}
|
|
40623
40637
|
extractRows(worksheet) {
|
|
40638
|
+
const spilledCells = new Set();
|
|
40624
40639
|
return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
|
|
40625
40640
|
return {
|
|
40626
40641
|
index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
|
|
40627
|
-
cells: this.extractCells(rowElement),
|
|
40642
|
+
cells: this.extractCells(rowElement, spilledCells),
|
|
40628
40643
|
height: this.extractAttr(rowElement, "ht")?.asNum(),
|
|
40629
40644
|
customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
|
|
40630
40645
|
hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
|
|
@@ -40634,14 +40649,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40634
40649
|
};
|
|
40635
40650
|
});
|
|
40636
40651
|
}
|
|
40637
|
-
extractCells(row) {
|
|
40652
|
+
extractCells(row, spilledCells) {
|
|
40638
40653
|
return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
|
|
40654
|
+
const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
|
|
40655
|
+
const formula = this.extractCellFormula(cellElement);
|
|
40656
|
+
if (formula?.ref && formula.sharedIndex === undefined) {
|
|
40657
|
+
const zone = toZone(formula.ref);
|
|
40658
|
+
for (const { col, row } of positions(zone)) {
|
|
40659
|
+
const followerXc = toXC(col, row);
|
|
40660
|
+
if (followerXc !== xc) {
|
|
40661
|
+
spilledCells.add(followerXc);
|
|
40662
|
+
}
|
|
40663
|
+
}
|
|
40664
|
+
}
|
|
40665
|
+
const isSpilled = spilledCells.has(xc);
|
|
40639
40666
|
return {
|
|
40640
|
-
xc
|
|
40667
|
+
xc,
|
|
40641
40668
|
styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
|
|
40642
40669
|
type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
|
|
40643
|
-
value: this.extractChildTextContent(cellElement, "v"),
|
|
40644
|
-
formula:
|
|
40670
|
+
value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
|
|
40671
|
+
formula: isSpilled ? undefined : formula,
|
|
40645
40672
|
};
|
|
40646
40673
|
});
|
|
40647
40674
|
}
|
|
@@ -40649,11 +40676,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40649
40676
|
const formulaElement = this.querySelector(cellElement, "f");
|
|
40650
40677
|
if (!formulaElement)
|
|
40651
40678
|
return undefined;
|
|
40652
|
-
|
|
40653
|
-
|
|
40654
|
-
|
|
40655
|
-
|
|
40656
|
-
|
|
40679
|
+
const content = this.extractTextContent(formulaElement);
|
|
40680
|
+
const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
|
|
40681
|
+
const ref = this.extractAttr(formulaElement, "ref")?.asString();
|
|
40682
|
+
// This is the case of spilled cells of array formulas where <f> is empty
|
|
40683
|
+
if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
|
|
40684
|
+
return undefined;
|
|
40685
|
+
}
|
|
40686
|
+
return { content, sharedIndex, ref };
|
|
40657
40687
|
}
|
|
40658
40688
|
extractHyperLinks(worksheet) {
|
|
40659
40689
|
return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
|
|
@@ -54473,12 +54503,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54473
54503
|
addCalculatedMeasure() {
|
|
54474
54504
|
const { measures } = this.props.definition;
|
|
54475
54505
|
const measureName = this.env.model.getters.generateNewCalculatedMeasureName(measures);
|
|
54506
|
+
const aggregator = "sum";
|
|
54476
54507
|
this.props.onDimensionsUpdated({
|
|
54477
54508
|
measures: measures.concat([
|
|
54478
54509
|
{
|
|
54479
|
-
id: this.getMeasureId(measureName),
|
|
54510
|
+
id: this.getMeasureId(measureName, aggregator),
|
|
54480
54511
|
fieldName: measureName,
|
|
54481
|
-
aggregator
|
|
54512
|
+
aggregator,
|
|
54482
54513
|
computedBy: {
|
|
54483
54514
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
54484
54515
|
formula: "=0",
|
|
@@ -67944,7 +67975,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67944
67975
|
return { value: 0 };
|
|
67945
67976
|
}
|
|
67946
67977
|
const { columns, rows } = super.definition;
|
|
67947
|
-
if (columns.length + rows.length !== domain.length) {
|
|
67978
|
+
if (measure.aggregator && columns.length + rows.length !== domain.length) {
|
|
67948
67979
|
const values = this.getValuesToAggregate(measure, domain);
|
|
67949
67980
|
const aggregator = AGGREGATORS_FN[measure.aggregator];
|
|
67950
67981
|
if (!aggregator) {
|
|
@@ -67963,11 +67994,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67963
67994
|
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
|
|
67964
67995
|
const { colDomain } = domainToColRowDomain(this, domain);
|
|
67965
67996
|
const symbolIndex = colDomain.findIndex((node) => node.field === symbolName);
|
|
67997
|
+
if (symbolIndex === -1) {
|
|
67998
|
+
return new NotAvailableError();
|
|
67999
|
+
}
|
|
67966
68000
|
return this.getPivotHeaderValueAndFormat(colDomain.slice(0, symbolIndex + 1));
|
|
67967
68001
|
}
|
|
67968
68002
|
if (rows.find((row) => row.nameWithGranularity === symbolName)) {
|
|
67969
68003
|
const { rowDomain } = domainToColRowDomain(this, domain);
|
|
67970
68004
|
const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
|
|
68005
|
+
if (symbolIndex === -1) {
|
|
68006
|
+
return new NotAvailableError();
|
|
68007
|
+
}
|
|
67971
68008
|
return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
|
|
67972
68009
|
}
|
|
67973
68010
|
return this.getPivotCellValueAndFormat(symbolName, domain);
|
|
@@ -70991,7 +71028,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
70991
71028
|
bottom: rowIndex,
|
|
70992
71029
|
}));
|
|
70993
71030
|
const handler = new CellClipboardHandler(this.getters, this.dispatch);
|
|
70994
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep));
|
|
71031
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep), false);
|
|
70995
71032
|
if (!data) {
|
|
70996
71033
|
return;
|
|
70997
71034
|
}
|
|
@@ -73076,12 +73113,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
73076
73113
|
}
|
|
73077
73114
|
case "INSERT_CELL": {
|
|
73078
73115
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
73079
|
-
const copiedData = this.copy(cut);
|
|
73116
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73080
73117
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
73081
73118
|
}
|
|
73082
73119
|
case "DELETE_CELL": {
|
|
73083
73120
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
73084
|
-
const copiedData = this.copy(cut);
|
|
73121
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73085
73122
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
73086
73123
|
}
|
|
73087
73124
|
}
|
|
@@ -73192,13 +73229,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
73192
73229
|
});
|
|
73193
73230
|
break;
|
|
73194
73231
|
}
|
|
73195
|
-
const copiedData = this.copy(cut);
|
|
73232
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73196
73233
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
73197
73234
|
break;
|
|
73198
73235
|
}
|
|
73199
73236
|
case "INSERT_CELL": {
|
|
73200
73237
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
73201
|
-
const copiedData = this.copy(cut);
|
|
73238
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
73202
73239
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
73203
73240
|
break;
|
|
73204
73241
|
}
|
|
@@ -73313,11 +73350,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
73313
73350
|
}
|
|
73314
73351
|
return false;
|
|
73315
73352
|
}
|
|
73316
|
-
copy(zones) {
|
|
73353
|
+
copy(zones, mode = "copyPaste") {
|
|
73317
73354
|
const copiedData = {};
|
|
73318
73355
|
const clipboardData = this.getClipboardData(zones);
|
|
73319
73356
|
for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
|
|
73320
|
-
const data = handler.copy(clipboardData, this._isCutOperation);
|
|
73357
|
+
const data = handler.copy(clipboardData, this._isCutOperation, mode);
|
|
73321
73358
|
copiedData[handlerName] = data;
|
|
73322
73359
|
const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
|
|
73323
73360
|
for (const key of minimalKeys) {
|
|
@@ -74304,13 +74341,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74304
74341
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
74305
74342
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
74306
74343
|
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74307
|
-
const originalSize =
|
|
74308
|
-
|
|
74309
|
-
|
|
74310
|
-
|
|
74311
|
-
const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
|
|
74312
|
-
return [element, isDefaultCol ? undefined : size];
|
|
74313
|
-
}));
|
|
74344
|
+
const originalSize = {};
|
|
74345
|
+
for (const element of toRemove) {
|
|
74346
|
+
originalSize[element] = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
|
|
74347
|
+
}
|
|
74314
74348
|
const target = [
|
|
74315
74349
|
{
|
|
74316
74350
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -74331,7 +74365,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74331
74365
|
];
|
|
74332
74366
|
for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
|
|
74333
74367
|
const handler = new Handler(this.getters, this.dispatch);
|
|
74334
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, target));
|
|
74368
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, target), false, "shiftCells");
|
|
74335
74369
|
if (!data) {
|
|
74336
74370
|
continue;
|
|
74337
74371
|
}
|
|
@@ -74346,11 +74380,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74346
74380
|
for (const element of toRemove) {
|
|
74347
74381
|
const size = originalSize[element];
|
|
74348
74382
|
const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
|
|
74349
|
-
if (size
|
|
74383
|
+
if (size !== currentSize) {
|
|
74350
74384
|
resizingGroups[size] ??= [];
|
|
74351
74385
|
resizingGroups[size].push(currentIndex);
|
|
74352
|
-
currentIndex += 1;
|
|
74353
74386
|
}
|
|
74387
|
+
currentIndex += 1;
|
|
74354
74388
|
}
|
|
74355
74389
|
for (const size in resizingGroups) {
|
|
74356
74390
|
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
@@ -84071,7 +84105,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
84071
84105
|
handlers = [];
|
|
84072
84106
|
uiHandlers = [];
|
|
84073
84107
|
coreHandlers = [];
|
|
84074
|
-
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport =
|
|
84108
|
+
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = false) {
|
|
84075
84109
|
const start = performance.now();
|
|
84076
84110
|
console.debug("##### Model creation #####");
|
|
84077
84111
|
super();
|
|
@@ -84821,9 +84855,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
84821
84855
|
exports.tokenize = tokenize;
|
|
84822
84856
|
|
|
84823
84857
|
|
|
84824
|
-
__info__.version = "18.4.
|
|
84825
|
-
__info__.date = "2025-09-
|
|
84826
|
-
__info__.hash = "
|
|
84858
|
+
__info__.version = "18.4.11";
|
|
84859
|
+
__info__.date = "2025-09-19T07:25:39.033Z";
|
|
84860
|
+
__info__.hash = "c7e71ac";
|
|
84827
84861
|
|
|
84828
84862
|
|
|
84829
84863
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|