@microsoft/connected-workbooks 3.2.2-beta → 3.3.2-beta
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/README.md +372 -132
- package/dist/src/utils/constants.js +20 -2
- package/dist/src/utils/documentUtils.js +18 -4
- package/dist/src/utils/tableUtils.js +74 -29
- package/dist/src/utils/xmlInnerPartsUtils.js +156 -14
- package/dist/src/utils/xmlPartsUtils.js +61 -17
- package/dist/src/workbookTemplate.js +3 -1
- package/dist/tests/arrayUtils.test.js +14 -13
- package/dist/tests/documentUtils.test.js +40 -34
- package/dist/tests/gridUtils.test.js +59 -13
- package/dist/tests/htmlUtils.test.js +16 -15
- package/dist/tests/mashupDocumentParser.test.js +7 -6
- package/dist/tests/mocks/xmlMocks.js +3 -1
- package/dist/tests/tableUtils.test.js +44 -37
- package/dist/tests/workbookQueryTemplate.test.js +89 -17
- package/dist/tests/workbookTableTemplate.test.js +12 -11
- package/dist/tests/xmlInnerPartsUtils.test.js +159 -18
- package/dist/types.d.ts +7 -1
- package/dist/utils/constants.js +20 -2
- package/dist/utils/documentUtils.js +18 -4
- package/dist/utils/tableUtils.js +74 -29
- package/dist/utils/xmlInnerPartsUtils.js +156 -14
- package/dist/utils/xmlPartsUtils.js +61 -17
- package/dist/workbookManager.js +12 -12
- package/dist/workbookTemplate.js +3 -1
- package/package.json +8 -2
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright (c) Microsoft Corporation.
|
|
3
3
|
// Licensed under the MIT license.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
6
|
-
exports.OFU = exports.headers = exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = void 0;
|
|
5
|
+
exports.textResultType = exports.application = exports.uint8ArrayType = exports.blobFileType = exports.relationshipErr = exports.columnIndexOutOfRangeErr = exports.xlRelsNotFoundErr = exports.relsNotFoundErr = exports.arrayIsntMxNErr = exports.unexpectedErr = exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = exports.InvalidColumnNameErr = exports.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameInvalidCharsErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.tableReferenceNotFoundErr = exports.tableNotFoundErr = exports.queryTableNotFoundErr = exports.templateWithInitialDataErr = exports.formulaSectionNotFoundErr = exports.queryConnectionNotFoundErr = exports.queryAndPivotTableNotFoundErr = exports.queryNameNotFoundErr = exports.emptyQueryMashupErr = exports.base64NotFoundErr = exports.sheetsNotFoundErr = exports.WorkbookNotFoundERR = exports.connectionsNotFoundErr = exports.sharedStringsNotFoundErr = exports.docPropsAppXmlPath = exports.labelInfoXmlPath = exports.workbookRelsXmlPath = exports.docPropsRootElement = exports.docMetadataXmlPath = exports.relsXmlPath = exports.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.tablesFolderPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
|
|
6
|
+
exports.OFU = exports.headers = exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = exports.maxQueryLength = exports.divider = exports.section1PathPrefix = exports.emptyValue = exports.falseValue = exports.trueValue = exports.pivotCachesPathPrefix = exports.xmlTextResultType = void 0;
|
|
7
7
|
exports.connectionsXmlPath = "xl/connections.xml";
|
|
8
8
|
exports.sharedStringsXmlPath = "xl/sharedStrings.xml";
|
|
9
9
|
exports.sheetsXmlPath = "xl/worksheets/sheet1.xml";
|
|
@@ -11,14 +11,19 @@ exports.tableXmlPath = "xl/tables/table1.xml";
|
|
|
11
11
|
exports.queryTableXmlPath = "xl/queryTables/queryTable1.xml";
|
|
12
12
|
exports.workbookXmlPath = "xl/workbook.xml";
|
|
13
13
|
exports.queryTablesPath = "xl/queryTables/";
|
|
14
|
+
exports.tablesFolderPath = "xl/tables/";
|
|
14
15
|
exports.pivotCachesPath = "xl/pivotCache/";
|
|
15
16
|
exports.section1mPath = "Formulas/Section1.m";
|
|
16
17
|
exports.docPropsCoreXmlPath = "docProps/core.xml";
|
|
17
18
|
exports.relsXmlPath = "_rels/.rels";
|
|
18
19
|
exports.docMetadataXmlPath = "docMetadata";
|
|
19
20
|
exports.docPropsRootElement = "cp:coreProperties";
|
|
21
|
+
exports.workbookRelsXmlPath = "xl/_rels/workbook.xml.rels";
|
|
22
|
+
exports.labelInfoXmlPath = "docMetadata/LabelInfo.xml";
|
|
23
|
+
exports.docPropsAppXmlPath = "docProps/app.xml";
|
|
20
24
|
exports.sharedStringsNotFoundErr = "SharedStrings were not found in template";
|
|
21
25
|
exports.connectionsNotFoundErr = "Connections were not found in template";
|
|
26
|
+
exports.WorkbookNotFoundERR = "workbook was not found in template";
|
|
22
27
|
exports.sheetsNotFoundErr = "Sheets were not found in template";
|
|
23
28
|
exports.base64NotFoundErr = "Base64 was not found in template";
|
|
24
29
|
exports.emptyQueryMashupErr = "Query mashup is empty";
|
|
@@ -29,6 +34,7 @@ exports.formulaSectionNotFoundErr = "Formula section wasn't found in template";
|
|
|
29
34
|
exports.templateWithInitialDataErr = "Cannot use a template file with initial data";
|
|
30
35
|
exports.queryTableNotFoundErr = "Query table wasn't found in template";
|
|
31
36
|
exports.tableNotFoundErr = "Table wasn't found in template";
|
|
37
|
+
exports.tableReferenceNotFoundErr = "Reference not found in the table XML.";
|
|
32
38
|
exports.invalidValueInColumnErr = "Invalid cell value in column";
|
|
33
39
|
exports.headerNotFoundErr = "Invalid JSON file, header is missing";
|
|
34
40
|
exports.invalidDataTypeErr = "Invalid JSON file, invalid data type";
|
|
@@ -41,7 +47,9 @@ exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = "Headers can
|
|
|
41
47
|
exports.unexpectedErr = "Unexpected error";
|
|
42
48
|
exports.arrayIsntMxNErr = "Array isn't MxN";
|
|
43
49
|
exports.relsNotFoundErr = ".rels were not found in template";
|
|
50
|
+
exports.xlRelsNotFoundErr = "workbook.xml.rels were not found xl";
|
|
44
51
|
exports.columnIndexOutOfRangeErr = "Column index out of range";
|
|
52
|
+
exports.relationshipErr = "Relationship not found";
|
|
45
53
|
exports.blobFileType = "blob";
|
|
46
54
|
exports.uint8ArrayType = "uint8array";
|
|
47
55
|
exports.application = "application/xlsx";
|
|
@@ -85,6 +93,9 @@ exports.element = {
|
|
|
85
93
|
dimension: "dimension",
|
|
86
94
|
selection: "selection",
|
|
87
95
|
kindCell: "c",
|
|
96
|
+
sheet: "sheet",
|
|
97
|
+
relationships: "Relationships",
|
|
98
|
+
relationship: "Relationship"
|
|
88
99
|
};
|
|
89
100
|
exports.elementAttributes = {
|
|
90
101
|
connection: "connection",
|
|
@@ -98,6 +109,11 @@ exports.elementAttributes = {
|
|
|
98
109
|
name: "name",
|
|
99
110
|
description: "description",
|
|
100
111
|
id: "id",
|
|
112
|
+
Id: "Id",
|
|
113
|
+
relationId: "r:id",
|
|
114
|
+
relationId1: "RId1",
|
|
115
|
+
relationId2: "RId2",
|
|
116
|
+
relationId3: "RId3",
|
|
101
117
|
type: "Type",
|
|
102
118
|
value: "Value",
|
|
103
119
|
relationshipInfo: "RelationshipInfoContainer",
|
|
@@ -117,6 +133,7 @@ exports.elementAttributes = {
|
|
|
117
133
|
x14acDyDescent: "x14ac:dyDescent",
|
|
118
134
|
xr3uid: "xr3:uid",
|
|
119
135
|
space: "xml:space",
|
|
136
|
+
target: "Target",
|
|
120
137
|
};
|
|
121
138
|
exports.dataTypeKind = {
|
|
122
139
|
string: "str",
|
|
@@ -134,6 +151,7 @@ exports.defaults = {
|
|
|
134
151
|
queryName: "Query1",
|
|
135
152
|
sheetName: "Sheet1",
|
|
136
153
|
columnName: "Column",
|
|
154
|
+
tableName: "Table1",
|
|
137
155
|
};
|
|
138
156
|
exports.URLS = {
|
|
139
157
|
PQ: [
|
|
@@ -93,13 +93,27 @@ var convertToExcelColumn = function (index) {
|
|
|
93
93
|
var base = 26; // number of letters in the alphabet
|
|
94
94
|
while (index >= 0) {
|
|
95
95
|
var remainder = index % base;
|
|
96
|
-
columnStr = String.fromCharCode(remainder +
|
|
96
|
+
columnStr = String.fromCharCode(remainder + 'A'.charCodeAt(0)) + columnStr;
|
|
97
97
|
index = Math.floor(index / base) - 1;
|
|
98
98
|
}
|
|
99
99
|
return columnStr;
|
|
100
100
|
};
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Parse an Excel range (e.g. "B2:D10") and return its starting row and column indices.
|
|
103
|
+
* @param cellRangeRef - Range reference string.
|
|
104
|
+
* @returns Object with numeric row and column.
|
|
105
|
+
*/
|
|
106
|
+
var GetStartPosition = function (cellRangeRef) {
|
|
107
|
+
var match = cellRangeRef.toUpperCase().match(/^([A-Z]+)(\d+)/);
|
|
108
|
+
if (!match) {
|
|
109
|
+
return { row: 0, column: 0 };
|
|
110
|
+
}
|
|
111
|
+
var colLetters = match[1], rowStr = match[2];
|
|
112
|
+
var row = parseInt(rowStr, 10);
|
|
113
|
+
var column = colLetters
|
|
114
|
+
.split("")
|
|
115
|
+
.reduce(function (acc, char) { return acc * 26 + (char.charCodeAt(0) - "A".charCodeAt(0) + 1); }, 0);
|
|
116
|
+
return { row: row, column: column };
|
|
103
117
|
};
|
|
104
118
|
var createCellElement = function (doc, colIndex, rowIndex, data) {
|
|
105
119
|
var cell = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.kindCell);
|
|
@@ -146,8 +160,8 @@ exports.default = {
|
|
|
146
160
|
getCellReferenceRelative: getCellReferenceRelative,
|
|
147
161
|
getCellReferenceAbsolute: getCellReferenceAbsolute,
|
|
148
162
|
createCell: createCellElement,
|
|
149
|
-
getTableReference: getTableReference,
|
|
150
163
|
updateCellData: updateCellData,
|
|
151
164
|
resolveType: resolveType,
|
|
152
165
|
convertToExcelColumn: convertToExcelColumn,
|
|
166
|
+
GetStartPosition: GetStartPosition,
|
|
153
167
|
};
|
|
@@ -45,7 +45,17 @@ var constants_1 = require("./constants");
|
|
|
45
45
|
var documentUtils_1 = __importDefault(require("./documentUtils"));
|
|
46
46
|
var uuid_1 = require("uuid");
|
|
47
47
|
var xmldom_qsa_1 = require("xmldom-qsa");
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Update initial data for a table, its sheet, query table, and defined name if provided.
|
|
50
|
+
* @param zip - The JSZip instance containing workbook parts.
|
|
51
|
+
* @param cellRangeRef - Cell range reference (e.g. "A1:C5").
|
|
52
|
+
* @param sheetPath - Path to the sheet XML within the zip.
|
|
53
|
+
* @param tablePath - Path to the table XML within the zip.
|
|
54
|
+
* @param tableName - Name of the table.
|
|
55
|
+
* @param tableData - Optional TableData containing headers and rows.
|
|
56
|
+
* @param updateQueryTable - Whether to update the associated queryTable part.
|
|
57
|
+
*/
|
|
58
|
+
var updateTableInitialDataIfNeeded = function (zip, cellRangeRef, sheetPath, tablePath, sheetName, tableData, updateQueryTable) { return __awaiter(void 0, void 0, void 0, function () {
|
|
49
59
|
var sheetsXmlString, newSheet, queryTableXmlString, newQueryTable, workbookXmlString, newWorkbook, tableXmlString, newTable;
|
|
50
60
|
var _a, _b, _c, _d;
|
|
51
61
|
return __generator(this, function (_e) {
|
|
@@ -54,14 +64,14 @@ var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable)
|
|
|
54
64
|
if (!tableData) {
|
|
55
65
|
return [2 /*return*/];
|
|
56
66
|
}
|
|
57
|
-
return [4 /*yield*/, ((_a = zip.file(
|
|
67
|
+
return [4 /*yield*/, ((_a = zip.file(sheetPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
|
|
58
68
|
case 1:
|
|
59
69
|
sheetsXmlString = _e.sent();
|
|
60
70
|
if (sheetsXmlString === undefined) {
|
|
61
71
|
throw new Error(constants_1.sheetsNotFoundErr);
|
|
62
72
|
}
|
|
63
|
-
newSheet = updateSheetsInitialData(sheetsXmlString, tableData);
|
|
64
|
-
zip.file(
|
|
73
|
+
newSheet = updateSheetsInitialData(sheetsXmlString, tableData, cellRangeRef);
|
|
74
|
+
zip.file(sheetPath, newSheet);
|
|
65
75
|
if (!updateQueryTable) return [3 /*break*/, 5];
|
|
66
76
|
return [4 /*yield*/, ((_b = zip.file(constants_1.queryTableXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType))];
|
|
67
77
|
case 2:
|
|
@@ -79,22 +89,30 @@ var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable)
|
|
|
79
89
|
if (workbookXmlString === undefined) {
|
|
80
90
|
throw new Error(constants_1.sheetsNotFoundErr);
|
|
81
91
|
}
|
|
82
|
-
newWorkbook = updateWorkbookInitialData(workbookXmlString,
|
|
92
|
+
newWorkbook = updateWorkbookInitialData(workbookXmlString, sheetName + GenerateReferenceFromString(cellRangeRef));
|
|
83
93
|
zip.file(constants_1.workbookXmlPath, newWorkbook);
|
|
84
94
|
_e.label = 5;
|
|
85
|
-
case 5: return [4 /*yield*/, ((_d = zip.file(
|
|
95
|
+
case 5: return [4 /*yield*/, ((_d = zip.file(tablePath)) === null || _d === void 0 ? void 0 : _d.async(constants_1.textResultType))];
|
|
86
96
|
case 6:
|
|
87
97
|
tableXmlString = _e.sent();
|
|
88
98
|
if (tableXmlString === undefined) {
|
|
89
99
|
throw new Error(constants_1.tableNotFoundErr);
|
|
90
100
|
}
|
|
91
|
-
newTable = updateTablesInitialData(tableXmlString, tableData, updateQueryTable);
|
|
92
|
-
zip.file(
|
|
101
|
+
newTable = updateTablesInitialData(tableXmlString, tableData, cellRangeRef, updateQueryTable);
|
|
102
|
+
zip.file(tablePath, newTable);
|
|
93
103
|
return [2 /*return*/];
|
|
94
104
|
}
|
|
95
105
|
});
|
|
96
106
|
}); };
|
|
97
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Generate updated table XML string with new columns, reference, and filter range.
|
|
109
|
+
* @param tableXmlString - Original table XML.
|
|
110
|
+
* @param tableData - TableData containing column names.
|
|
111
|
+
* @param cellRangeRef - Cell range reference.
|
|
112
|
+
* @param updateQueryTable - Whether to include queryTable attributes.
|
|
113
|
+
* @returns Serialized XML string of the updated table.
|
|
114
|
+
*/
|
|
115
|
+
var updateTablesInitialData = function (tableXmlString, tableData, cellRangeRef, updateQueryTable) {
|
|
98
116
|
if (updateQueryTable === void 0) { updateQueryTable = false; }
|
|
99
117
|
var parser = new xmldom_qsa_1.DOMParser();
|
|
100
118
|
var serializer = new xmldom_qsa_1.XMLSerializer();
|
|
@@ -115,19 +133,24 @@ var updateTablesInitialData = function (tableXmlString, tableData, updateQueryTa
|
|
|
115
133
|
tableColumns.setAttribute(constants_1.elementAttributes.count, tableData.columnNames.length.toString());
|
|
116
134
|
tableDoc
|
|
117
135
|
.getElementsByTagName(constants_1.element.table)[0]
|
|
118
|
-
.setAttribute(constants_1.elementAttributes.reference,
|
|
136
|
+
.setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
|
|
119
137
|
tableDoc
|
|
120
138
|
.getElementsByTagName(constants_1.element.autoFilter)[0]
|
|
121
|
-
.setAttribute(constants_1.elementAttributes.reference,
|
|
139
|
+
.setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
|
|
122
140
|
return serializer.serializeToString(tableDoc);
|
|
123
141
|
};
|
|
124
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Update the definedName element in workbook XML to a custom name.
|
|
144
|
+
* @param workbookXmlString - Original workbook XML string.
|
|
145
|
+
* @param customDefinedName - New defined name text content (e.g. "!$A$1:$C$5").
|
|
146
|
+
* @returns Serialized XML string of the updated workbook.
|
|
147
|
+
*/
|
|
148
|
+
var updateWorkbookInitialData = function (workbookXmlString, customDefinedName) {
|
|
125
149
|
var newParser = new xmldom_qsa_1.DOMParser();
|
|
126
150
|
var newSerializer = new xmldom_qsa_1.XMLSerializer();
|
|
127
151
|
var workbookDoc = newParser.parseFromString(workbookXmlString, constants_1.xmlTextResultType);
|
|
128
152
|
var definedName = workbookDoc.getElementsByTagName(constants_1.element.definedName)[0];
|
|
129
|
-
definedName.textContent =
|
|
130
|
-
constants_1.defaults.sheetName + "!$A$1:".concat(documentUtils_1.default.getCellReferenceAbsolute(tableData.columnNames.length - 1, tableData.rows.length + 1));
|
|
153
|
+
definedName.textContent = customDefinedName;
|
|
131
154
|
return newSerializer.serializeToString(workbookDoc);
|
|
132
155
|
};
|
|
133
156
|
var updateQueryTablesInitialData = function (queryTableXmlString, tableData) {
|
|
@@ -147,42 +170,64 @@ var updateQueryTablesInitialData = function (queryTableXmlString, tableData) {
|
|
|
147
170
|
queryTableDoc.getElementsByTagName(constants_1.element.queryTableRefresh)[0].setAttribute(constants_1.elementAttributes.nextId, (tableData.columnNames.length + 1).toString());
|
|
148
171
|
return serializer.serializeToString(queryTableDoc);
|
|
149
172
|
};
|
|
150
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Update sheet XML with header row and data rows based on TableData.
|
|
175
|
+
* @param sheetsXmlString - Original sheet XML string.
|
|
176
|
+
* @param tableData - TableData containing headers and rows.
|
|
177
|
+
* @param cellRangeRef - Cell range reference.
|
|
178
|
+
* @returns Serialized XML string of the updated sheet.
|
|
179
|
+
*/
|
|
180
|
+
var updateSheetsInitialData = function (sheetsXmlString, tableData, cellRangeRef) {
|
|
181
|
+
var _a = documentUtils_1.default.GetStartPosition(cellRangeRef), row = _a.row, column = _a.column;
|
|
151
182
|
var parser = new xmldom_qsa_1.DOMParser();
|
|
152
183
|
var serializer = new xmldom_qsa_1.XMLSerializer();
|
|
153
184
|
var sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
|
|
154
185
|
var sheetData = sheetsDoc.getElementsByTagName(constants_1.element.sheetData)[0];
|
|
155
186
|
sheetData.textContent = "";
|
|
156
|
-
var rowIndex = 0;
|
|
157
187
|
var columnRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
|
|
158
|
-
columnRow.setAttribute(constants_1.elementAttributes.row,
|
|
159
|
-
columnRow.setAttribute(constants_1.elementAttributes.spans, "
|
|
188
|
+
columnRow.setAttribute(constants_1.elementAttributes.row, row.toString());
|
|
189
|
+
columnRow.setAttribute(constants_1.elementAttributes.spans, column + ":" + (column + tableData.columnNames.length - 1));
|
|
160
190
|
columnRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
|
|
161
191
|
tableData.columnNames.forEach(function (col, colIndex) {
|
|
162
|
-
columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex,
|
|
192
|
+
columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex + column - 1, row - 1, col));
|
|
163
193
|
});
|
|
164
194
|
sheetData.appendChild(columnRow);
|
|
165
|
-
|
|
166
|
-
tableData.rows.forEach(function (
|
|
195
|
+
row++;
|
|
196
|
+
tableData.rows.forEach(function (_row) {
|
|
167
197
|
var newRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
|
|
168
|
-
newRow.setAttribute(constants_1.elementAttributes.row,
|
|
169
|
-
newRow.setAttribute(constants_1.elementAttributes.spans, "
|
|
198
|
+
newRow.setAttribute(constants_1.elementAttributes.row, row.toString());
|
|
199
|
+
newRow.setAttribute(constants_1.elementAttributes.spans, column + ":" + (column + tableData.columnNames.length - 1));
|
|
170
200
|
newRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
|
|
171
|
-
|
|
172
|
-
newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex,
|
|
201
|
+
_row.forEach(function (cellContent, colIndex) {
|
|
202
|
+
newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex + column - 1, row - 1, cellContent));
|
|
173
203
|
});
|
|
174
204
|
sheetData.appendChild(newRow);
|
|
175
|
-
|
|
205
|
+
row++;
|
|
176
206
|
});
|
|
177
|
-
|
|
178
|
-
sheetsDoc.getElementsByTagName(constants_1.element.
|
|
179
|
-
sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, reference);
|
|
207
|
+
sheetsDoc.getElementsByTagName(constants_1.element.dimension)[0].setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
|
|
208
|
+
sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, cellRangeRef);
|
|
180
209
|
return serializer.serializeToString(sheetsDoc);
|
|
181
210
|
};
|
|
211
|
+
/**
|
|
212
|
+
* Add Excel-style dollar signs and a '!' prefix to a cell range.
|
|
213
|
+
* Converts "A1:B2" into "!$A$1:$B$2".
|
|
214
|
+
* @param cellRangeRef - Range reference string without dollar signs.
|
|
215
|
+
* @returns Range with dollar signs and prefix.
|
|
216
|
+
*/
|
|
217
|
+
var GenerateReferenceFromString = function (cellRangeRef) {
|
|
218
|
+
return "!" + cellRangeRef.split(":").map(function (part) {
|
|
219
|
+
var match = part.match(/^([A-Za-z]+)(\d+)$/);
|
|
220
|
+
if (match) {
|
|
221
|
+
var col = match[1], row = match[2];
|
|
222
|
+
return "$".concat(col.toUpperCase(), "$").concat(row);
|
|
223
|
+
}
|
|
224
|
+
}).join(":");
|
|
225
|
+
};
|
|
182
226
|
exports.default = {
|
|
183
227
|
updateTableInitialDataIfNeeded: updateTableInitialDataIfNeeded,
|
|
184
228
|
updateSheetsInitialData: updateSheetsInitialData,
|
|
185
229
|
updateWorkbookInitialData: updateWorkbookInitialData,
|
|
186
230
|
updateTablesInitialData: updateTablesInitialData,
|
|
187
231
|
updateQueryTablesInitialData: updateQueryTablesInitialData,
|
|
232
|
+
GenerateReferenceFromString: GenerateReferenceFromString,
|
|
188
233
|
};
|
|
@@ -76,33 +76,60 @@ var updateDocProps = function (zip, docProps) {
|
|
|
76
76
|
});
|
|
77
77
|
});
|
|
78
78
|
};
|
|
79
|
+
var removeLabelInfoRelationship = function (doc, relationships) {
|
|
80
|
+
// Find and remove LabelInfo.xml relationship
|
|
81
|
+
var relationshipElements = doc.getElementsByTagName(constants_1.element.relationship);
|
|
82
|
+
for (var i = 0; i < relationshipElements.length; i++) {
|
|
83
|
+
var rel = relationshipElements[i];
|
|
84
|
+
if (rel.getAttribute(constants_1.elementAttributes.target) === constants_1.labelInfoXmlPath) {
|
|
85
|
+
relationships.removeChild(rel);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var updateRelationshipIds = function (doc) {
|
|
91
|
+
// Update relationship IDs
|
|
92
|
+
var relationshipElements = doc.getElementsByTagName(constants_1.element.relationship);
|
|
93
|
+
for (var i = 0; i < relationshipElements.length; i++) {
|
|
94
|
+
var rel = relationshipElements[i];
|
|
95
|
+
var target = rel.getAttribute(constants_1.elementAttributes.target);
|
|
96
|
+
if (target === constants_1.workbookXmlPath) {
|
|
97
|
+
rel.setAttribute(constants_1.elementAttributes.Id, constants_1.elementAttributes.relationId1);
|
|
98
|
+
}
|
|
99
|
+
else if (target === constants_1.docPropsCoreXmlPath) {
|
|
100
|
+
rel.setAttribute(constants_1.elementAttributes.Id, constants_1.elementAttributes.relationId2);
|
|
101
|
+
}
|
|
102
|
+
else if (target === constants_1.docPropsAppXmlPath) {
|
|
103
|
+
rel.setAttribute(constants_1.elementAttributes.Id, constants_1.elementAttributes.relationId3);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
79
107
|
var clearLabelInfo = function (zip) { return __awaiter(void 0, void 0, void 0, function () {
|
|
80
|
-
var relsString, parser, doc,
|
|
81
|
-
var _a
|
|
82
|
-
return __generator(this, function (
|
|
83
|
-
switch (
|
|
108
|
+
var relsString, parser, doc, relationshipsList, relationships, serializer, newDoc;
|
|
109
|
+
var _a;
|
|
110
|
+
return __generator(this, function (_b) {
|
|
111
|
+
switch (_b.label) {
|
|
84
112
|
case 0:
|
|
85
113
|
// remove docMetadata folder that contains only LabelInfo.xml in template file.
|
|
86
114
|
zip.remove(constants_1.docMetadataXmlPath);
|
|
87
115
|
return [4 /*yield*/, ((_a = zip.file(constants_1.relsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
|
|
88
116
|
case 1:
|
|
89
|
-
relsString =
|
|
117
|
+
relsString = _b.sent();
|
|
90
118
|
if (relsString === undefined) {
|
|
91
119
|
throw new Error(constants_1.relsNotFoundErr);
|
|
92
120
|
}
|
|
93
121
|
parser = new xmldom_qsa_1.DOMParser();
|
|
94
122
|
doc = parser.parseFromString(relsString, constants_1.xmlTextResultType);
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
throw new Error(constants_1.
|
|
123
|
+
relationshipsList = doc.getElementsByTagName(constants_1.element.relationships);
|
|
124
|
+
if (!relationshipsList || relationshipsList.length === 0) {
|
|
125
|
+
throw new Error(constants_1.relationshipErr);
|
|
98
126
|
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
|
|
127
|
+
relationships = relationshipsList[0];
|
|
128
|
+
if (!relationships) {
|
|
129
|
+
throw new Error(constants_1.relationshipErr);
|
|
102
130
|
}
|
|
103
|
-
(
|
|
104
|
-
(
|
|
105
|
-
(_d = relationships.querySelector('Relationship[Target="docProps/app.xml"]')) === null || _d === void 0 ? void 0 : _d.setAttribute("Id", "rId3");
|
|
131
|
+
removeLabelInfoRelationship(doc, relationships);
|
|
132
|
+
updateRelationshipIds(doc);
|
|
106
133
|
serializer = new xmldom_qsa_1.XMLSerializer();
|
|
107
134
|
newDoc = serializer.serializeToString(doc);
|
|
108
135
|
zip.file(constants_1.relsXmlPath, newDoc);
|
|
@@ -277,6 +304,118 @@ var updatePivotTable = function (tableXmlString, connectionId, refreshOnOpen) {
|
|
|
277
304
|
}
|
|
278
305
|
return { isPivotTableUpdated: isPivotTableUpdated, newPivotTable: newPivotTable };
|
|
279
306
|
};
|
|
307
|
+
/**
|
|
308
|
+
* Retrieves the target path of a sheet from workbook relationships by its relationship ID.
|
|
309
|
+
*/
|
|
310
|
+
function getSheetPathFromXlRelId(zip, rId) {
|
|
311
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
312
|
+
var relsFile, relsString, relsDoc, relationships, target, i, el;
|
|
313
|
+
return __generator(this, function (_a) {
|
|
314
|
+
switch (_a.label) {
|
|
315
|
+
case 0:
|
|
316
|
+
relsFile = zip.file(constants_1.workbookRelsXmlPath);
|
|
317
|
+
if (!relsFile) {
|
|
318
|
+
throw new Error(constants_1.xlRelsNotFoundErr);
|
|
319
|
+
}
|
|
320
|
+
return [4 /*yield*/, relsFile.async(constants_1.textResultType)];
|
|
321
|
+
case 1:
|
|
322
|
+
relsString = _a.sent();
|
|
323
|
+
relsDoc = new xmldom_qsa_1.DOMParser().parseFromString(relsString, constants_1.xmlTextResultType);
|
|
324
|
+
relationships = relsDoc.getElementsByTagName("Relationship");
|
|
325
|
+
target = null;
|
|
326
|
+
for (i = 0; i < relationships.length; i++) {
|
|
327
|
+
el = relationships[i];
|
|
328
|
+
if (el && el.getAttribute && el.getAttribute("Id") === rId) {
|
|
329
|
+
target = el.getAttribute(constants_1.elementAttributes.target);
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (!target) {
|
|
334
|
+
throw new Error("Relationship not found or missing Target for Id: ".concat(rId));
|
|
335
|
+
}
|
|
336
|
+
return [2 /*return*/, target];
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
// get sheet name from workbook
|
|
342
|
+
var getSheetPathByNameFromZip = function (zip, sheetName) { return __awaiter(void 0, void 0, void 0, function () {
|
|
343
|
+
var workbookXmlString, parser, doc, sheetElements, i, rId;
|
|
344
|
+
var _a;
|
|
345
|
+
return __generator(this, function (_b) {
|
|
346
|
+
switch (_b.label) {
|
|
347
|
+
case 0: return [4 /*yield*/, ((_a = zip.file(constants_1.workbookXmlPath)) === null || _a === void 0 ? void 0 : _a.async("text"))];
|
|
348
|
+
case 1:
|
|
349
|
+
workbookXmlString = _b.sent();
|
|
350
|
+
if (!workbookXmlString) {
|
|
351
|
+
throw new Error(constants_1.WorkbookNotFoundERR);
|
|
352
|
+
}
|
|
353
|
+
parser = new xmldom_qsa_1.DOMParser();
|
|
354
|
+
doc = parser.parseFromString(workbookXmlString, constants_1.xmlTextResultType);
|
|
355
|
+
sheetElements = doc.getElementsByTagName(constants_1.element.sheet);
|
|
356
|
+
for (i = 0; i < sheetElements.length; i++) {
|
|
357
|
+
if (sheetElements[i].getAttribute(constants_1.elementAttributes.name) === sheetName) {
|
|
358
|
+
rId = sheetElements[i].getAttribute(constants_1.elementAttributes.relationId);
|
|
359
|
+
if (rId) {
|
|
360
|
+
return [2 /*return*/, getSheetPathFromXlRelId(zip, rId)];
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
throw new Error("Sheet with name ".concat(sheetName, " not found"));
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}); };
|
|
368
|
+
// get definedName
|
|
369
|
+
var getReferenceFromTable = function (zip, tablePath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
370
|
+
var tableXmlString, parser, doc, tableElements, reference;
|
|
371
|
+
var _a, _b;
|
|
372
|
+
return __generator(this, function (_c) {
|
|
373
|
+
switch (_c.label) {
|
|
374
|
+
case 0: return [4 /*yield*/, ((_a = zip.file(tablePath)) === null || _a === void 0 ? void 0 : _a.async("text"))];
|
|
375
|
+
case 1:
|
|
376
|
+
tableXmlString = _c.sent();
|
|
377
|
+
if (!tableXmlString) {
|
|
378
|
+
throw new Error(constants_1.WorkbookNotFoundERR);
|
|
379
|
+
}
|
|
380
|
+
parser = new xmldom_qsa_1.DOMParser();
|
|
381
|
+
doc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
|
|
382
|
+
tableElements = doc.getElementsByTagName(constants_1.element.table);
|
|
383
|
+
reference = (_b = tableElements[0]) === null || _b === void 0 ? void 0 : _b.getAttribute(constants_1.elementAttributes.reference);
|
|
384
|
+
if (!reference) {
|
|
385
|
+
throw new Error(constants_1.tableReferenceNotFoundErr);
|
|
386
|
+
}
|
|
387
|
+
return [2 /*return*/, reference.split(":")[0]]; // Return the start cell reference (e.g., "A1" from "A1:B10")
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}); };
|
|
391
|
+
var findTablePathFromZip = function (zip, targetTableName) { return __awaiter(void 0, void 0, void 0, function () {
|
|
392
|
+
var tablesFolder, tableFilePromises, tableFiles, parser, _i, tableFiles_1, _a, path, content, doc, tableElem;
|
|
393
|
+
return __generator(this, function (_b) {
|
|
394
|
+
switch (_b.label) {
|
|
395
|
+
case 0:
|
|
396
|
+
tablesFolder = zip.folder("xl/tables");
|
|
397
|
+
if (!tablesFolder)
|
|
398
|
+
return [2 /*return*/, ""];
|
|
399
|
+
tableFilePromises = [];
|
|
400
|
+
tablesFolder.forEach(function (relativePath, file) {
|
|
401
|
+
tableFilePromises.push(file.async(constants_1.textResultType).then(function (content) { return ({ path: relativePath, content: content }); }));
|
|
402
|
+
});
|
|
403
|
+
return [4 /*yield*/, Promise.all(tableFilePromises)];
|
|
404
|
+
case 1:
|
|
405
|
+
tableFiles = _b.sent();
|
|
406
|
+
parser = new xmldom_qsa_1.DOMParser();
|
|
407
|
+
for (_i = 0, tableFiles_1 = tableFiles; _i < tableFiles_1.length; _i++) {
|
|
408
|
+
_a = tableFiles_1[_i], path = _a.path, content = _a.content;
|
|
409
|
+
doc = parser.parseFromString(content, constants_1.xmlTextResultType);
|
|
410
|
+
tableElem = doc.getElementsByTagName(constants_1.element.table)[0];
|
|
411
|
+
if (tableElem && tableElem.getAttribute(constants_1.elementAttributes.name) === targetTableName) {
|
|
412
|
+
return [2 /*return*/, path];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
throw new Error(constants_1.tableNotFoundErr);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}); };
|
|
280
419
|
exports.default = {
|
|
281
420
|
updateDocProps: updateDocProps,
|
|
282
421
|
clearLabelInfo: clearLabelInfo,
|
|
@@ -286,4 +425,7 @@ exports.default = {
|
|
|
286
425
|
updatePivotTablesandQueryTables: updatePivotTablesandQueryTables,
|
|
287
426
|
updateQueryTable: updateQueryTable,
|
|
288
427
|
updatePivotTable: updatePivotTable,
|
|
428
|
+
getSheetPathByNameFromZip: getSheetPathByNameFromZip,
|
|
429
|
+
getReferenceFromTable: getReferenceFromTable,
|
|
430
|
+
findTablePathFromZip: findTablePathFromZip,
|
|
289
431
|
};
|
|
@@ -44,26 +44,63 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
44
44
|
var constants_1 = require("./constants");
|
|
45
45
|
var mashupDocumentParser_1 = require("./mashupDocumentParser");
|
|
46
46
|
var pqUtils_1 = __importDefault(require("./pqUtils"));
|
|
47
|
-
var xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
|
|
48
47
|
var tableUtils_1 = __importDefault(require("./tableUtils"));
|
|
48
|
+
var xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
|
|
49
|
+
var documentUtils_1 = __importDefault(require("./documentUtils"));
|
|
49
50
|
var updateWorkbookDataAndConfigurations = function (zip, fileConfigs, tableData, updateQueryTable) {
|
|
50
51
|
if (updateQueryTable === void 0) { updateQueryTable = false; }
|
|
51
52
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
var sheetName, tablePath, sheetPath, templateSettings, sheetLocation, _a, cellRangeRef, _b, row, column, endColumn, endRow;
|
|
54
|
+
return __generator(this, function (_c) {
|
|
55
|
+
switch (_c.label) {
|
|
56
|
+
case 0:
|
|
57
|
+
sheetName = constants_1.defaults.sheetName;
|
|
58
|
+
tablePath = constants_1.tableXmlPath;
|
|
59
|
+
sheetPath = constants_1.sheetsXmlPath;
|
|
60
|
+
if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) !== undefined)) return [3 /*break*/, 4];
|
|
61
|
+
templateSettings = fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateSettings;
|
|
62
|
+
if (!((templateSettings === null || templateSettings === void 0 ? void 0 : templateSettings.sheetName) !== undefined)) return [3 /*break*/, 2];
|
|
63
|
+
return [4 /*yield*/, xmlInnerPartsUtils_1.default.getSheetPathByNameFromZip(zip, templateSettings.sheetName)];
|
|
55
64
|
case 1:
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
sheetLocation = _c.sent();
|
|
66
|
+
sheetName = templateSettings.sheetName;
|
|
67
|
+
sheetPath = "xl/" + sheetLocation;
|
|
68
|
+
_c.label = 2;
|
|
69
|
+
case 2:
|
|
70
|
+
if (!((templateSettings === null || templateSettings === void 0 ? void 0 : templateSettings.tableName) !== undefined)) return [3 /*break*/, 4];
|
|
71
|
+
_a = constants_1.tablesFolderPath;
|
|
72
|
+
return [4 /*yield*/, xmlInnerPartsUtils_1.default.findTablePathFromZip(zip, templateSettings === null || templateSettings === void 0 ? void 0 : templateSettings.tableName)];
|
|
73
|
+
case 3:
|
|
74
|
+
tablePath = _a + (_c.sent());
|
|
75
|
+
_c.label = 4;
|
|
76
|
+
case 4:
|
|
77
|
+
cellRangeRef = "A1";
|
|
78
|
+
if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) !== undefined)) return [3 /*break*/, 6];
|
|
79
|
+
return [4 /*yield*/, xmlInnerPartsUtils_1.default.getReferenceFromTable(zip, tablePath)];
|
|
80
|
+
case 5:
|
|
81
|
+
cellRangeRef = _c.sent();
|
|
82
|
+
_c.label = 6;
|
|
83
|
+
case 6:
|
|
84
|
+
if (tableData) {
|
|
85
|
+
_b = documentUtils_1.default.GetStartPosition(cellRangeRef), row = _b.row, column = _b.column;
|
|
86
|
+
endColumn = column - 1 + tableData.columnNames.length;
|
|
87
|
+
endRow = row - 1 + tableData.rows.length;
|
|
88
|
+
// Extend the cell range to include the entire table span
|
|
89
|
+
cellRangeRef += ":".concat(documentUtils_1.default.getCellReferenceRelative(endColumn - 1, endRow + 1));
|
|
90
|
+
}
|
|
91
|
+
return [4 /*yield*/, xmlInnerPartsUtils_1.default.updateDocProps(zip, fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.docProps)];
|
|
92
|
+
case 7:
|
|
93
|
+
_c.sent();
|
|
94
|
+
if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) === undefined)) return [3 /*break*/, 9];
|
|
58
95
|
// If we are using our base template, we need to clear label info
|
|
59
96
|
return [4 /*yield*/, xmlInnerPartsUtils_1.default.clearLabelInfo(zip)];
|
|
60
|
-
case
|
|
97
|
+
case 8:
|
|
61
98
|
// If we are using our base template, we need to clear label info
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
case
|
|
65
|
-
case
|
|
66
|
-
|
|
99
|
+
_c.sent();
|
|
100
|
+
_c.label = 9;
|
|
101
|
+
case 9: return [4 /*yield*/, tableUtils_1.default.updateTableInitialDataIfNeeded(zip, cellRangeRef, sheetPath, tablePath, sheetPath, tableData, updateQueryTable)];
|
|
102
|
+
case 10:
|
|
103
|
+
_c.sent();
|
|
67
104
|
return [2 /*return*/];
|
|
68
105
|
}
|
|
69
106
|
});
|
|
@@ -89,8 +126,8 @@ var updateWorkbookPowerQueryDocument = function (zip, queryName, queryMashupDoc)
|
|
|
89
126
|
}
|
|
90
127
|
});
|
|
91
128
|
}); };
|
|
92
|
-
var updateWorkbookSingleQueryAttributes = function (zip, queryName, refreshOnOpen) { return __awaiter(void 0, void 0, void 0, function () {
|
|
93
|
-
var connectionsXmlString, _a, connectionId, connectionXmlFileString, sharedStringsXmlString, _b, sharedStringIndex, newSharedStrings, sheetsXmlString, worksheetString;
|
|
129
|
+
var updateWorkbookSingleQueryAttributes = function (zip, queryName, refreshOnOpen, sheetName) { return __awaiter(void 0, void 0, void 0, function () {
|
|
130
|
+
var connectionsXmlString, _a, connectionId, connectionXmlFileString, sharedStringsXmlString, _b, sharedStringIndex, newSharedStrings, sheetPath, sheetLocation, sheetsXmlString, worksheetString;
|
|
94
131
|
var _c, _d, _e;
|
|
95
132
|
return __generator(this, function (_f) {
|
|
96
133
|
switch (_f.label) {
|
|
@@ -110,17 +147,24 @@ var updateWorkbookSingleQueryAttributes = function (zip, queryName, refreshOnOpe
|
|
|
110
147
|
}
|
|
111
148
|
_b = xmlInnerPartsUtils_1.default.updateSharedStrings(sharedStringsXmlString, queryName), sharedStringIndex = _b.sharedStringIndex, newSharedStrings = _b.newSharedStrings;
|
|
112
149
|
zip.file(constants_1.sharedStringsXmlPath, newSharedStrings);
|
|
113
|
-
|
|
150
|
+
sheetPath = constants_1.sheetsXmlPath;
|
|
151
|
+
if (!(sheetName !== undefined)) return [3 /*break*/, 4];
|
|
152
|
+
return [4 /*yield*/, xmlInnerPartsUtils_1.default.getSheetPathByNameFromZip(zip, sheetName)];
|
|
114
153
|
case 3:
|
|
154
|
+
sheetLocation = _f.sent();
|
|
155
|
+
sheetPath = "xl/" + sheetLocation;
|
|
156
|
+
_f.label = 4;
|
|
157
|
+
case 4: return [4 /*yield*/, ((_e = zip.file(sheetPath)) === null || _e === void 0 ? void 0 : _e.async(constants_1.textResultType))];
|
|
158
|
+
case 5:
|
|
115
159
|
sheetsXmlString = _f.sent();
|
|
116
160
|
if (sheetsXmlString === undefined) {
|
|
117
161
|
throw new Error(constants_1.sheetsNotFoundErr);
|
|
118
162
|
}
|
|
119
163
|
worksheetString = xmlInnerPartsUtils_1.default.updateWorksheet(sheetsXmlString, sharedStringIndex.toString());
|
|
120
|
-
zip.file(
|
|
164
|
+
zip.file(sheetPath, worksheetString);
|
|
121
165
|
// Update tables
|
|
122
166
|
return [4 /*yield*/, xmlInnerPartsUtils_1.default.updatePivotTablesandQueryTables(zip, queryName, refreshOnOpen, connectionId)];
|
|
123
|
-
case
|
|
167
|
+
case 6:
|
|
124
168
|
// Update tables
|
|
125
169
|
_f.sent();
|
|
126
170
|
return [2 /*return*/];
|