@kepler.gl/duckdb 3.3.0-alpha.0 → 3.3.0-alpha.10

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