@kepler.gl/duckdb 3.3.0-alpha.5 → 3.3.0-alpha.6
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/cjs/adapters/duckdb-wasm-adapter.js +258 -0
- package/dist/{components → cjs/components}/index.js +1 -1
- package/dist/cjs/components/monaco-editor.js +174 -0
- package/dist/cjs/components/preview-data-panel.js +127 -0
- package/dist/cjs/components/schema-panel.js +170 -0
- package/dist/cjs/components/sql-panel.js +395 -0
- package/dist/cjs/components/tree.js +90 -0
- package/dist/{index.js → cjs/index.js} +1 -1
- package/dist/{plugin.js → cjs/plugin.js} +1 -1
- package/dist/cjs/processors/data-processor.js +353 -0
- package/dist/cjs/table/duckdb-table-utils.js +668 -0
- package/dist/cjs/table/duckdb-table.js +479 -0
- package/dist/{table → cjs/table}/index.js +1 -1
- package/dist/cjs/utils/perf.js +46 -0
- package/dist/esm/adapters/duckdb-wasm-adapter.js +251 -0
- package/dist/esm/components/index.js +9 -0
- package/dist/esm/components/monaco-editor.js +167 -0
- package/dist/esm/components/preview-data-panel.js +120 -0
- package/dist/esm/components/schema-panel.js +164 -0
- package/dist/esm/components/sql-panel.js +388 -0
- package/dist/esm/components/tree.js +82 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/plugin.js +22 -0
- package/dist/esm/processors/data-processor.js +342 -0
- package/dist/esm/table/duckdb-table-utils.js +644 -0
- package/dist/esm/table/duckdb-table.js +474 -0
- package/dist/esm/table/index.js +5 -0
- package/dist/esm/utils/perf.js +40 -0
- package/package.json +21 -17
- package/dist/adapters/duckdb-wasm-adapter.js +0 -258
- package/dist/components/monaco-editor.js +0 -174
- package/dist/components/preview-data-panel.js +0 -127
- package/dist/components/schema-panel.js +0 -170
- package/dist/components/sql-panel.js +0 -395
- package/dist/components/tree.js +0 -90
- package/dist/processors/data-processor.js +0 -353
- package/dist/table/duckdb-table-utils.js +0 -668
- package/dist/table/duckdb-table.js +0 -479
- package/dist/utils/perf.js +0 -46
|
@@ -1,668 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.SUPPORTED_DUCKDB_DROP_EXTENSIONS = void 0;
|
|
9
|
-
exports.castDuckDBTypesForKepler = castDuckDBTypesForKepler;
|
|
10
|
-
exports.checkIsSelectQuery = checkIsSelectQuery;
|
|
11
|
-
exports.dropTableIfExists = void 0;
|
|
12
|
-
exports.getDuckDBColumnTypes = getDuckDBColumnTypes;
|
|
13
|
-
exports.getDuckDBColumnTypesMap = getDuckDBColumnTypesMap;
|
|
14
|
-
exports.isGeoArrowLineString = isGeoArrowLineString;
|
|
15
|
-
exports.isGeoArrowMultiLineString = isGeoArrowMultiLineString;
|
|
16
|
-
exports.isGeoArrowMultiPoint = isGeoArrowMultiPoint;
|
|
17
|
-
exports.isGeoArrowMultiPolygon = isGeoArrowMultiPolygon;
|
|
18
|
-
exports.isGeoArrowPoint = isGeoArrowPoint;
|
|
19
|
-
exports.isGeoArrowPolygon = isGeoArrowPolygon;
|
|
20
|
-
exports.quoteTableName = quoteTableName;
|
|
21
|
-
exports.removeSQLComments = removeSQLComments;
|
|
22
|
-
exports.restoreUnsupportedExtensions = exports.restoreArrowTable = exports.removeUnsupportedExtensions = void 0;
|
|
23
|
-
exports.sanitizeDuckDBTableName = sanitizeDuckDBTableName;
|
|
24
|
-
exports.setGeoArrowWKBExtension = setGeoArrowWKBExtension;
|
|
25
|
-
exports.splitSqlStatements = splitSqlStatements;
|
|
26
|
-
exports.tableFromFile = tableFromFile;
|
|
27
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
28
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
29
|
-
var arrow = _interopRequireWildcard(require("apache-arrow"));
|
|
30
|
-
var _type = require("apache-arrow/type");
|
|
31
|
-
var _duckdbWasm = require("@duckdb/duckdb-wasm");
|
|
32
|
-
var _constants = require("@kepler.gl/constants");
|
|
33
|
-
var _utils = require("@kepler.gl/utils");
|
|
34
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
35
|
-
// SPDX-License-Identifier: MIT
|
|
36
|
-
// Copyright contributors to the kepler.gl project
|
|
37
|
-
|
|
38
|
-
// loaders.gl
|
|
39
|
-
// SPDX-License-Identifier: MIT
|
|
40
|
-
// Copyright (c) vis.gl contributors
|
|
41
|
-
|
|
42
|
-
// Copied from loaders.gl/geoarrow
|
|
43
|
-
|
|
44
|
-
// TODO: Remove isGeoArrow* once Kepler.gl is upgraded to loaders.gl 4.4+
|
|
45
|
-
|
|
46
|
-
var SUPPORTED_DUCKDB_DROP_EXTENSIONS = exports.SUPPORTED_DUCKDB_DROP_EXTENSIONS = ['arrow', 'csv', 'geojson', 'json', 'parquet'];
|
|
47
|
-
/**
|
|
48
|
-
* Queries a DuckDB table for the schema description.
|
|
49
|
-
* @param connection An active DuckDB connection.
|
|
50
|
-
* @param tableName A name of DuckDB table to query.
|
|
51
|
-
* @returns An array of column names and DuckDB types.
|
|
52
|
-
*/
|
|
53
|
-
function getDuckDBColumnTypes(_x, _x2) {
|
|
54
|
-
return _getDuckDBColumnTypes.apply(this, arguments);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Generates a mapping of column names to their corresponding DuckDB data types.
|
|
58
|
-
* @param columns An array of column descriptions from DuckDB. Check getDuckDBColumnTypes.
|
|
59
|
-
* @returns A record where keys are column names and values are their data types.
|
|
60
|
-
*/
|
|
61
|
-
function _getDuckDBColumnTypes() {
|
|
62
|
-
_getDuckDBColumnTypes = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(connection, tableName) {
|
|
63
|
-
var quotedTableName, duckDbTypes, resInfo, numRows, columnNames, columnTypes, i, resDescribe, _numRows, _i, _resDescribe$getChild, _resDescribe$getChild2, columnName, columnType, error;
|
|
64
|
-
return _regenerator["default"].wrap(function _callee2$(_context2) {
|
|
65
|
-
while (1) switch (_context2.prev = _context2.next) {
|
|
66
|
-
case 0:
|
|
67
|
-
quotedTableName = quoteTableName(tableName);
|
|
68
|
-
duckDbTypes = [];
|
|
69
|
-
_context2.prev = 2;
|
|
70
|
-
_context2.next = 5;
|
|
71
|
-
return connection.query("PRAGMA table_info(".concat(quotedTableName, ")"));
|
|
72
|
-
case 5:
|
|
73
|
-
resInfo = _context2.sent;
|
|
74
|
-
numRows = resInfo.numRows;
|
|
75
|
-
columnNames = resInfo.getChild('name');
|
|
76
|
-
columnTypes = resInfo.getChild('type');
|
|
77
|
-
for (i = 0; i < numRows; ++i) {
|
|
78
|
-
duckDbTypes.push({
|
|
79
|
-
name: columnNames === null || columnNames === void 0 ? void 0 : columnNames.get(i),
|
|
80
|
-
type: columnTypes === null || columnTypes === void 0 ? void 0 : columnTypes.get(i)
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
_context2.next = 27;
|
|
84
|
-
break;
|
|
85
|
-
case 12:
|
|
86
|
-
_context2.prev = 12;
|
|
87
|
-
_context2.t0 = _context2["catch"](2);
|
|
88
|
-
_context2.prev = 14;
|
|
89
|
-
_context2.next = 17;
|
|
90
|
-
return connection.query("DESCRIBE ".concat(quotedTableName));
|
|
91
|
-
case 17:
|
|
92
|
-
resDescribe = _context2.sent;
|
|
93
|
-
_numRows = resDescribe.numRows;
|
|
94
|
-
for (_i = 0; _i < _numRows; ++_i) {
|
|
95
|
-
columnName = (_resDescribe$getChild = resDescribe.getChildAt(0)) === null || _resDescribe$getChild === void 0 ? void 0 : _resDescribe$getChild.get(_i);
|
|
96
|
-
columnType = (_resDescribe$getChild2 = resDescribe.getChildAt(1)) === null || _resDescribe$getChild2 === void 0 ? void 0 : _resDescribe$getChild2.get(_i);
|
|
97
|
-
duckDbTypes.push({
|
|
98
|
-
name: columnName,
|
|
99
|
-
type: columnType
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
_context2.next = 27;
|
|
103
|
-
break;
|
|
104
|
-
case 22:
|
|
105
|
-
_context2.prev = 22;
|
|
106
|
-
_context2.t1 = _context2["catch"](14);
|
|
107
|
-
error = new Error("[DuckDB] Failed to load column types for ".concat(tableName, " (PRAGMA + DESCRIBE)."));
|
|
108
|
-
error.cause = {
|
|
109
|
-
primaryError: _context2.t0,
|
|
110
|
-
fallbackError: _context2.t1
|
|
111
|
-
};
|
|
112
|
-
throw error;
|
|
113
|
-
case 27:
|
|
114
|
-
return _context2.abrupt("return", duckDbTypes);
|
|
115
|
-
case 28:
|
|
116
|
-
case "end":
|
|
117
|
-
return _context2.stop();
|
|
118
|
-
}
|
|
119
|
-
}, _callee2, null, [[2, 12], [14, 22]]);
|
|
120
|
-
}));
|
|
121
|
-
return _getDuckDBColumnTypes.apply(this, arguments);
|
|
122
|
-
}
|
|
123
|
-
function getDuckDBColumnTypesMap(columns) {
|
|
124
|
-
return columns.reduce(function (acc, value) {
|
|
125
|
-
acc[value.name] = value.type;
|
|
126
|
-
return acc;
|
|
127
|
-
}, {});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Quotes a table name for safe SQL usage.
|
|
132
|
-
* Always quotes to handle all edge cases (spaces, special characters, reserved words).
|
|
133
|
-
* For fully qualified names (containing dots), preserves the existing structure.
|
|
134
|
-
* @param tableName The table name to quote.
|
|
135
|
-
* @returns The table name, properly quoted.
|
|
136
|
-
*/
|
|
137
|
-
function quoteTableName(tableName) {
|
|
138
|
-
// Return as-is if:
|
|
139
|
-
// 1. It's already a properly quoted simple identifier (starts and ends with quotes)
|
|
140
|
-
// 2. It contains both dots and quotes (assume it's a qualified name)
|
|
141
|
-
if (tableName.startsWith('"') && tableName.endsWith('"') || tableName.includes('.') && tableName.includes('"')) {
|
|
142
|
-
return tableName;
|
|
143
|
-
}
|
|
144
|
-
return "\"".concat(tableName.replace(/"/g, '""'), "\"");
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Quotes a column name for safe SQL usage.
|
|
149
|
-
* Always quotes to handle all edge cases (spaces, special characters, reserved words).
|
|
150
|
-
* @param columnName The column name to quote.
|
|
151
|
-
* @returns The column name, properly quoted.
|
|
152
|
-
*/
|
|
153
|
-
function quoteColumnName(columnName) {
|
|
154
|
-
return "\"".concat(columnName.replace(/"/g, '""'), "\"");
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Constructs an SQL query to select all columns from a given table,
|
|
159
|
-
* converting specified columns to Well-Known Binary (WKB) format using ST_AsWKB,
|
|
160
|
-
* and casting BIGINT columns to DOUBLE if specified.
|
|
161
|
-
* @param tableName The name of the table from which to select data.
|
|
162
|
-
* @param columns An array of column descriptors, each with a type and name.
|
|
163
|
-
* @param options Optional parameters to control the conversion behavior.
|
|
164
|
-
* @returns The constructed SQL query.
|
|
165
|
-
*/
|
|
166
|
-
function castDuckDBTypesForKepler(tableName, columns) {
|
|
167
|
-
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
168
|
-
geometryToWKB: true,
|
|
169
|
-
bigIntToDouble: true
|
|
170
|
-
};
|
|
171
|
-
var modifiedColumns = columns.map(function (column) {
|
|
172
|
-
var name = column.name,
|
|
173
|
-
type = column.type;
|
|
174
|
-
var quotedColumnName = quoteColumnName(name);
|
|
175
|
-
if (type === 'GEOMETRY' && options.geometryToWKB) {
|
|
176
|
-
return "ST_AsWKB(".concat(quotedColumnName, ") as ").concat(quotedColumnName);
|
|
177
|
-
} else if (options.bigIntToDouble && (type === 'BIGINT' || type === 'UBIGINT' || type === 'HUGEINT' || type === 'UHUGEINT' || type.startsWith('DECIMAL'))) {
|
|
178
|
-
// Cast 64-bit and larger integer types and DECIMAL to DOUBLE to avoid BigInt in JS
|
|
179
|
-
return "CAST(".concat(quotedColumnName, " AS DOUBLE) as ").concat(quotedColumnName);
|
|
180
|
-
}
|
|
181
|
-
return quotedColumnName;
|
|
182
|
-
});
|
|
183
|
-
var quotedTableName = quoteTableName(tableName);
|
|
184
|
-
return "SELECT ".concat(modifiedColumns.join(', '), " FROM ").concat(quotedTableName);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Sets the GeoArrow WKB extension metadata for columns of type GEOMETRY in an Arrow table.
|
|
189
|
-
* @param table The Apache Arrow table whose schema fields will be modified.
|
|
190
|
-
* @param columns An array of column descriptors from a DuckDB table.
|
|
191
|
-
*/
|
|
192
|
-
function setGeoArrowWKBExtension(table, columns) {
|
|
193
|
-
table.schema.fields.forEach(function (field) {
|
|
194
|
-
var info = columns.find(function (t) {
|
|
195
|
-
return t.name === field.name;
|
|
196
|
-
});
|
|
197
|
-
if ((info === null || info === void 0 ? void 0 : info.type) === 'GEOMETRY') {
|
|
198
|
-
field.metadata.set(_constants.GEOARROW_METADATA_KEY, _constants.GEOARROW_EXTENSIONS.WKB);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Creates an arrow table from an array of arrow vectors and fields.
|
|
205
|
-
* @param columns An array of arrow vectors.
|
|
206
|
-
* @param fields An array of fields per arrow vector.
|
|
207
|
-
* @param arrowSchema Optional arrow table schema when available.
|
|
208
|
-
* @returns An arrow table.
|
|
209
|
-
*/
|
|
210
|
-
var restoreArrowTable = exports.restoreArrowTable = function restoreArrowTable(columns, fields, arrowSchema) {
|
|
211
|
-
var creaOpts = {};
|
|
212
|
-
fields.map(function (field, index) {
|
|
213
|
-
creaOpts[field.name] = columns[index];
|
|
214
|
-
});
|
|
215
|
-
return arrowSchema ? new arrow.Table(arrowSchema, creaOpts) : new arrow.Table(creaOpts);
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* DuckDb throws when geoarrow extensions are present in metadata.
|
|
220
|
-
* @param table An arrow table to clear from extensions.
|
|
221
|
-
* @returns A map of removed per field geoarrow extensions.
|
|
222
|
-
*/
|
|
223
|
-
var removeUnsupportedExtensions = exports.removeUnsupportedExtensions = function removeUnsupportedExtensions(table) {
|
|
224
|
-
var removedMetadata = {};
|
|
225
|
-
table.schema.fields.forEach(function (field) {
|
|
226
|
-
var extension = field.metadata.get(_constants.GEOARROW_METADATA_KEY);
|
|
227
|
-
if (extension !== null && extension !== void 0 && extension.startsWith('geoarrow')) {
|
|
228
|
-
removedMetadata[field.name] = extension;
|
|
229
|
-
field.metadata["delete"](_constants.GEOARROW_METADATA_KEY);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
return removedMetadata;
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Restore removed metadata extensions after a call to removeUnsupportedExtensions.
|
|
237
|
-
* @param table An arrow table to restore geoarrow extensions.
|
|
238
|
-
* @param removedExtensions A map of per field geoarrow extensions to restore.
|
|
239
|
-
*/
|
|
240
|
-
var restoreUnsupportedExtensions = exports.restoreUnsupportedExtensions = function restoreUnsupportedExtensions(table, removedExtensions) {
|
|
241
|
-
table.schema.fields.forEach(function (field) {
|
|
242
|
-
var extension = removedExtensions[field.name];
|
|
243
|
-
if (extension) {
|
|
244
|
-
field.metadata.set(_constants.GEOARROW_METADATA_KEY, extension);
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
/** Checks whether the given Apache Arrow JS type is a Point data type */
|
|
250
|
-
function isGeoArrowPoint(type) {
|
|
251
|
-
if (_type.DataType.isFixedSizeList(type)) {
|
|
252
|
-
// Check list size
|
|
253
|
-
if (![2, 3, 4].includes(type.listSize)) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Check child of FixedSizeList is floating type
|
|
258
|
-
if (!_type.DataType.isFloat(type.children[0])) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/** Checks whether the given Apache Arrow JS type is a Point data type */
|
|
267
|
-
function isGeoArrowLineString(type) {
|
|
268
|
-
// Check the outer type is a List
|
|
269
|
-
if (!_type.DataType.isList(type)) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Check the child is a point type
|
|
274
|
-
if (!isGeoArrowPoint(type.children[0].type)) {
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
return true;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/** Checks whether the given Apache Arrow JS type is a Polygon data type */
|
|
281
|
-
function isGeoArrowPolygon(type) {
|
|
282
|
-
// Check the outer vector is a List
|
|
283
|
-
if (!_type.DataType.isList(type)) {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Check the child is a linestring vector
|
|
288
|
-
if (!isGeoArrowLineString(type.children[0].type)) {
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/** Checks whether the given Apache Arrow JS type is a Polygon data type */
|
|
295
|
-
function isGeoArrowMultiPoint(type) {
|
|
296
|
-
// Check the outer vector is a List
|
|
297
|
-
if (!_type.DataType.isList(type)) {
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Check the child is a point vector
|
|
302
|
-
if (!isGeoArrowPoint(type.children[0].type)) {
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
305
|
-
return true;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/** Checks whether the given Apache Arrow JS type is a Polygon data type */
|
|
309
|
-
function isGeoArrowMultiLineString(type) {
|
|
310
|
-
// Check the outer vector is a List
|
|
311
|
-
if (!_type.DataType.isList(type)) {
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Check the child is a linestring vector
|
|
316
|
-
if (!isGeoArrowLineString(type.children[0].type)) {
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
return true;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/** Checks whether the given Apache Arrow JS type is a Polygon data type */
|
|
323
|
-
function isGeoArrowMultiPolygon(type) {
|
|
324
|
-
// Check the outer vector is a List
|
|
325
|
-
if (!_type.DataType.isList(type)) {
|
|
326
|
-
return false;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Check the child is a polygon vector
|
|
330
|
-
if (!isGeoArrowPolygon(type.children[0].type)) {
|
|
331
|
-
return false;
|
|
332
|
-
}
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Checks if the given SQL query is a SELECT query by using the EXPLAIN command.
|
|
338
|
-
* @param connection The DuckDB connection instance.
|
|
339
|
-
* @param query The SQL query to check.
|
|
340
|
-
* @returns Resolves to `true` if the query is a SELECT statement, otherwise `false`.
|
|
341
|
-
*/
|
|
342
|
-
function checkIsSelectQuery(_x3, _x4) {
|
|
343
|
-
return _checkIsSelectQuery.apply(this, arguments);
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Split a string with potentially multiple SQL queries (separated as usual by ';') into an array of queries.
|
|
347
|
-
* This implementation:
|
|
348
|
-
* - Handles single and double quoted strings with proper escaping
|
|
349
|
-
* - Ignores semicolons in line comments (--) and block comments (slash asterisk)
|
|
350
|
-
* - Trims whitespace from queries
|
|
351
|
-
* - Handles SQL-style escaped quotes ('' inside strings)
|
|
352
|
-
* - Returns only non-empty queries
|
|
353
|
-
* @param input A string with potentially multiple SQL queries.
|
|
354
|
-
* @returns An array of queries.
|
|
355
|
-
*/
|
|
356
|
-
function _checkIsSelectQuery() {
|
|
357
|
-
_checkIsSelectQuery = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3(connection, query) {
|
|
358
|
-
var result;
|
|
359
|
-
return _regenerator["default"].wrap(function _callee3$(_context3) {
|
|
360
|
-
while (1) switch (_context3.prev = _context3.next) {
|
|
361
|
-
case 0:
|
|
362
|
-
_context3.prev = 0;
|
|
363
|
-
_context3.next = 3;
|
|
364
|
-
return connection.query("EXPLAIN (".concat(query, ")"));
|
|
365
|
-
case 3:
|
|
366
|
-
result = _context3.sent;
|
|
367
|
-
return _context3.abrupt("return", result.numRows > 0);
|
|
368
|
-
case 7:
|
|
369
|
-
_context3.prev = 7;
|
|
370
|
-
_context3.t0 = _context3["catch"](0);
|
|
371
|
-
return _context3.abrupt("return", false);
|
|
372
|
-
case 10:
|
|
373
|
-
case "end":
|
|
374
|
-
return _context3.stop();
|
|
375
|
-
}
|
|
376
|
-
}, _callee3, null, [[0, 7]]);
|
|
377
|
-
}));
|
|
378
|
-
return _checkIsSelectQuery.apply(this, arguments);
|
|
379
|
-
}
|
|
380
|
-
function splitSqlStatements(input) {
|
|
381
|
-
var queries = [];
|
|
382
|
-
var currentQuery = '';
|
|
383
|
-
var inSingleQuote = false;
|
|
384
|
-
var inDoubleQuote = false;
|
|
385
|
-
var inLineComment = false;
|
|
386
|
-
var inBlockComment = false;
|
|
387
|
-
for (var i = 0; i < input.length; i++) {
|
|
388
|
-
var _char = input[i];
|
|
389
|
-
if (inLineComment) {
|
|
390
|
-
currentQuery += _char;
|
|
391
|
-
if (_char === '\n') {
|
|
392
|
-
inLineComment = false;
|
|
393
|
-
}
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
if (inBlockComment) {
|
|
397
|
-
currentQuery += _char;
|
|
398
|
-
if (_char === '*' && input[i + 1] === '/') {
|
|
399
|
-
inBlockComment = false;
|
|
400
|
-
currentQuery += input[++i]; // Consume '/'
|
|
401
|
-
}
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
if (inSingleQuote) {
|
|
405
|
-
currentQuery += _char;
|
|
406
|
-
if (_char === "'") {
|
|
407
|
-
// Handle escaped single quotes in SQL
|
|
408
|
-
if (i + 1 < input.length && input[i + 1] === "'") {
|
|
409
|
-
currentQuery += input[++i];
|
|
410
|
-
} else {
|
|
411
|
-
inSingleQuote = false;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
continue;
|
|
415
|
-
}
|
|
416
|
-
if (inDoubleQuote) {
|
|
417
|
-
currentQuery += _char;
|
|
418
|
-
if (_char === '"') {
|
|
419
|
-
// Handle escaped double quotes
|
|
420
|
-
if (i + 1 < input.length && input[i + 1] === '"') {
|
|
421
|
-
currentQuery += input[++i];
|
|
422
|
-
} else {
|
|
423
|
-
inDoubleQuote = false;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// Check for comment starts
|
|
430
|
-
if (_char === '-' && input[i + 1] === '-') {
|
|
431
|
-
inLineComment = true;
|
|
432
|
-
currentQuery += _char + input[++i];
|
|
433
|
-
continue;
|
|
434
|
-
}
|
|
435
|
-
if (_char === '/' && input[i + 1] === '*') {
|
|
436
|
-
inBlockComment = true;
|
|
437
|
-
currentQuery += _char + input[++i];
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Check for quote starts
|
|
442
|
-
if (_char === "'") {
|
|
443
|
-
inSingleQuote = true;
|
|
444
|
-
currentQuery += _char;
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
if (_char === '"') {
|
|
448
|
-
inDoubleQuote = true;
|
|
449
|
-
currentQuery += _char;
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// Handle query separator
|
|
454
|
-
if (_char === ';') {
|
|
455
|
-
var _trimmed = currentQuery.trim();
|
|
456
|
-
if (_trimmed.length > 0) {
|
|
457
|
-
queries.push(_trimmed);
|
|
458
|
-
}
|
|
459
|
-
currentQuery = '';
|
|
460
|
-
continue;
|
|
461
|
-
}
|
|
462
|
-
currentQuery += _char;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// Add the final query
|
|
466
|
-
var trimmed = currentQuery.trim();
|
|
467
|
-
if (trimmed.length > 0) {
|
|
468
|
-
queries.push(trimmed);
|
|
469
|
-
}
|
|
470
|
-
return queries;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Removes SQL comments from a given SQL string.
|
|
475
|
-
* @param sql The SQL query string from which comments should be removed.
|
|
476
|
-
* @returns The cleaned SQL string without comments.
|
|
477
|
-
*/
|
|
478
|
-
function removeSQLComments(sql) {
|
|
479
|
-
// Remove multi-line comments (/* ... */)
|
|
480
|
-
sql = sql.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
481
|
-
// Remove single-line comments (-- ...)
|
|
482
|
-
sql = sql.replace(/--.*$/gm, '');
|
|
483
|
-
return sql.trim();
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Drops a table if it exists in the DuckDB database.
|
|
488
|
-
* @param connection The DuckDB connection instance.
|
|
489
|
-
* @param tableName The name of the table to drop.
|
|
490
|
-
* @returns A promise that resolves when the operation is complete.
|
|
491
|
-
* @throws Logs an error if the table drop operation fails.
|
|
492
|
-
*/
|
|
493
|
-
var dropTableIfExists = exports.dropTableIfExists = /*#__PURE__*/function () {
|
|
494
|
-
var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(connection, tableName) {
|
|
495
|
-
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
496
|
-
while (1) switch (_context.prev = _context.next) {
|
|
497
|
-
case 0:
|
|
498
|
-
_context.prev = 0;
|
|
499
|
-
_context.next = 3;
|
|
500
|
-
return connection.query("DROP TABLE IF EXISTS \"".concat(tableName, "\";"));
|
|
501
|
-
case 3:
|
|
502
|
-
_context.next = 8;
|
|
503
|
-
break;
|
|
504
|
-
case 5:
|
|
505
|
-
_context.prev = 5;
|
|
506
|
-
_context.t0 = _context["catch"](0);
|
|
507
|
-
console.error('Dropping table failed', tableName, _context.t0);
|
|
508
|
-
case 8:
|
|
509
|
-
case "end":
|
|
510
|
-
return _context.stop();
|
|
511
|
-
}
|
|
512
|
-
}, _callee, null, [[0, 5]]);
|
|
513
|
-
}));
|
|
514
|
-
return function dropTableIfExists(_x5, _x6) {
|
|
515
|
-
return _ref.apply(this, arguments);
|
|
516
|
-
};
|
|
517
|
-
}();
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Imports a file into DuckDB as a table, supporting multiple formats from SUPPORTED_DUCKDB_DROP_EXTENSIONS.
|
|
521
|
-
* @param file The file to be imported.
|
|
522
|
-
* @returns A promise that resolves when the file has been processed into a DuckDB table.
|
|
523
|
-
*/
|
|
524
|
-
function tableFromFile(_x7) {
|
|
525
|
-
return _tableFromFile.apply(this, arguments);
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Sanitizes a file name to be a valid DuckDB table name.
|
|
529
|
-
* @param fileName The input file name to be sanitized.
|
|
530
|
-
* @returns A valid DuckDB table name.
|
|
531
|
-
*/
|
|
532
|
-
function _tableFromFile() {
|
|
533
|
-
_tableFromFile = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee4(file) {
|
|
534
|
-
var fileExt, db, c, error, tableName, sourceName, arrayBuffer, uint8Array, arrowTable, message;
|
|
535
|
-
return _regenerator["default"].wrap(function _callee4$(_context4) {
|
|
536
|
-
while (1) switch (_context4.prev = _context4.next) {
|
|
537
|
-
case 0:
|
|
538
|
-
if (file) {
|
|
539
|
-
_context4.next = 2;
|
|
540
|
-
break;
|
|
541
|
-
}
|
|
542
|
-
return _context4.abrupt("return", new Error('File Drag & Drop: No file'));
|
|
543
|
-
case 2:
|
|
544
|
-
fileExt = SUPPORTED_DUCKDB_DROP_EXTENSIONS.find(function (ext) {
|
|
545
|
-
return file.name.endsWith(ext);
|
|
546
|
-
});
|
|
547
|
-
if (fileExt) {
|
|
548
|
-
_context4.next = 5;
|
|
549
|
-
break;
|
|
550
|
-
}
|
|
551
|
-
return _context4.abrupt("return", new Error("File Drag & Drop: File extension isn't supported"));
|
|
552
|
-
case 5:
|
|
553
|
-
_context4.next = 7;
|
|
554
|
-
return (0, _utils.getApplicationConfig)().database;
|
|
555
|
-
case 7:
|
|
556
|
-
db = _context4.sent;
|
|
557
|
-
if (db) {
|
|
558
|
-
_context4.next = 10;
|
|
559
|
-
break;
|
|
560
|
-
}
|
|
561
|
-
return _context4.abrupt("return", new Error('The database is not configured properly.'));
|
|
562
|
-
case 10:
|
|
563
|
-
_context4.next = 12;
|
|
564
|
-
return db.connect();
|
|
565
|
-
case 12:
|
|
566
|
-
c = _context4.sent;
|
|
567
|
-
error = null;
|
|
568
|
-
_context4.prev = 14;
|
|
569
|
-
tableName = sanitizeDuckDBTableName(file.name);
|
|
570
|
-
sourceName = 'temp_file_handle';
|
|
571
|
-
c.query("install spatial;\n load spatial;");
|
|
572
|
-
if (!(fileExt === 'arrow')) {
|
|
573
|
-
_context4.next = 28;
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
_context4.next = 21;
|
|
577
|
-
return file.arrayBuffer();
|
|
578
|
-
case 21:
|
|
579
|
-
arrayBuffer = _context4.sent;
|
|
580
|
-
uint8Array = new Uint8Array(arrayBuffer);
|
|
581
|
-
arrowTable = arrow.tableFromIPC(uint8Array);
|
|
582
|
-
_context4.next = 26;
|
|
583
|
-
return c.insertArrowTable(arrowTable, {
|
|
584
|
-
name: tableName
|
|
585
|
-
});
|
|
586
|
-
case 26:
|
|
587
|
-
_context4.next = 48;
|
|
588
|
-
break;
|
|
589
|
-
case 28:
|
|
590
|
-
_context4.next = 30;
|
|
591
|
-
return db.registerFileHandle(sourceName, file, _duckdbWasm.DuckDBDataProtocol.BROWSER_FILEREADER, true);
|
|
592
|
-
case 30:
|
|
593
|
-
if (!(fileExt === 'csv')) {
|
|
594
|
-
_context4.next = 35;
|
|
595
|
-
break;
|
|
596
|
-
}
|
|
597
|
-
_context4.next = 33;
|
|
598
|
-
return c.query("\n CREATE TABLE '".concat(tableName, "' AS\n SELECT *\n FROM read_csv('").concat(sourceName, "', header = true, auto_detect = true, sample_size = -1);\n "));
|
|
599
|
-
case 33:
|
|
600
|
-
_context4.next = 48;
|
|
601
|
-
break;
|
|
602
|
-
case 35:
|
|
603
|
-
if (!(fileExt === 'json')) {
|
|
604
|
-
_context4.next = 40;
|
|
605
|
-
break;
|
|
606
|
-
}
|
|
607
|
-
_context4.next = 38;
|
|
608
|
-
return c.query("\n CREATE TABLE '".concat(tableName, "' AS\n SELECT *\n FROM read_json_auto('").concat(sourceName, "');\n "));
|
|
609
|
-
case 38:
|
|
610
|
-
_context4.next = 48;
|
|
611
|
-
break;
|
|
612
|
-
case 40:
|
|
613
|
-
if (!(fileExt === 'geojson')) {
|
|
614
|
-
_context4.next = 45;
|
|
615
|
-
break;
|
|
616
|
-
}
|
|
617
|
-
_context4.next = 43;
|
|
618
|
-
return c.query("\n CREATE TABLE '".concat(tableName, "' AS\n SELECT *\n FROM ST_READ('").concat(sourceName, "', keep_wkb = TRUE);\n "));
|
|
619
|
-
case 43:
|
|
620
|
-
_context4.next = 48;
|
|
621
|
-
break;
|
|
622
|
-
case 45:
|
|
623
|
-
if (!(fileExt === 'parquet')) {
|
|
624
|
-
_context4.next = 48;
|
|
625
|
-
break;
|
|
626
|
-
}
|
|
627
|
-
_context4.next = 48;
|
|
628
|
-
return c.query("\n CREATE TABLE '".concat(tableName, "' AS\n SELECT *\n FROM read_parquet('").concat(sourceName, "')\n "));
|
|
629
|
-
case 48:
|
|
630
|
-
_context4.next = 54;
|
|
631
|
-
break;
|
|
632
|
-
case 50:
|
|
633
|
-
_context4.prev = 50;
|
|
634
|
-
_context4.t0 = _context4["catch"](14);
|
|
635
|
-
if (_context4.t0 instanceof Error) {
|
|
636
|
-
message = _context4.t0.message || ''; // output more readable errors for known issues
|
|
637
|
-
if (message.includes('Arrow Type with extension name: geoarrow')) {
|
|
638
|
-
error = new Error('The GeoArrow extensions are not implemented in the connected DuckDB version.');
|
|
639
|
-
} else if (message.includes("Geoparquet column 'geometry' does not have geometry types")) {
|
|
640
|
-
error = new Error("Invalid Input Error: Geoparquet column 'geometry' does not have geometry types.\nPossible reasons:\n - Old .parquet files that don't match the Parquet format specification.\n - Unsupported compression.");
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
if (!error) {
|
|
644
|
-
error = _context4.t0;
|
|
645
|
-
}
|
|
646
|
-
case 54:
|
|
647
|
-
_context4.next = 56;
|
|
648
|
-
return c.close();
|
|
649
|
-
case 56:
|
|
650
|
-
return _context4.abrupt("return", error);
|
|
651
|
-
case 57:
|
|
652
|
-
case "end":
|
|
653
|
-
return _context4.stop();
|
|
654
|
-
}
|
|
655
|
-
}, _callee4, null, [[14, 50]]);
|
|
656
|
-
}));
|
|
657
|
-
return _tableFromFile.apply(this, arguments);
|
|
658
|
-
}
|
|
659
|
-
function sanitizeDuckDBTableName(fileName) {
|
|
660
|
-
// Replace invalid characters with underscores
|
|
661
|
-
var name = fileName.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
662
|
-
// Ensure it doesn't start with a digit
|
|
663
|
-
if (/^\d/.test(name)) {
|
|
664
|
-
name = "t_".concat(name);
|
|
665
|
-
}
|
|
666
|
-
return name || 'default_table';
|
|
667
|
-
}
|
|
668
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhcnJvdyIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwicmVxdWlyZSIsIl90eXBlIiwiX2R1Y2tkYldhc20iLCJfY29uc3RhbnRzIiwiX3V0aWxzIiwiZSIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJfX2VzTW9kdWxlIiwibyIsImkiLCJmIiwiX19wcm90b19fIiwiX3R5cGVvZiIsImhhcyIsImdldCIsInNldCIsIl90IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJTVVBQT1JURURfRFVDS0RCX0RST1BfRVhURU5TSU9OUyIsImV4cG9ydHMiLCJnZXREdWNrREJDb2x1bW5UeXBlcyIsIl94IiwiX3gyIiwiX2dldER1Y2tEQkNvbHVtblR5cGVzIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJfYXN5bmNUb0dlbmVyYXRvcjIiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiX2NhbGxlZTIiLCJjb25uZWN0aW9uIiwidGFibGVOYW1lIiwicXVvdGVkVGFibGVOYW1lIiwiZHVja0RiVHlwZXMiLCJyZXNJbmZvIiwibnVtUm93cyIsImNvbHVtbk5hbWVzIiwiY29sdW1uVHlwZXMiLCJyZXNEZXNjcmliZSIsIl9udW1Sb3dzIiwiX2kiLCJfcmVzRGVzY3JpYmUkZ2V0Q2hpbGQiLCJfcmVzRGVzY3JpYmUkZ2V0Q2hpbGQyIiwiY29sdW1uTmFtZSIsImNvbHVtblR5cGUiLCJlcnJvciIsIndyYXAiLCJfY2FsbGVlMiQiLCJfY29udGV4dDIiLCJwcmV2IiwibmV4dCIsInF1b3RlVGFibGVOYW1lIiwicXVlcnkiLCJjb25jYXQiLCJzZW50IiwiZ2V0Q2hpbGQiLCJwdXNoIiwibmFtZSIsInR5cGUiLCJ0MCIsImdldENoaWxkQXQiLCJ0MSIsIkVycm9yIiwiY2F1c2UiLCJwcmltYXJ5RXJyb3IiLCJmYWxsYmFja0Vycm9yIiwiYWJydXB0Iiwic3RvcCIsImdldER1Y2tEQkNvbHVtblR5cGVzTWFwIiwiY29sdW1ucyIsInJlZHVjZSIsImFjYyIsInZhbHVlIiwic3RhcnRzV2l0aCIsImVuZHNXaXRoIiwiaW5jbHVkZXMiLCJyZXBsYWNlIiwicXVvdGVDb2x1bW5OYW1lIiwiY2FzdER1Y2tEQlR5cGVzRm9yS2VwbGVyIiwib3B0aW9ucyIsImxlbmd0aCIsInVuZGVmaW5lZCIsImdlb21ldHJ5VG9XS0IiLCJiaWdJbnRUb0RvdWJsZSIsIm1vZGlmaWVkQ29sdW1ucyIsIm1hcCIsImNvbHVtbiIsInF1b3RlZENvbHVtbk5hbWUiLCJqb2luIiwic2V0R2VvQXJyb3dXS0JFeHRlbnNpb24iLCJ0YWJsZSIsInNjaGVtYSIsImZpZWxkcyIsImZvckVhY2giLCJmaWVsZCIsImluZm8iLCJmaW5kIiwibWV0YWRhdGEiLCJHRU9BUlJPV19NRVRBREFUQV9LRVkiLCJHRU9BUlJPV19FWFRFTlNJT05TIiwiV0tCIiwicmVzdG9yZUFycm93VGFibGUiLCJhcnJvd1NjaGVtYSIsImNyZWFPcHRzIiwiaW5kZXgiLCJUYWJsZSIsInJlbW92ZVVuc3VwcG9ydGVkRXh0ZW5zaW9ucyIsInJlbW92ZWRNZXRhZGF0YSIsImV4dGVuc2lvbiIsInJlc3RvcmVVbnN1cHBvcnRlZEV4dGVuc2lvbnMiLCJyZW1vdmVkRXh0ZW5zaW9ucyIsImlzR2VvQXJyb3dQb2ludCIsIkRhdGFUeXBlIiwiaXNGaXhlZFNpemVMaXN0IiwibGlzdFNpemUiLCJpc0Zsb2F0IiwiY2hpbGRyZW4iLCJpc0dlb0Fycm93TGluZVN0cmluZyIsImlzTGlzdCIsImlzR2VvQXJyb3dQb2x5Z29uIiwiaXNHZW9BcnJvd011bHRpUG9pbnQiLCJpc0dlb0Fycm93TXVsdGlMaW5lU3RyaW5nIiwiaXNHZW9BcnJvd011bHRpUG9seWdvbiIsImNoZWNrSXNTZWxlY3RRdWVyeSIsIl94MyIsIl94NCIsIl9jaGVja0lzU2VsZWN0UXVlcnkiLCJfY2FsbGVlMyIsInJlc3VsdCIsIl9jYWxsZWUzJCIsIl9jb250ZXh0MyIsInNwbGl0U3FsU3RhdGVtZW50cyIsImlucHV0IiwicXVlcmllcyIsImN1cnJlbnRRdWVyeSIsImluU2luZ2xlUXVvdGUiLCJpbkRvdWJsZVF1b3RlIiwiaW5MaW5lQ29tbWVudCIsImluQmxvY2tDb21tZW50IiwiY2hhciIsInRyaW1tZWQiLCJ0cmltIiwicmVtb3ZlU1FMQ29tbWVudHMiLCJzcWwiLCJkcm9wVGFibGVJZkV4aXN0cyIsIl9yZWYiLCJfY2FsbGVlIiwiX2NhbGxlZSQiLCJfY29udGV4dCIsImNvbnNvbGUiLCJfeDUiLCJfeDYiLCJ0YWJsZUZyb21GaWxlIiwiX3g3IiwiX3RhYmxlRnJvbUZpbGUiLCJfY2FsbGVlNCIsImZpbGUiLCJmaWxlRXh0IiwiZGIiLCJjIiwic291cmNlTmFtZSIsImFycmF5QnVmZmVyIiwidWludDhBcnJheSIsImFycm93VGFibGUiLCJtZXNzYWdlIiwiX2NhbGxlZTQkIiwiX2NvbnRleHQ0IiwiZXh0IiwiZ2V0QXBwbGljYXRpb25Db25maWciLCJkYXRhYmFzZSIsImNvbm5lY3QiLCJzYW5pdGl6ZUR1Y2tEQlRhYmxlTmFtZSIsIlVpbnQ4QXJyYXkiLCJ0YWJsZUZyb21JUEMiLCJpbnNlcnRBcnJvd1RhYmxlIiwicmVnaXN0ZXJGaWxlSGFuZGxlIiwiRHVja0RCRGF0YVByb3RvY29sIiwiQlJPV1NFUl9GSUxFUkVBREVSIiwiY2xvc2UiLCJmaWxlTmFtZSIsInRlc3QiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFibGUvZHVja2RiLXRhYmxlLXV0aWxzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbi8vIGxvYWRlcnMuZ2xcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCAoYykgdmlzLmdsIGNvbnRyaWJ1dG9yc1xuXG4vLyBDb3BpZWQgZnJvbSBsb2FkZXJzLmdsL2dlb2Fycm93XG5cbi8vIFRPRE86IFJlbW92ZSBpc0dlb0Fycm93KiBvbmNlIEtlcGxlci5nbCBpcyB1cGdyYWRlZCB0byBsb2FkZXJzLmdsIDQuNCtcblxuaW1wb3J0ICogYXMgYXJyb3cgZnJvbSAnYXBhY2hlLWFycm93JztcbmltcG9ydCB7RGF0YVR5cGV9IGZyb20gJ2FwYWNoZS1hcnJvdy90eXBlJztcbmltcG9ydCB7RHVja0RCRGF0YVByb3RvY29sfSBmcm9tICdAZHVja2RiL2R1Y2tkYi13YXNtJztcblxuaW1wb3J0IHtHRU9BUlJPV19FWFRFTlNJT05TLCBHRU9BUlJPV19NRVRBREFUQV9LRVl9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7UHJvdG9EYXRhc2V0RmllbGR9IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtEYXRhYmFzZUNvbm5lY3Rpb24sIGdldEFwcGxpY2F0aW9uQ29uZmlnfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuZXhwb3J0IGNvbnN0IFNVUFBPUlRFRF9EVUNLREJfRFJPUF9FWFRFTlNJT05TID0gWydhcnJvdycsICdjc3YnLCAnZ2VvanNvbicsICdqc29uJywgJ3BhcnF1ZXQnXTtcblxuZXhwb3J0IHR5cGUgRHVja0RCQ29sdW1uRGVzYyA9IHtuYW1lOiBzdHJpbmc7IHR5cGU6IHN0cmluZ307XG5cbi8qKlxuICogUXVlcmllcyBhIER1Y2tEQiB0YWJsZSBmb3IgdGhlIHNjaGVtYSBkZXNjcmlwdGlvbi5cbiAqIEBwYXJhbSBjb25uZWN0aW9uIEFuIGFjdGl2ZSBEdWNrREIgY29ubmVjdGlvbi5cbiAqIEBwYXJhbSB0YWJsZU5hbWUgQSBuYW1lIG9mIER1Y2tEQiB0YWJsZSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGNvbHVtbiBuYW1lcyBhbmQgRHVja0RCIHR5cGVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RHVja0RCQ29sdW1uVHlwZXMoXG4gIGNvbm5lY3Rpb246IERhdGFiYXNlQ29ubmVjdGlvbixcbiAgdGFibGVOYW1lOiBzdHJpbmdcbik6IFByb21pc2U8RHVja0RCQ29sdW1uRGVzY1tdPiB7XG4gIGNvbnN0IHF1b3RlZFRhYmxlTmFtZSA9IHF1b3RlVGFibGVOYW1lKHRhYmxlTmFtZSk7XG4gIGNvbnN0IGR1Y2tEYlR5cGVzOiBEdWNrREJDb2x1bW5EZXNjW10gPSBbXTtcbiAgdHJ5IHtcbiAgICAvLyBQUkFHTUEgdGFibGVfaW5mbyBpcyBsZXNzIGxpa2VseSB0byBiaW5kL2V4ZWN1dGUgdmlldyBTUUwgdGhhbiBERVNDUklCRSxcbiAgICAvLyBzbyBpdCBhdm9pZHMgdHJpZ2dlcmluZyByZW1vdGUgYWNjZXNzIChlLmcuLCBTMykgZm9yIHZpZXctYmFja2VkIHNjaGVtYXMuXG4gICAgY29uc3QgcmVzSW5mbyA9IGF3YWl0IGNvbm5lY3Rpb24ucXVlcnkoYFBSQUdNQSB0YWJsZV9pbmZvKCR7cXVvdGVkVGFibGVOYW1lfSlgKTtcbiAgICBjb25zdCBudW1Sb3dzID0gcmVzSW5mby5udW1Sb3dzO1xuICAgIGNvbnN0IGNvbHVtbk5hbWVzID0gcmVzSW5mby5nZXRDaGlsZCgnbmFtZScpO1xuICAgIGNvbnN0IGNvbHVtblR5cGVzID0gcmVzSW5mby5nZXRDaGlsZCgndHlwZScpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtUm93czsgKytpKSB7XG4gICAgICBkdWNrRGJUeXBlcy5wdXNoKHtcbiAgICAgICAgbmFtZTogY29sdW1uTmFtZXM/LmdldChpKSxcbiAgICAgICAgdHlwZTogY29sdW1uVHlwZXM/LmdldChpKVxuICAgICAgfSk7XG4gICAgfVxuICB9IGNhdGNoIChwcmltYXJ5RXJyb3IpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzRGVzY3JpYmUgPSBhd2FpdCBjb25uZWN0aW9uLnF1ZXJ5KGBERVNDUklCRSAke3F1b3RlZFRhYmxlTmFtZX1gKTtcbiAgICAgIGNvbnN0IG51bVJvd3MgPSByZXNEZXNjcmliZS5udW1Sb3dzO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1Sb3dzOyArK2kpIHtcbiAgICAgICAgY29uc3QgY29sdW1uTmFtZSA9IHJlc0Rlc2NyaWJlLmdldENoaWxkQXQoMCk/LmdldChpKTtcbiAgICAgICAgY29uc3QgY29sdW1uVHlwZSA9IHJlc0Rlc2NyaWJlLmdldENoaWxkQXQoMSk/LmdldChpKTtcblxuICAgICAgICBkdWNrRGJUeXBlcy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBjb2x1bW5OYW1lLFxuICAgICAgICAgIHR5cGU6IGNvbHVtblR5cGVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZmFsbGJhY2tFcnJvcikge1xuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoXG4gICAgICAgIGBbRHVja0RCXSBGYWlsZWQgdG8gbG9hZCBjb2x1bW4gdHlwZXMgZm9yICR7dGFibGVOYW1lfSAoUFJBR01BICsgREVTQ1JJQkUpLmBcbiAgICAgICk7XG4gICAgICAoZXJyb3IgYXMgRXJyb3IgJiB7Y2F1c2U/OiB1bmtub3dufSkuY2F1c2UgPSB7XG4gICAgICAgIHByaW1hcnlFcnJvcixcbiAgICAgICAgZmFsbGJhY2tFcnJvclxuICAgICAgfTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkdWNrRGJUeXBlcztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBtYXBwaW5nIG9mIGNvbHVtbiBuYW1lcyB0byB0aGVpciBjb3JyZXNwb25kaW5nIER1Y2tEQiBkYXRhIHR5cGVzLlxuICogQHBhcmFtIGNvbHVtbnMgQW4gYXJyYXkgb2YgY29sdW1uIGRlc2NyaXB0aW9ucyBmcm9tIER1Y2tEQi4gQ2hlY2sgZ2V0RHVja0RCQ29sdW1uVHlwZXMuXG4gKiBAcmV0dXJucyBBIHJlY29yZCB3aGVyZSBrZXlzIGFyZSBjb2x1bW4gbmFtZXMgYW5kIHZhbHVlcyBhcmUgdGhlaXIgZGF0YSB0eXBlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldER1Y2tEQkNvbHVtblR5cGVzTWFwKGNvbHVtbnM6IER1Y2tEQkNvbHVtbkRlc2NbXSkge1xuICByZXR1cm4gY29sdW1ucy5yZWR1Y2UoKGFjYywgdmFsdWUpID0+IHtcbiAgICBhY2NbdmFsdWUubmFtZV0gPSB2YWx1ZS50eXBlO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pO1xufVxuXG4vKipcbiAqIFF1b3RlcyBhIHRhYmxlIG5hbWUgZm9yIHNhZmUgU1FMIHVzYWdlLlxuICogQWx3YXlzIHF1b3RlcyB0byBoYW5kbGUgYWxsIGVkZ2UgY2FzZXMgKHNwYWNlcywgc3BlY2lhbCBjaGFyYWN0ZXJzLCByZXNlcnZlZCB3b3JkcykuXG4gKiBGb3IgZnVsbHkgcXVhbGlmaWVkIG5hbWVzIChjb250YWluaW5nIGRvdHMpLCBwcmVzZXJ2ZXMgdGhlIGV4aXN0aW5nIHN0cnVjdHVyZS5cbiAqIEBwYXJhbSB0YWJsZU5hbWUgVGhlIHRhYmxlIG5hbWUgdG8gcXVvdGUuXG4gKiBAcmV0dXJucyBUaGUgdGFibGUgbmFtZSwgcHJvcGVybHkgcXVvdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcXVvdGVUYWJsZU5hbWUodGFibGVOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBSZXR1cm4gYXMtaXMgaWY6XG4gIC8vIDEuIEl0J3MgYWxyZWFkeSBhIHByb3Blcmx5IHF1b3RlZCBzaW1wbGUgaWRlbnRpZmllciAoc3RhcnRzIGFuZCBlbmRzIHdpdGggcXVvdGVzKVxuICAvLyAyLiBJdCBjb250YWlucyBib3RoIGRvdHMgYW5kIHF1b3RlcyAoYXNzdW1lIGl0J3MgYSBxdWFsaWZpZWQgbmFtZSlcbiAgaWYgKFxuICAgICh0YWJsZU5hbWUuc3RhcnRzV2l0aCgnXCInKSAmJiB0YWJsZU5hbWUuZW5kc1dpdGgoJ1wiJykpIHx8XG4gICAgKHRhYmxlTmFtZS5pbmNsdWRlcygnLicpICYmIHRhYmxlTmFtZS5pbmNsdWRlcygnXCInKSlcbiAgKSB7XG4gICAgcmV0dXJuIHRhYmxlTmFtZTtcbiAgfVxuXG4gIHJldHVybiBgXCIke3RhYmxlTmFtZS5yZXBsYWNlKC9cIi9nLCAnXCJcIicpfVwiYDtcbn1cblxuLyoqXG4gKiBRdW90ZXMgYSBjb2x1bW4gbmFtZSBmb3Igc2FmZSBTUUwgdXNhZ2UuXG4gKiBBbHdheXMgcXVvdGVzIHRvIGhhbmRsZSBhbGwgZWRnZSBjYXNlcyAoc3BhY2VzLCBzcGVjaWFsIGNoYXJhY3RlcnMsIHJlc2VydmVkIHdvcmRzKS5cbiAqIEBwYXJhbSBjb2x1bW5OYW1lIFRoZSBjb2x1bW4gbmFtZSB0byBxdW90ZS5cbiAqIEByZXR1cm5zIFRoZSBjb2x1bW4gbmFtZSwgcHJvcGVybHkgcXVvdGVkLlxuICovXG5mdW5jdGlvbiBxdW90ZUNvbHVtbk5hbWUoY29sdW1uTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBcIiR7Y29sdW1uTmFtZS5yZXBsYWNlKC9cIi9nLCAnXCJcIicpfVwiYDtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGFuIFNRTCBxdWVyeSB0byBzZWxlY3QgYWxsIGNvbHVtbnMgZnJvbSBhIGdpdmVuIHRhYmxlLFxuICogY29udmVydGluZyBzcGVjaWZpZWQgY29sdW1ucyB0byBXZWxsLUtub3duIEJpbmFyeSAoV0tCKSBmb3JtYXQgdXNpbmcgU1RfQXNXS0IsXG4gKiBhbmQgY2FzdGluZyBCSUdJTlQgY29sdW1ucyB0byBET1VCTEUgaWYgc3BlY2lmaWVkLlxuICogQHBhcmFtIHRhYmxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgZnJvbSB3aGljaCB0byBzZWxlY3QgZGF0YS5cbiAqIEBwYXJhbSBjb2x1bW5zIEFuIGFycmF5IG9mIGNvbHVtbiBkZXNjcmlwdG9ycywgZWFjaCB3aXRoIGEgdHlwZSBhbmQgbmFtZS5cbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIHBhcmFtZXRlcnMgdG8gY29udHJvbCB0aGUgY29udmVyc2lvbiBiZWhhdmlvci5cbiAqIEByZXR1cm5zIFRoZSBjb25zdHJ1Y3RlZCBTUUwgcXVlcnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYXN0RHVja0RCVHlwZXNGb3JLZXBsZXIoXG4gIHRhYmxlTmFtZTogc3RyaW5nLFxuICBjb2x1bW5zOiBEdWNrREJDb2x1bW5EZXNjW10sXG4gIG9wdGlvbnMgPSB7Z2VvbWV0cnlUb1dLQjogdHJ1ZSwgYmlnSW50VG9Eb3VibGU6IHRydWV9XG4pOiBzdHJpbmcge1xuICBjb25zdCBtb2RpZmllZENvbHVtbnMgPSBjb2x1bW5zLm1hcChjb2x1bW4gPT4ge1xuICAgIGNvbnN0IHtuYW1lLCB0eXBlfSA9IGNvbHVtbjtcbiAgICBjb25zdCBxdW90ZWRDb2x1bW5OYW1lID0gcXVvdGVDb2x1bW5OYW1lKG5hbWUpO1xuICAgIGlmICh0eXBlID09PSAnR0VPTUVUUlknICYmIG9wdGlvbnMuZ2VvbWV0cnlUb1dLQikge1xuICAgICAgcmV0dXJuIGBTVF9Bc1dLQigke3F1b3RlZENvbHVtbk5hbWV9KSBhcyAke3F1b3RlZENvbHVtbk5hbWV9YDtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgb3B0aW9ucy5iaWdJbnRUb0RvdWJsZSAmJlxuICAgICAgKHR5cGUgPT09ICdCSUdJTlQnIHx8XG4gICAgICAgIHR5cGUgPT09ICdVQklHSU5UJyB8fFxuICAgICAgICB0eXBlID09PSAnSFVHRUlOVCcgfHxcbiAgICAgICAgdHlwZSA9PT0gJ1VIVUdFSU5UJyB8fFxuICAgICAgICB0eXBlLnN0YXJ0c1dpdGgoJ0RFQ0lNQUwnKSlcbiAgICApIHtcbiAgICAgIC8vIENhc3QgNjQtYml0IGFuZCBsYXJnZXIgaW50ZWdlciB0eXBlcyBhbmQgREVDSU1BTCB0byBET1VCTEUgdG8gYXZvaWQgQmlnSW50IGluIEpTXG4gICAgICByZXR1cm4gYENBU1QoJHtxdW90ZWRDb2x1bW5OYW1lfSBBUyBET1VCTEUpIGFzICR7cXVvdGVkQ29sdW1uTmFtZX1gO1xuICAgIH1cbiAgICByZXR1cm4gcXVvdGVkQ29sdW1uTmFtZTtcbiAgfSk7XG5cbiAgY29uc3QgcXVvdGVkVGFibGVOYW1lID0gcXVvdGVUYWJsZU5hbWUodGFibGVOYW1lKTtcbiAgcmV0dXJuIGBTRUxFQ1QgJHttb2RpZmllZENvbHVtbnMuam9pbignLCAnKX0gRlJPTSAke3F1b3RlZFRhYmxlTmFtZX1gO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIEdlb0Fycm93IFdLQiBleHRlbnNpb24gbWV0YWRhdGEgZm9yIGNvbHVtbnMgb2YgdHlwZSBHRU9NRVRSWSBpbiBhbiBBcnJvdyB0YWJsZS5cbiAqIEBwYXJhbSB0YWJsZSBUaGUgQXBhY2hlIEFycm93IHRhYmxlIHdob3NlIHNjaGVtYSBmaWVsZHMgd2lsbCBiZSBtb2RpZmllZC5cbiAqIEBwYXJhbSBjb2x1bW5zIEFuIGFycmF5IG9mIGNvbHVtbiBkZXNjcmlwdG9ycyBmcm9tIGEgRHVja0RCIHRhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0R2VvQXJyb3dXS0JFeHRlbnNpb24odGFibGU6IGFycm93LlRhYmxlLCBjb2x1bW5zOiBEdWNrREJDb2x1bW5EZXNjW10pIHtcbiAgdGFibGUuc2NoZW1hLmZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICBjb25zdCBpbmZvID0gY29sdW1ucy5maW5kKHQgPT4gdC5uYW1lID09PSBmaWVsZC5uYW1lKTtcbiAgICBpZiAoaW5mbz8udHlwZSA9PT0gJ0dFT01FVFJZJykge1xuICAgICAgZmllbGQubWV0YWRhdGEuc2V0KEdFT0FSUk9XX01FVEFEQVRBX0tFWSwgR0VPQVJST1dfRVhURU5TSU9OUy5XS0IpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJvdyB0YWJsZSBmcm9tIGFuIGFycmF5IG9mIGFycm93IHZlY3RvcnMgYW5kIGZpZWxkcy5cbiAqIEBwYXJhbSBjb2x1bW5zIEFuIGFycmF5IG9mIGFycm93IHZlY3RvcnMuXG4gKiBAcGFyYW0gZmllbGRzIEFuIGFycmF5IG9mIGZpZWxkcyBwZXIgYXJyb3cgdmVjdG9yLlxuICogQHBhcmFtIGFycm93U2NoZW1hIE9wdGlvbmFsIGFycm93IHRhYmxlIHNjaGVtYSB3aGVuIGF2YWlsYWJsZS5cbiAqIEByZXR1cm5zIEFuIGFycm93IHRhYmxlLlxuICovXG5leHBvcnQgY29uc3QgcmVzdG9yZUFycm93VGFibGUgPSAoXG4gIGNvbHVtbnM6IGFycm93LlZlY3RvcltdLFxuICBmaWVsZHM6IFByb3RvRGF0YXNldEZpZWxkW10sXG4gIGFycm93U2NoZW1hPzogYXJyb3cuU2NoZW1hXG4pID0+IHtcbiAgY29uc3QgY3JlYU9wdHMgPSB7fTtcbiAgZmllbGRzLm1hcCgoZmllbGQsIGluZGV4KSA9PiB7XG4gICAgY3JlYU9wdHNbZmllbGQubmFtZV0gPSBjb2x1bW5zW2luZGV4XTtcbiAgfSk7XG5cbiAgcmV0dXJuIGFycm93U2NoZW1hID8gbmV3IGFycm93LlRhYmxlKGFycm93U2NoZW1hLCBjcmVhT3B0cykgOiBuZXcgYXJyb3cuVGFibGUoY3JlYU9wdHMpO1xufTtcblxuLyoqXG4gKiBEdWNrRGIgdGhyb3dzIHdoZW4gZ2VvYXJyb3cgZXh0ZW5zaW9ucyBhcmUgcHJlc2VudCBpbiBtZXRhZGF0YS5cbiAqIEBwYXJhbSB0YWJsZSBBbiBhcnJvdyB0YWJsZSB0byBjbGVhciBmcm9tIGV4dGVuc2lvbnMuXG4gKiBAcmV0dXJucyBBIG1hcCBvZiByZW1vdmVkIHBlciBmaWVsZCBnZW9hcnJvdyBleHRlbnNpb25zLlxuICovXG5leHBvcnQgY29uc3QgcmVtb3ZlVW5zdXBwb3J0ZWRFeHRlbnNpb25zID0gKHRhYmxlOiBhcnJvdy5UYWJsZSk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPT4ge1xuICBjb25zdCByZW1vdmVkTWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgdGFibGUuc2NoZW1hLmZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICBjb25zdCBleHRlbnNpb24gPSBmaWVsZC5tZXRhZGF0YS5nZXQoR0VPQVJST1dfTUVUQURBVEFfS0VZKTtcbiAgICBpZiAoZXh0ZW5zaW9uPy5zdGFydHNXaXRoKCdnZW9hcnJvdycpKSB7XG4gICAgICByZW1vdmVkTWV0YWRhdGFbZmllbGQubmFtZV0gPSBleHRlbnNpb247XG4gICAgICBmaWVsZC5tZXRhZGF0YS5kZWxldGUoR0VPQVJST1dfTUVUQURBVEFfS0VZKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVtb3ZlZE1ldGFkYXRhO1xufTtcblxuLyoqXG4gKiBSZXN0b3JlIHJlbW92ZWQgbWV0YWRhdGEgZXh0ZW5zaW9ucyBhZnRlciBhIGNhbGwgdG8gcmVtb3ZlVW5zdXBwb3J0ZWRFeHRlbnNpb25zLlxuICogQHBhcmFtIHRhYmxlIEFuIGFycm93IHRhYmxlIHRvIHJlc3RvcmUgZ2VvYXJyb3cgZXh0ZW5zaW9ucy5cbiAqIEBwYXJhbSByZW1vdmVkRXh0ZW5zaW9ucyBBIG1hcCBvZiBwZXIgZmllbGQgZ2VvYXJyb3cgZXh0ZW5zaW9ucyB0byByZXN0b3JlLlxuICovXG5leHBvcnQgY29uc3QgcmVzdG9yZVVuc3VwcG9ydGVkRXh0ZW5zaW9ucyA9IChcbiAgdGFibGU6IGFycm93LlRhYmxlLFxuICByZW1vdmVkRXh0ZW5zaW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPlxuKSA9PiB7XG4gIHRhYmxlLnNjaGVtYS5maWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgY29uc3QgZXh0ZW5zaW9uID0gcmVtb3ZlZEV4dGVuc2lvbnNbZmllbGQubmFtZV07XG4gICAgaWYgKGV4dGVuc2lvbikge1xuICAgICAgZmllbGQubWV0YWRhdGEuc2V0KEdFT0FSUk9XX01FVEFEQVRBX0tFWSwgZXh0ZW5zaW9uKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLyoqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBBcGFjaGUgQXJyb3cgSlMgdHlwZSBpcyBhIFBvaW50IGRhdGEgdHlwZSAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzR2VvQXJyb3dQb2ludCh0eXBlOiBEYXRhVHlwZSkge1xuICBpZiAoRGF0YVR5cGUuaXNGaXhlZFNpemVMaXN0KHR5cGUpKSB7XG4gICAgLy8gQ2hlY2sgbGlzdCBzaXplXG4gICAgaWYgKCFbMiwgMywgNF0uaW5jbHVkZXModHlwZS5saXN0U2l6ZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBjaGlsZCBvZiBGaXhlZFNpemVMaXN0IGlzIGZsb2F0aW5nIHR5cGVcbiAgICBpZiAoIURhdGFUeXBlLmlzRmxvYXQodHlwZS5jaGlsZHJlblswXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBBcGFjaGUgQXJyb3cgSlMgdHlwZSBpcyBhIFBvaW50IGRhdGEgdHlwZSAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzR2VvQXJyb3dMaW5lU3RyaW5nKHR5cGU6IERhdGFUeXBlKSB7XG4gIC8vIENoZWNrIHRoZSBvdXRlciB0eXBlIGlzIGEgTGlzdFxuICBpZiAoIURhdGFUeXBlLmlzTGlzdCh0eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENoZWNrIHRoZSBjaGlsZCBpcyBhIHBvaW50IHR5cGVcbiAgaWYgKCFpc0dlb0Fycm93UG9pbnQodHlwZS5jaGlsZHJlblswXS50eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIEFwYWNoZSBBcnJvdyBKUyB0eXBlIGlzIGEgUG9seWdvbiBkYXRhIHR5cGUgKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0dlb0Fycm93UG9seWdvbih0eXBlOiBEYXRhVHlwZSkge1xuICAvLyBDaGVjayB0aGUgb3V0ZXIgdmVjdG9yIGlzIGEgTGlzdFxuICBpZiAoIURhdGFUeXBlLmlzTGlzdCh0eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENoZWNrIHRoZSBjaGlsZCBpcyBhIGxpbmVzdHJpbmcgdmVjdG9yXG4gIGlmICghaXNHZW9BcnJvd0xpbmVTdHJpbmcodHlwZS5jaGlsZHJlblswXS50eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIEFwYWNoZSBBcnJvdyBKUyB0eXBlIGlzIGEgUG9seWdvbiBkYXRhIHR5cGUgKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0dlb0Fycm93TXVsdGlQb2ludCh0eXBlOiBEYXRhVHlwZSkge1xuICAvLyBDaGVjayB0aGUgb3V0ZXIgdmVjdG9yIGlzIGEgTGlzdFxuICBpZiAoIURhdGFUeXBlLmlzTGlzdCh0eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENoZWNrIHRoZSBjaGlsZCBpcyBhIHBvaW50IHZlY3RvclxuICBpZiAoIWlzR2VvQXJyb3dQb2ludCh0eXBlLmNoaWxkcmVuWzBdLnR5cGUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gQXBhY2hlIEFycm93IEpTIHR5cGUgaXMgYSBQb2x5Z29uIGRhdGEgdHlwZSAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzR2VvQXJyb3dNdWx0aUxpbmVTdHJpbmcodHlwZTogRGF0YVR5cGUpIHtcbiAgLy8gQ2hlY2sgdGhlIG91dGVyIHZlY3RvciBpcyBhIExpc3RcbiAgaWYgKCFEYXRhVHlwZS5pc0xpc3QodHlwZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBDaGVjayB0aGUgY2hpbGQgaXMgYSBsaW5lc3RyaW5nIHZlY3RvclxuICBpZiAoIWlzR2VvQXJyb3dMaW5lU3RyaW5nKHR5cGUuY2hpbGRyZW5bMF0udHlwZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBBcGFjaGUgQXJyb3cgSlMgdHlwZSBpcyBhIFBvbHlnb24gZGF0YSB0eXBlICovXG5leHBvcnQgZnVuY3Rpb24gaXNHZW9BcnJvd011bHRpUG9seWdvbih0eXBlOiBEYXRhVHlwZSkge1xuICAvLyBDaGVjayB0aGUgb3V0ZXIgdmVjdG9yIGlzIGEgTGlzdFxuICBpZiAoIURhdGFUeXBlLmlzTGlzdCh0eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENoZWNrIHRoZSBjaGlsZCBpcyBhIHBvbHlnb24gdmVjdG9yXG4gIGlmICghaXNHZW9BcnJvd1BvbHlnb24odHlwZS5jaGlsZHJlblswXS50eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gU1FMIHF1ZXJ5IGlzIGEgU0VMRUNUIHF1ZXJ5IGJ5IHVzaW5nIHRoZSBFWFBMQUlOIGNvbW1hbmQuXG4gKiBAcGFyYW0gY29ubmVjdGlvbiBUaGUgRHVja0RCIGNvbm5lY3Rpb24gaW5zdGFuY2UuXG4gKiBAcGFyYW0gcXVlcnkgVGhlIFNRTCBxdWVyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIFJlc29sdmVzIHRvIGB0cnVlYCBpZiB0aGUgcXVlcnkgaXMgYSBTRUxFQ1Qgc3RhdGVtZW50LCBvdGhlcndpc2UgYGZhbHNlYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNoZWNrSXNTZWxlY3RRdWVyeShcbiAgY29ubmVjdGlvbjogRGF0YWJhc2VDb25uZWN0aW9uLFxuICBxdWVyeTogc3RyaW5nXG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb25uZWN0aW9uLnF1ZXJ5KGBFWFBMQUlOICgke3F1ZXJ5fSlgKTtcbiAgICByZXR1cm4gcmVzdWx0Lm51bVJvd3MgPiAwO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIFNwbGl0IGEgc3RyaW5nIHdpdGggcG90ZW50aWFsbHkgbXVsdGlwbGUgU1FMIHF1ZXJpZXMgKHNlcGFyYXRlZCBhcyB1c3VhbCBieSAnOycpIGludG8gYW4gYXJyYXkgb2YgcXVlcmllcy5cbiAqIFRoaXMgaW1wbGVtZW50YXRpb246XG4gKiAgLSBIYW5kbGVzIHNpbmdsZSBhbmQgZG91YmxlIHF1b3RlZCBzdHJpbmdzIHdpdGggcHJvcGVyIGVzY2FwaW5nXG4gKiAgLSBJZ25vcmVzIHNlbWljb2xvbnMgaW4gbGluZSBjb21tZW50cyAoLS0pIGFuZCBibG9jayBjb21tZW50cyAoc2xhc2ggYXN0ZXJpc2spXG4gKiAgLSBUcmltcyB3aGl0ZXNwYWNlIGZyb20gcXVlcmllc1xuICogIC0gSGFuZGxlcyBTUUwtc3R5bGUgZXNjYXBlZCBxdW90ZXMgKCcnIGluc2lkZSBzdHJpbmdzKVxuICogIC0gUmV0dXJucyBvbmx5IG5vbi1lbXB0eSBxdWVyaWVzXG4gKiBAcGFyYW0gaW5wdXQgQSBzdHJpbmcgd2l0aCBwb3RlbnRpYWxseSBtdWx0aXBsZSBTUUwgcXVlcmllcy5cbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHF1ZXJpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcGxpdFNxbFN0YXRlbWVudHMoaW5wdXQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcXVlcmllczogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGN1cnJlbnRRdWVyeSA9ICcnO1xuICBsZXQgaW5TaW5nbGVRdW90ZSA9IGZhbHNlO1xuICBsZXQgaW5Eb3VibGVRdW90ZSA9IGZhbHNlO1xuICBsZXQgaW5MaW5lQ29tbWVudCA9IGZhbHNlO1xuICBsZXQgaW5CbG9ja0NvbW1lbnQgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hhciA9IGlucHV0W2ldO1xuXG4gICAgaWYgKGluTGluZUNvbW1lbnQpIHtcbiAgICAgIGN1cnJlbnRRdWVyeSArPSBjaGFyO1xuICAgICAgaWYgKGNoYXIgPT09ICdcXG4nKSB7XG4gICAgICAgIGluTGluZUNvbW1lbnQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChpbkJsb2NrQ29tbWVudCkge1xuICAgICAgY3VycmVudFF1ZXJ5ICs9IGNoYXI7XG4gICAgICBpZiAoY2hhciA9PT0gJyonICYmIGlucHV0W2kgKyAxXSA9PT0gJy8nKSB7XG4gICAgICAgIGluQmxvY2tDb21tZW50ID0gZmFsc2U7XG4gICAgICAgIGN1cnJlbnRRdWVyeSArPSBpbnB1dFsrK2ldOyAvLyBDb25zdW1lICcvJ1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGluU2luZ2xlUXVvdGUpIHtcbiAgICAgIGN1cnJlbnRRdWVyeSArPSBjaGFyO1xuICAgICAgaWYgKGNoYXIgPT09IFwiJ1wiKSB7XG4gICAgICAgIC8vIEhhbmRsZSBlc2NhcGVkIHNpbmdsZSBxdW90ZXMgaW4gU1FMXG4gICAgICAgIGlmIChpICsgMSA8IGlucHV0Lmxlbmd0aCAmJiBpbnB1dFtpICsgMV0gPT09IFwiJ1wiKSB7XG4gICAgICAgICAgY3VycmVudFF1ZXJ5ICs9IGlucHV0WysraV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaW5TaW5nbGVRdW90ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaW5Eb3VibGVRdW90ZSkge1xuICAgICAgY3VycmVudFF1ZXJ5ICs9IGNoYXI7XG4gICAgICBpZiAoY2hhciA9PT0gJ1wiJykge1xuICAgICAgICAvLyBIYW5kbGUgZXNjYXBlZCBkb3VibGUgcXVvdGVzXG4gICAgICAgIGlmIChpICsgMSA8IGlucHV0Lmxlbmd0aCAmJiBpbnB1dFtpICsgMV0gPT09ICdcIicpIHtcbiAgICAgICAgICBjdXJyZW50UXVlcnkgKz0gaW5wdXRbKytpXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbkRvdWJsZVF1b3RlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBjb21tZW50IHN0YXJ0c1xuICAgIGlmIChjaGFyID09PSAnLScgJiYgaW5wdXRbaSArIDFdID09PSAnLScpIHtcbiAgICAgIGluTGluZUNvbW1lbnQgPSB0cnVlO1xuICAgICAgY3VycmVudFF1ZXJ5ICs9IGNoYXIgKyBpbnB1dFsrK2ldO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGNoYXIgPT09ICcvJyAmJiBpbnB1dFtpICsgMV0gPT09ICcqJykge1xuICAgICAgaW5CbG9ja0NvbW1lbnQgPSB0cnVlO1xuICAgICAgY3VycmVudFF1ZXJ5ICs9IGNoYXIgKyBpbnB1dFsrK2ldO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIHF1b3RlIHN0YXJ0c1xuICAgIGlmIChjaGFyID09PSBcIidcIikge1xuICAgICAgaW5TaW5nbGVRdW90ZSA9IHRydWU7XG4gICAgICBjdXJyZW50UXVlcnkgKz0gY2hhcjtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChjaGFyID09PSAnXCInKSB7XG4gICAgICBpbkRvdWJsZVF1b3RlID0gdHJ1ZTtcbiAgICAgIGN1cnJlbnRRdWVyeSArPSBjaGFyO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHF1ZXJ5IHNlcGFyYXRvclxuICAgIGlmIChjaGFyID09PSAnOycpIHtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSBjdXJyZW50UXVlcnkudHJpbSgpO1xuICAgICAgaWYgKHRyaW1tZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBxdWVyaWVzLnB1c2godHJpbW1lZCk7XG4gICAgICB9XG4gICAgICBjdXJyZW50UXVlcnkgPSAnJztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGN1cnJlbnRRdWVyeSArPSBjaGFyO1xuICB9XG5cbiAgLy8gQWRkIHRoZSBmaW5hbCBxdWVyeVxuICBjb25zdCB0cmltbWVkID0gY3VycmVudFF1ZXJ5LnRyaW0oKTtcbiAgaWYgKHRyaW1tZWQubGVuZ3RoID4gMCkge1xuICAgIHF1ZXJpZXMucHVzaCh0cmltbWVkKTtcbiAgfVxuXG4gIHJldHVybiBxdWVyaWVzO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgU1FMIGNvbW1lbnRzIGZyb20gYSBnaXZlbiBTUUwgc3RyaW5nLlxuICogQHBhcmFtIHNxbCBUaGUgU1FMIHF1ZXJ5IHN0cmluZyBmcm9tIHdoaWNoIGNvbW1lbnRzIHNob3VsZCBiZSByZW1vdmVkLlxuICogQHJldHVybnMgVGhlIGNsZWFuZWQgU1FMIHN0cmluZyB3aXRob3V0IGNvbW1lbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlU1FMQ29tbWVudHMoc3FsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBSZW1vdmUgbXVsdGktbGluZSBjb21tZW50cyAoLyogLi4uICovKVxuICBzcWwgPSBzcWwucmVwbGFjZSgvXFwvXFwqW1xcc1xcU10qP1xcKlxcLy9nLCAnJyk7XG4gIC8vIFJlbW92ZSBzaW5nbGUtbGluZSBjb21tZW50cyAoLS0gLi4uKVxuICBzcWwgPSBzcWwucmVwbGFjZSgvLS0uKiQvZ20sICcnKTtcbiAgcmV0dXJuIHNxbC50cmltKCk7XG59XG5cbi8qKlxuICogRHJvcHMgYSB0YWJsZSBpZiBpdCBleGlzdHMgaW4gdGhlIER1Y2tEQiBkYXRhYmFzZS5cbiAqIEBwYXJhbSBjb25uZWN0aW9uIFRoZSBEdWNrREIgY29ubmVjdGlvbiBpbnN0YW5jZS5cbiAqIEBwYXJhbSB0YWJsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIHRhYmxlIHRvIGRyb3AuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGUuXG4gKiBAdGhyb3dzIExvZ3MgYW4gZXJyb3IgaWYgdGhlIHRhYmxlIGRyb3Agb3BlcmF0aW9uIGZhaWxzLlxuICovXG5leHBvcnQgY29uc3QgZHJvcFRhYmxlSWZFeGlzdHMgPSBhc3luYyAoY29ubmVjdGlvbjogRGF0YWJhc2VDb25uZWN0aW9uLCB0YWJsZU5hbWU6IHN0cmluZykgPT4ge1xuICB0cnkge1xuICAgIGF3YWl0IGNvbm5lY3Rpb24ucXVlcnkoYERST1AgVEFCTEUgSUYgRVhJU1RTIFwiJHt0YWJsZU5hbWV9XCI7YCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcignRHJvcHBpbmcgdGFibGUgZmFpbGVkJywgdGFibGVOYW1lLCBlcnJvcik7XG4gIH1cbn07XG5cbi8qKlxuICogSW1wb3J0cyBhIGZpbGUgaW50byBEdWNrREIgYXMgYSB0YWJsZSwgc3VwcG9ydGluZyBtdWx0aXBsZSBmb3JtYXRzIGZyb20gU1VQUE9SVEVEX0RVQ0tEQl9EUk9QX0VYVEVOU0lPTlMuXG4gKiBAcGFyYW0gZmlsZSBUaGUgZmlsZSB0byBiZSBpbXBvcnRlZC5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGZpbGUgaGFzIGJlZW4gcHJvY2Vzc2VkIGludG8gYSBEdWNrREIgdGFibGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0YWJsZUZyb21GaWxlKGZpbGU6IEZpbGUgfCBudWxsKTogUHJvbWlzZTxudWxsIHwgRXJyb3I+IHtcbiAgaWYgKCFmaWxlKSByZXR1cm4gbmV3IEVycm9yKCdGaWxlIERyYWcgJiBEcm9wOiBObyBmaWxlJyk7XG5cbiAgY29uc3QgZmlsZUV4dCA9IFNVUFBPUlRFRF9EVUNLREJfRFJPUF9FWFRFTlNJT05TLmZpbmQoZXh0ID0+IGZpbGUubmFtZS5lbmRzV2l0aChleHQpKTtcbiAgaWYgKCFmaWxlRXh0KSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihcIkZpbGUgRHJhZyAmIERyb3A6IEZpbGUgZXh0ZW5zaW9uIGlzbid0IHN1cHBvcnRlZFwiKTtcbiAgfVxuXG4gIGNvbnN0IGRiID0gYXdhaXQgZ2V0QXBwbGljYXRpb25Db25maWcoKS5kYXRhYmFzZTtcbiAgaWYgKCFkYikge1xuICAgIHJldHVybiBuZXcgRXJyb3IoJ1RoZSBkYXRhYmFzZSBpcyBub3QgY29uZmlndXJlZCBwcm9wZXJseS4nKTtcbiAgfVxuICBjb25zdCBjID0gYXdhaXQgZGIuY29ubmVjdCgpO1xuXG4gIGxldCBlcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbDtcblxuICB0cnkge1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IHNhbml0aXplRHVja0RCVGFibGVOYW1lKGZpbGUubmFtZSk7XG4gICAgY29uc3Qgc291cmNlTmFtZSA9ICd0ZW1wX2ZpbGVfaGFuZGxlJztcblxuICAgIGMucXVlcnkoYGluc3RhbGwgc3BhdGlhbDtcbiAgICAgIGxvYWQgc3BhdGlhbDtgKTtcblxuICAgIGlmIChmaWxlRXh0ID09PSAnYXJyb3cnKSB7XG4gICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGF3YWl0IGZpbGUuYXJyYXlCdWZmZXIoKTtcbiAgICAgIGNvbnN0IHVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcik7XG4gICAgICBjb25zdCBhcnJvd1RhYmxlID0gYXJyb3cudGFibGVGcm9tSVBDKHVpbnQ4QXJyYXkpO1xuXG4gICAgICBhd2FpdCBjLmluc2VydEFycm93VGFibGUoYXJyb3dUYWJsZSwge25hbWU6IHRhYmxlTmFtZX0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBkYi5yZWdpc3RlckZpbGVIYW5kbGUoc291cmNlTmFtZSwgZmlsZSwgRHVja0RCRGF0YVByb3RvY29sLkJST1dTRVJfRklMRVJFQURFUiwgdHJ1ZSk7XG5cbiAgICAgIGlmIChmaWxlRXh0ID09PSAnY3N2Jykge1xuICAgICAgICBhd2FpdCBjLnF1ZXJ5KGBcbiAgICAgICAgICAgIENSRUFURSBUQUJMRSAnJHt0YWJsZU5hbWV9JyBBU1xuICAgICAgICAgICAgU0VMRUNUICpcbiAgICAgICAgICAgIEZST00gcmVhZF9jc3YoJyR7c291cmNlTmFtZX0nLCBoZWFkZXIgPSB0cnVlLCBhdXRvX2RldGVjdCA9IHRydWUsIHNhbXBsZV9zaXplID0gLTEpO1xuICAgICAgICAgIGApO1xuICAgICAgfSBlbHNlIGlmIChmaWxlRXh0ID09PSAnanNvbicpIHtcbiAgICAgICAgYXdhaXQgYy5xdWVyeShgXG4gICAgICAgICAgICBDUkVBVEUgVEFCTEUgJyR7dGFibGVOYW1lfScgQVNcbiAgICAgICAgICAgIFNFTEVDVCAqXG4gICAgICAgICAgICBGUk9NIHJlYWRfanNvbl9hdXRvKCcke3NvdXJjZU5hbWV9Jyk7XG4gICAgICAgICAgYCk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGVFeHQgPT09ICdnZW9qc29uJykge1xuICAgICAgICBhd2FpdCBjLnF1ZXJ5KGBcbiAgICAgICAgICAgIENSRUFURSBUQUJMRSAnJHt0YWJsZU5hbWV9JyBBU1xuICAgICAgICAgICAgU0VMRUNUICpcbiAgICAgICAgICAgIEZST00gU1RfUkVBRCgnJHtzb3VyY2VOYW1lfScsIGtlZXBfd2tiID0gVFJVRSk7XG4gICAgICAgICAgYCk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGVFeHQgPT09ICdwYXJxdWV0Jykge1xuICAgICAgICBhd2FpdCBjLnF1ZXJ5KGBcbiAgICAgICAgICAgIENSRUFURSBUQUJMRSAnJHt0YWJsZU5hbWV9JyBBU1xuICAgICAgICAgICAgU0VMRUNUICpcbiAgICAgICAgICAgIEZST00gcmVhZF9wYXJxdWV0KCcke3NvdXJjZU5hbWV9JylcbiAgICAgICAgICBgKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yRGF0YSkge1xuICAgIGlmIChlcnJvckRhdGEgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yRGF0YS5tZXNzYWdlIHx8ICcnO1xuICAgICAgLy8gb3V0cHV0IG1vcmUgcmVhZGFibGUgZXJyb3JzIGZvciBrbm93biBpc3N1ZXNcbiAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKCdBcnJvdyBUeXBlIHdpdGggZXh0ZW5zaW9uIG5hbWU6IGdlb2Fycm93JykpIHtcbiAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1RoZSBHZW9BcnJvdyBleHRlbnNpb25zIGFyZSBub3QgaW1wbGVtZW50ZWQgaW4gdGhlIGNvbm5lY3RlZCBEdWNrREIgdmVyc2lvbi4nXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCJHZW9wYXJxdWV0IGNvbHVtbiAnZ2VvbWV0cnknIGRvZXMgbm90IGhhdmUgZ2VvbWV0cnkgdHlwZXNcIikpIHtcbiAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoXG4gICAgICAgICAgYEludmFsaWQgSW5wdXQgRXJyb3I6IEdlb3BhcnF1ZXQgY29sdW1uICdnZW9tZXRyeScgZG9lcyBub3QgaGF2ZSBnZW9tZXRyeSB0eXBlcy5cblBvc3NpYmxlIHJlYXNvbnM6XG4gIC0gT2xkIC5wYXJxdWV0IGZpbGVzIHRoYXQgZG9uJ3QgbWF0Y2ggdGhlIFBhcnF1ZXQgZm9ybWF0IHNwZWNpZmljYXRpb24uXG4gIC0gVW5zdXBwb3J0ZWQgY29tcHJlc3Npb24uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZXJyb3IpIHtcbiAgICAgIGVycm9yID0gZXJyb3JEYXRhIGFzIEVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGF3YWl0IGMuY2xvc2UoKTtcblxuICByZXR1cm4gZXJyb3I7XG59XG5cbi8qKlxuICogU2FuaXRpemVzIGEgZmlsZSBuYW1lIHRvIGJlIGEgdmFsaWQgRHVja0RCIHRhYmxlIG5hbWUuXG4gKiBAcGFyYW0gZmlsZU5hbWUgVGhlIGlucHV0IGZpbGUgbmFtZSB0byBiZSBzYW5pdGl6ZWQuXG4gKiBAcmV0dXJucyBBIHZhbGlkIER1Y2tEQiB0YWJsZSBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVEdWNrREJUYWJsZU5hbWUoZmlsZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIFJlcGxhY2UgaW52YWxpZCBjaGFyYWN0ZXJzIHdpdGggdW5kZXJzY29yZXNcbiAgbGV0IG5hbWUgPSBmaWxlTmFtZS5yZXBsYWNlKC9bXmEtekEtWjAtOV9dL2csICdfJyk7XG4gIC8vIEVuc3VyZSBpdCBkb2Vzbid0IHN0YXJ0IHdpdGggYSBkaWdpdFxuICBpZiAoL15cXGQvLnRlc3QobmFtZSkpIHtcbiAgICBuYW1lID0gYHRfJHtuYW1lfWA7XG4gIH1cbiAgcmV0dXJuIG5hbWUgfHwgJ2RlZmF1bHRfdGFibGUnO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBV0EsSUFBQUEsS0FBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsS0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsV0FBQSxHQUFBRixPQUFBO0FBRUEsSUFBQUcsVUFBQSxHQUFBSCxPQUFBO0FBRUEsSUFBQUksTUFBQSxHQUFBSixPQUFBO0FBQTBFLFNBQUFELHdCQUFBTSxDQUFBLEVBQUFDLENBQUEsNkJBQUFDLE9BQUEsTUFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBUix1QkFBQSxZQUFBQSx3QkFBQU0sQ0FBQSxFQUFBQyxDQUFBLFNBQUFBLENBQUEsSUFBQUQsQ0FBQSxJQUFBQSxDQUFBLENBQUFLLFVBQUEsU0FBQUwsQ0FBQSxNQUFBTSxDQUFBLEVBQUFDLENBQUEsRUFBQUMsQ0FBQSxLQUFBQyxTQUFBLG1CQUFBVCxDQUFBLGlCQUFBQSxDQUFBLGdCQUFBVSxPQUFBLENBQUFWLENBQUEsMEJBQUFBLENBQUEsU0FBQVEsQ0FBQSxNQUFBRixDQUFBLEdBQUFMLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLFFBQUFHLENBQUEsQ0FBQUssR0FBQSxDQUFBWCxDQUFBLFVBQUFNLENBQUEsQ0FBQU0sR0FBQSxDQUFBWixDQUFBLEdBQUFNLENBQUEsQ0FBQU8sR0FBQSxDQUFBYixDQUFBLEVBQUFRLENBQUEsY0FBQU0sRUFBQSxJQUFBZCxDQUFBLGdCQUFBYyxFQUFBLE9BQUFDLGNBQUEsQ0FBQUMsSUFBQSxDQUFBaEIsQ0FBQSxF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
|