UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

392 lines (390 loc) 64.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.SqlPanel = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _react = _interopRequireWildcard(require("react")); var _reactRedux = require("react-redux"); var _styledComponents = _interopRequireDefault(require("styled-components")); var _reactResizablePanels = require("react-resizable-panels"); var _actions = require("@kepler.gl/actions"); var _commonUtils = require("@kepler.gl/common-utils"); var _components = require("@kepler.gl/components"); var _processors = require("@kepler.gl/processors"); var _styles = require("@kepler.gl/styles"); var _utils = require("@kepler.gl/utils"); var _monacoEditor = _interopRequireDefault(require("./monaco-editor")); var _schemaPanel = require("./schema-panel"); var _previewDataPanel = require("./preview-data-panel"); var _init = require("../init"); var _duckdbTableUtils = require("../table/duckdb-table-utils"); var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12; // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } var StyledSqlPanel = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n height: 100%;\n background-color: ", ";\n border-left: 1px solid #333;\n"])), _styles.sidePanelBg); var StyledSqlActions = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n flex: 0 0 50px;\n display: flex;\n padding-top: 12px;\n align-items: center;\n flex-direction: column;\n justify-content: flex-start;\n border-bottom: 1px solid #333;\n"]))); var StyledSqlEditor = _styledComponents["default"].div(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: row;\n flex: 1;\n min-width: 0; // Prevents flex child from overflowing\n height: 100%;\n"]))); var StyledEditorPanel = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n background-color: ", ";\n display: flex;\n height: 100%;\n flex-direction: row;\n gap: 5px;\n flex-grow: 1;\n"])), _styles.sidePanelBg); var StyledDataPanel = _styledComponents["default"].div(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: column;\n height: 100%;\n background: white;\n"]))); var StyledEditor = _styledComponents["default"].div(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n padding: 12px 12px 12px 0;\n background-color: rgb(30, 30, 30);\n opacity: ", ";\n width: 100%;\n height: 100%;\n min-height: 0; // Prevents flex child from overflowing\n"])), function (props) { return props.isRunning ? 0.5 : 1; }); var StyledResultActions = _styledComponents["default"].div(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n background-color: white;\n padding: 2px 12px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 12px;\n"]))); var StyledResizeHandle = (0, _styledComponents["default"])(_reactResizablePanels.PanelResizeHandle)(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n background-color: ", ";\n width: 4px;\n cursor: col-resize;\n\n &:hover {\n background-color: #555;\n }\n"])), _styles.panelBorderColor); var StyledVerticalResizeHandle = (0, _styledComponents["default"])(_reactResizablePanels.PanelResizeHandle)(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2["default"])(["\n background-color: ", ";\n height: 4px;\n cursor: row-resize;\n\n &:hover {\n background-color: #555;\n }\n"])), _styles.panelBorderColor); var StyledLoadingContainer = _styledComponents["default"].div(_templateObject10 || (_templateObject10 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n"]))); var StyledErrorContainer = _styledComponents["default"].pre(_templateObject11 || (_templateObject11 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 12px;\n color: red;\n font-size: 12px;\n background-color: ", ";\n height: 100%;\n overflow: auto;\n"])), _styles.sidePanelBg); var StyledFileDropArea = (0, _styledComponents["default"])(_components.FileDrop)(_templateObject12 || (_templateObject12 = (0, _taggedTemplateLiteral2["default"])(["\n height: 100%;\n border-width: 1px;\n border: 1px ", "\n ", ";\n .file-drop-target {\n height: 100%;\n }\n"])), function (props) { return props.dragOver ? 'solid' : 'dashed'; }, function (props) { return props.dragOver ? props.theme.subtextColorLT : 'transparent'; }); var SCHEMA_PANEL_STYLE = { overflow: 'auto' }; var SqlPanel = exports.SqlPanel = function SqlPanel(_ref) { var _ref$initialSql = _ref.initialSql, initialSql = _ref$initialSql === void 0 ? '' : _ref$initialSql; var _useState = (0, _react.useState)(function () { var params = new URLSearchParams(window.location.search); return params.get('sql') || initialSql; }), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), sql = _useState2[0], setSql = _useState2[1]; var _useState3 = (0, _react.useState)(null), _useState4 = (0, _slicedToArray2["default"])(_useState3, 2), droppedFile = _useState4[0], setDroppedFile = _useState4[1]; var _useState5 = (0, _react.useState)(false), _useState6 = (0, _slicedToArray2["default"])(_useState5, 2), dragState = _useState6[0], setDragState = _useState6[1]; var _useState7 = (0, _react.useState)(null), _useState8 = (0, _slicedToArray2["default"])(_useState7, 2), result = _useState8[0], setResult = _useState8[1]; var _useState9 = (0, _react.useState)(0), _useState10 = (0, _slicedToArray2["default"])(_useState9, 2), schemaUpdateTrigger = _useState10[0], setSchemaUpdateTrigger = _useState10[1]; var _useState11 = (0, _react.useState)(null), _useState12 = (0, _slicedToArray2["default"])(_useState11, 2), error = _useState12[0], setError = _useState12[1]; var _useState13 = (0, _react.useState)(0), _useState14 = (0, _slicedToArray2["default"])(_useState13, 2), counter = _useState14[0], setCounter = _useState14[1]; var _useState15 = (0, _react.useState)([]), _useState16 = (0, _slicedToArray2["default"])(_useState15, 2), tableSchema = _useState16[0], setTableSchema = _useState16[1]; var _useState17 = (0, _react.useState)(false), _useState18 = (0, _slicedToArray2["default"])(_useState17, 2), isRunning = _useState18[0], setIsRunning = _useState18[1]; var _useState19 = (0, _react.useState)(function () { return (0, _utils.isAppleDevice)(); }), _useState20 = (0, _slicedToArray2["default"])(_useState19, 1), isMac = _useState20[0]; var dispatch = (0, _reactRedux.useDispatch)(); var droppedFileAreaRef = (0, _react.useRef)(null); (0, _react.useEffect)(function () { var currentUrl = new URL(window.location.href); if (sql) { currentUrl.searchParams.set('sql', sql); } else { currentUrl.searchParams["delete"]('sql'); } window.history.replaceState({}, '', currentUrl.toString()); }, [sql]); var runQuery = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { var adjustedQuery, db, connection, tempTableName, sqlStatements, arrowResult, tableDuckDBTypes, _iterator, _step, statement, isLastQuery, duckDbColumns, columnsToConvertToWKB, _adjustedQuery; return _regenerator["default"].wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: setIsRunning(true); _context.prev = 1; adjustedQuery = sql ? (0, _duckdbTableUtils.removeSQLComments)(sql) : null; if (adjustedQuery) { _context.next = 6; break; } setError(new Error('Query is empty')); return _context.abrupt("return"); case 6: _context.next = 8; return (0, _init.getDuckDB)(); case 8: db = _context.sent; _context.next = 11; return db.connect(); case 11: connection = _context.sent; // TODO find a cheap way to get DuckDb types with a single query to a remote resource - temp table? cte? tempTableName = 'temp_keplergl_table'; // remove comments sqlStatements = (0, _duckdbTableUtils.splitSqlStatements)(adjustedQuery); arrowResult = null; tableDuckDBTypes = {}; _iterator = _createForOfIteratorHelper(sqlStatements); _context.prev = 17; _iterator.s(); case 19: if ((_step = _iterator.n()).done) { _context.next = 48; break; } statement = _step.value; isLastQuery = statement === sqlStatements[sqlStatements.length - 1]; _context.t0 = isLastQuery; if (!_context.t0) { _context.next = 27; break; } _context.next = 26; return (0, _duckdbTableUtils.checkIsSelectQuery)(connection, statement); case 26: _context.t0 = _context.sent; case 27: if (!_context.t0) { _context.next = 44; break; } _context.next = 30; return connection.query("CREATE OR REPLACE TABLE '".concat(tempTableName, "' AS ").concat(statement)); case 30: _context.next = 32; return (0, _duckdbTableUtils.getDuckDBColumnTypes)(connection, tempTableName); case 32: duckDbColumns = _context.sent; tableDuckDBTypes = (0, _duckdbTableUtils.getDuckDBColumnTypesMap)(duckDbColumns); columnsToConvertToWKB = (0, _duckdbTableUtils.getGeometryColumns)(duckDbColumns); // 3) query GEOMETRY columns as WKB. _adjustedQuery = (0, _duckdbTableUtils.constructST_asWKBQuery)(tempTableName, columnsToConvertToWKB); _context.next = 38; return connection.query(_adjustedQuery); case 38: arrowResult = _context.sent; // 4) set geoarrow extension for the arrow table as DuckDB doesn't support the geoarrow extension. (0, _duckdbTableUtils.setGeoArrowWKBExtension)(arrowResult, duckDbColumns); // 5) remove temp table _context.next = 42; return connection.query("DROP TABLE ".concat(tempTableName, ";")); case 42: _context.next = 46; break; case 44: _context.next = 46; return connection.query(statement); case 46: _context.next = 19; break; case 48: _context.next = 53; break; case 50: _context.prev = 50; _context.t1 = _context["catch"](17); _iterator.e(_context.t1); case 53: _context.prev = 53; _iterator.f(); return _context.finish(53); case 56: // Show preview only for the result of the last query if (arrowResult) { setResult({ table: arrowResult, tableDuckDBTypes: tableDuckDBTypes }); setError(null); } _context.next = 59; return connection.close(); case 59: _context.next = 64; break; case 61: _context.prev = 61; _context.t2 = _context["catch"](1); setError(_context.t2); case 64: _context.prev = 64; setIsRunning(false); return _context.finish(64); case 67: // Indicate that there may be a possible change in DuckDB. setSchemaUpdateTrigger(Date.now()); case 68: case "end": return _context.stop(); } }, _callee, null, [[1, 61, 64, 67], [17, 50, 53, 56]]); })), [sql]); var onChange = (0, _react.useCallback)(function (value) { setSql(value); }, [setSql]); var onAddResultToMap = (0, _react.useCallback)(function () { if (!result) return; var keplerFields = (0, _processors.arrowSchemaToFields)(result.table, result.tableDuckDBTypes); var datasetToAdd = { data: { fields: keplerFields, // TODO type AddDataToMapPayload -> rows -> + arrow.Table rows: result.table }, info: { id: (0, _commonUtils.generateHashId)(), label: "query_result".concat(counter > 0 ? "_".concat(counter) : ''), format: 'arrow' } }; dispatch((0, _actions.addDataToMap)({ datasets: [datasetToAdd] })); setCounter(counter + 1); }, [result, counter, dispatch]); var isValidFileType = (0, _react.useCallback)(function (filename) { var fileExt = _duckdbTableUtils.SUPPORTED_DUCKDB_DROP_EXTENSIONS.find(function (ext) { return filename.endsWith(ext); }); return Boolean(fileExt); }, []); var createTableFromDroppedFile = (0, _react.useCallback)( /*#__PURE__*/function () { var _ref3 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(droppedFile) { var _error; return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: if (!droppedFile) { _context2.next = 5; break; } _context2.next = 3; return (0, _duckdbTableUtils.tableFromFile)(droppedFile); case 3: _error = _context2.sent; if (_error) { setError(_error); } else { setError(null); } case 5: setDroppedFile(null); setDragState(false); case 7: case "end": return _context2.stop(); } }, _callee2); })); return function (_x) { return _ref3.apply(this, arguments); }; }(), []); (0, _react.useEffect)(function () { createTableFromDroppedFile(droppedFile); }, [droppedFile, createTableFromDroppedFile]); var handleFileInput = (0, _react.useCallback)(function (fileList, event) { if (event) { event.preventDefault(); event.stopPropagation(); } var files = (0, _toConsumableArray2["default"])(fileList).filter(Boolean); var disableExtensionFilter = false; var filesToLoad = []; var errorFiles = []; var _iterator2 = _createForOfIteratorHelper(files), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var file = _step2.value; if (disableExtensionFilter || isValidFileType(file.name)) { filesToLoad.push(file); } else { errorFiles.push(file.name); } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } if (filesToLoad.length > 0) { setDroppedFile(filesToLoad[0]); } else if (errorFiles.length > 0) { setError(new Error("Unsupported file formats: ".concat(errorFiles.join(', ')))); } }, [isValidFileType]); return /*#__PURE__*/_react["default"].createElement(StyledSqlPanel, null, /*#__PURE__*/_react["default"].createElement(_reactResizablePanels.PanelGroup, { direction: "horizontal" }, /*#__PURE__*/_react["default"].createElement(_reactResizablePanels.Panel, { defaultSize: 20, minSize: 15, style: SCHEMA_PANEL_STYLE, className: "schema-panel" }, /*#__PURE__*/_react["default"].createElement(StyledFileDropArea, { dragOver: dragState, onDragOver: function onDragOver() { return setDragState(true); }, onDragLeave: function onDragLeave() { return setDragState(false); }, frame: droppedFileAreaRef.current || document, onDrop: handleFileInput, className: "file-uploader__file-drop" }, /*#__PURE__*/_react["default"].createElement(_schemaPanel.SchemaPanel, { setTableSchema: setTableSchema, droppedFile: droppedFile, schemaUpdateTrigger: schemaUpdateTrigger }))), /*#__PURE__*/_react["default"].createElement(StyledResizeHandle, null), /*#__PURE__*/_react["default"].createElement(_reactResizablePanels.Panel, { minSize: 40 }, /*#__PURE__*/_react["default"].createElement(StyledSqlEditor, null, /*#__PURE__*/_react["default"].createElement(_reactResizablePanels.PanelGroup, { direction: "vertical" }, /*#__PURE__*/_react["default"].createElement(_reactResizablePanels.Panel, { defaultSize: 30, className: "editor-panel" }, /*#__PURE__*/_react["default"].createElement(StyledEditorPanel, null, /*#__PURE__*/_react["default"].createElement(StyledSqlActions, null, /*#__PURE__*/_react["default"].createElement(_components.IconButton, { "data-tip": true, "data-for": "run-query-tooltip", onClick: runQuery, disabled: isRunning || !sql }, /*#__PURE__*/_react["default"].createElement(_components.Icons.Play, { height: "18px" }), /*#__PURE__*/_react["default"].createElement(_components.Tooltip, { id: "run-query-tooltip", place: "top", effect: "solid" }, "Run Query (", isMac ? '⌘Enter' : 'Ctrl+Enter', " or Shift+Enter)"))), /*#__PURE__*/_react["default"].createElement(StyledEditor, { isRunning: isRunning }, /*#__PURE__*/_react["default"].createElement(_monacoEditor["default"], { isReadOnly: isRunning, onRunQuery: runQuery, onChange: onChange, tableSchema: tableSchema, code: sql })))), /*#__PURE__*/_react["default"].createElement(StyledVerticalResizeHandle, null), /*#__PURE__*/_react["default"].createElement(_reactResizablePanels.Panel, { className: "preview-panel" }, isRunning ? /*#__PURE__*/_react["default"].createElement(StyledLoadingContainer, null, /*#__PURE__*/_react["default"].createElement(_components.LoadingSpinner, null)) : error ? /*#__PURE__*/_react["default"].createElement(StyledErrorContainer, null, /*#__PURE__*/_react["default"].createElement("div", null, error.message)) : result ? /*#__PURE__*/_react["default"].createElement(StyledDataPanel, null, /*#__PURE__*/_react["default"].createElement(StyledResultActions, null, /*#__PURE__*/_react["default"].createElement(_components.Button, { secondary: true, onClick: onAddResultToMap }, "Add to Map"), /*#__PURE__*/_react["default"].createElement("div", null, result.table.numRows, " rows")), /*#__PURE__*/_react["default"].createElement(_previewDataPanel.PreviewDataPanel, { result: result, dataTableStyle: {}, onAddResultToMap: onAddResultToMap })) : null)))))); }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVhY3RSZWR1eCIsIl9zdHlsZWRDb21wb25lbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9yZWFjdFJlc2l6YWJsZVBhbmVscyIsIl9hY3Rpb25zIiwiX2NvbW1vblV0aWxzIiwiX2NvbXBvbmVudHMiLCJfcHJvY2Vzc29ycyIsIl9zdHlsZXMiLCJfdXRpbHMiLCJfbW9uYWNvRWRpdG9yIiwiX3NjaGVtYVBhbmVsIiwiX3ByZXZpZXdEYXRhUGFuZWwiLCJfaW5pdCIsIl9kdWNrZGJUYWJsZVV0aWxzIiwiX3RlbXBsYXRlT2JqZWN0IiwiX3RlbXBsYXRlT2JqZWN0MiIsIl90ZW1wbGF0ZU9iamVjdDMiLCJfdGVtcGxhdGVPYmplY3Q0IiwiX3RlbXBsYXRlT2JqZWN0NSIsIl90ZW1wbGF0ZU9iamVjdDYiLCJfdGVtcGxhdGVPYmplY3Q3IiwiX3RlbXBsYXRlT2JqZWN0OCIsIl90ZW1wbGF0ZU9iamVjdDkiLCJfdGVtcGxhdGVPYmplY3QxMCIsIl90ZW1wbGF0ZU9iamVjdDExIiwiX3RlbXBsYXRlT2JqZWN0MTIiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiQXJyYXkiLCJpc0FycmF5IiwiX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IiwibGVuZ3RoIiwiX24iLCJGIiwicyIsImRvbmUiLCJ2YWx1ZSIsImYiLCJUeXBlRXJyb3IiLCJvIiwibmV4dCIsIl9hcnJheUxpa2VUb0FycmF5IiwidG9TdHJpbmciLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImZyb20iLCJ0ZXN0IiwiU3R5bGVkU3FsUGFuZWwiLCJzdHlsZWQiLCJkaXYiLCJfdGFnZ2VkVGVtcGxhdGVMaXRlcmFsMiIsInNpZGVQYW5lbEJnIiwiU3R5bGVkU3FsQWN0aW9ucyIsIlN0eWxlZFNxbEVkaXRvciIsIlN0eWxlZEVkaXRvclBhbmVsIiwiU3R5bGVkRGF0YVBhbmVsIiwiU3R5bGVkRWRpdG9yIiwicHJvcHMiLCJpc1J1bm5pbmciLCJTdHlsZWRSZXN1bHRBY3Rpb25zIiwiU3R5bGVkUmVzaXplSGFuZGxlIiwiUGFuZWxSZXNpemVIYW5kbGUiLCJwYW5lbEJvcmRlckNvbG9yIiwiU3R5bGVkVmVydGljYWxSZXNpemVIYW5kbGUiLCJTdHlsZWRMb2FkaW5nQ29udGFpbmVyIiwiU3R5bGVkRXJyb3JDb250YWluZXIiLCJwcmUiLCJTdHlsZWRGaWxlRHJvcEFyZWEiLCJGaWxlRHJvcCIsImRyYWdPdmVyIiwidGhlbWUiLCJzdWJ0ZXh0Q29sb3JMVCIsIlNDSEVNQV9QQU5FTF9TVFlMRSIsIm92ZXJmbG93IiwiU3FsUGFuZWwiLCJleHBvcnRzIiwiX3JlZiIsIl9yZWYkaW5pdGlhbFNxbCIsImluaXRpYWxTcWwiLCJfdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsInBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsIndpbmRvdyIsImxvY2F0aW9uIiwic2VhcmNoIiwiX3VzZVN0YXRlMiIsIl9zbGljZWRUb0FycmF5MiIsInNxbCIsInNldFNxbCIsIl91c2VTdGF0ZTMiLCJfdXNlU3RhdGU0IiwiZHJvcHBlZEZpbGUiLCJzZXREcm9wcGVkRmlsZSIsIl91c2VTdGF0ZTUiLCJfdXNlU3RhdGU2IiwiZHJhZ1N0YXRlIiwic2V0RHJhZ1N0YXRlIiwiX3VzZVN0YXRlNyIsIl91c2VTdGF0ZTgiLCJyZXN1bHQiLCJzZXRSZXN1bHQiLCJfdXNlU3RhdGU5IiwiX3VzZVN0YXRlMTAiLCJzY2hlbWFVcGRhdGVUcmlnZ2VyIiwic2V0U2NoZW1hVXBkYXRlVHJpZ2dlciIsIl91c2VTdGF0ZTExIiwiX3VzZVN0YXRlMTIiLCJlcnJvciIsInNldEVycm9yIiwiX3VzZVN0YXRlMTMiLCJfdXNlU3RhdGUxNCIsImNvdW50ZXIiLCJzZXRDb3VudGVyIiwiX3VzZVN0YXRlMTUiLCJfdXNlU3RhdGUxNiIsInRhYmxlU2NoZW1hIiwic2V0VGFibGVTY2hlbWEiLCJfdXNlU3RhdGUxNyIsIl91c2VTdGF0ZTE4Iiwic2V0SXNSdW5uaW5nIiwiX3VzZVN0YXRlMTkiLCJpc0FwcGxlRGV2aWNlIiwiX3VzZVN0YXRlMjAiLCJpc01hYyIsImRpc3BhdGNoIiwidXNlRGlzcGF0Y2giLCJkcm9wcGVkRmlsZUFyZWFSZWYiLCJ1c2VSZWYiLCJ1c2VFZmZlY3QiLCJjdXJyZW50VXJsIiwiVVJMIiwiaHJlZiIsInNlYXJjaFBhcmFtcyIsImhpc3RvcnkiLCJyZXBsYWNlU3RhdGUiLCJydW5RdWVyeSIsInVzZUNhbGxiYWNrIiwiX2FzeW5jVG9HZW5lcmF0b3IyIiwiX3JlZ2VuZXJhdG9yIiwibWFyayIsIl9jYWxsZWUiLCJhZGp1c3RlZFF1ZXJ5IiwiZGIiLCJjb25uZWN0aW9uIiwidGVtcFRhYmxlTmFtZSIsInNxbFN0YXRlbWVudHMiLCJhcnJvd1Jlc3VsdCIsInRhYmxlRHVja0RCVHlwZXMiLCJfaXRlcmF0b3IiLCJfc3RlcCIsInN0YXRlbWVudCIsImlzTGFzdFF1ZXJ5IiwiZHVja0RiQ29sdW1ucyIsImNvbHVtbnNUb0NvbnZlcnRUb1dLQiIsIl9hZGp1c3RlZFF1ZXJ5Iiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQiLCJwcmV2IiwicmVtb3ZlU1FMQ29tbWVudHMiLCJFcnJvciIsImFicnVwdCIsImdldER1Y2tEQiIsInNlbnQiLCJjb25uZWN0Iiwic3BsaXRTcWxTdGF0ZW1lbnRzIiwidDAiLCJjaGVja0lzU2VsZWN0UXVlcnkiLCJxdWVyeSIsImNvbmNhdCIsImdldER1Y2tEQkNvbHVtblR5cGVzIiwiZ2V0RHVja0RCQ29sdW1uVHlwZXNNYXAiLCJnZXRHZW9tZXRyeUNvbHVtbnMiLCJjb25zdHJ1Y3RTVF9hc1dLQlF1ZXJ5Iiwic2V0R2VvQXJyb3dXS0JFeHRlbnNpb24iLCJ0MSIsImZpbmlzaCIsInRhYmxlIiwiY2xvc2UiLCJ0MiIsIkRhdGUiLCJub3ciLCJzdG9wIiwib25DaGFuZ2UiLCJvbkFkZFJlc3VsdFRvTWFwIiwia2VwbGVyRmllbGRzIiwiYXJyb3dTY2hlbWFUb0ZpZWxkcyIsImRhdGFzZXRUb0FkZCIsImRhdGEiLCJmaWVsZHMiLCJyb3dzIiwiaW5mbyIsImlkIiwiZ2VuZXJhdGVIYXNoSWQiLCJsYWJlbCIsImZvcm1hdCIsImFkZERhdGFUb01hcCIsImRhdGFzZXRzIiwiaXNWYWxpZEZpbGVUeXBlIiwiZmlsZW5hbWUiLCJmaWxlRXh0IiwiU1VQUE9SVEVEX0RVQ0tEQl9EUk9QX0VYVEVOU0lPTlMiLCJmaW5kIiwiZXh0IiwiZW5kc1dpdGgiLCJCb29sZWFuIiwiY3JlYXRlVGFibGVGcm9tRHJvcHBlZEZpbGUiLCJfcmVmMyIsIl9jYWxsZWUyIiwiX2Vycm9yIiwiX2NhbGxlZTIkIiwiX2NvbnRleHQyIiwidGFibGVGcm9tRmlsZSIsIl94IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJoYW5kbGVGaWxlSW5wdXQiLCJmaWxlTGlzdCIsImV2ZW50IiwicHJldmVudERlZmF1bHQiLCJzdG9wUHJvcGFnYXRpb24iLCJmaWxlcyIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJmaWx0ZXIiLCJkaXNhYmxlRXh0ZW5zaW9uRmlsdGVyIiwiZmlsZXNUb0xvYWQiLCJlcnJvckZpbGVzIiwiX2l0ZXJhdG9yMiIsIl9zdGVwMiIsImZpbGUiLCJwdXNoIiwiZXJyIiwiam9pbiIsImNyZWF0ZUVsZW1lbnQiLCJQYW5lbEdyb3VwIiwiZGlyZWN0aW9uIiwiUGFuZWwiLCJkZWZhdWx0U2l6ZSIsIm1pblNpemUiLCJzdHlsZSIsImNsYXNzTmFtZSIsIm9uRHJhZ092ZXIiLCJvbkRyYWdMZWF2ZSIsImZyYW1lIiwiY3VycmVudCIsImRvY3VtZW50Iiwib25Ecm9wIiwiU2NoZW1hUGFuZWwiLCJJY29uQnV0dG9uIiwib25DbGljayIsImRpc2FibGVkIiwiSWNvbnMiLCJQbGF5IiwiaGVpZ2h0IiwiVG9vbHRpcCIsInBsYWNlIiwiZWZmZWN0IiwiaXNSZWFkT25seSIsIm9uUnVuUXVlcnkiLCJjb2RlIiwiTG9hZGluZ1NwaW5uZXIiLCJtZXNzYWdlIiwiQnV0dG9uIiwic2Vjb25kYXJ5IiwibnVtUm93cyIsIlByZXZpZXdEYXRhUGFuZWwiLCJkYXRhVGFibGVTdHlsZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL3NxbC1wYW5lbC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0ICogYXMgYXJyb3cgZnJvbSAnYXBhY2hlLWFycm93JztcbmltcG9ydCBSZWFjdCwge3VzZUNhbGxiYWNrLCB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWZ9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7dXNlRGlzcGF0Y2h9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtQYW5lbCwgUGFuZWxHcm91cCwgUGFuZWxSZXNpemVIYW5kbGV9IGZyb20gJ3JlYWN0LXJlc2l6YWJsZS1wYW5lbHMnO1xuXG5pbXBvcnQge2FkZERhdGFUb01hcH0gZnJvbSAnQGtlcGxlci5nbC9hY3Rpb25zJztcbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWR9IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7QnV0dG9uLCBGaWxlRHJvcCwgSWNvbkJ1dHRvbiwgSWNvbnMsIExvYWRpbmdTcGlubmVyLCBUb29sdGlwfSBmcm9tICdAa2VwbGVyLmdsL2NvbXBvbmVudHMnO1xuaW1wb3J0IHthcnJvd1NjaGVtYVRvRmllbGRzfSBmcm9tICdAa2VwbGVyLmdsL3Byb2Nlc3NvcnMnO1xuaW1wb3J0IHtzaWRlUGFuZWxCZywgcGFuZWxCb3JkZXJDb2xvcn0gZnJvbSAnQGtlcGxlci5nbC9zdHlsZXMnO1xuaW1wb3J0IHtpc0FwcGxlRGV2aWNlfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IE1vbmFjb0VkaXRvciBmcm9tICcuL21vbmFjby1lZGl0b3InO1xuaW1wb3J0IHtTY2hlbWFQYW5lbCwgU2NoZW1hU3VnZ2VzdGlvbn0gZnJvbSAnLi9zY2hlbWEtcGFuZWwnO1xuaW1wb3J0IHtQcmV2aWV3RGF0YVBhbmVsLCBRdWVyeVJlc3VsdH0gZnJvbSAnLi9wcmV2aWV3LWRhdGEtcGFuZWwnO1xuaW1wb3J0IHtnZXREdWNrREJ9IGZyb20gJy4uL2luaXQnO1xuaW1wb3J0IHtcbiAgY29uc3RydWN0U1RfYXNXS0JRdWVyeSxcbiAgZ2V0RHVja0RCQ29sdW1uVHlwZXMsXG4gIGdldER1Y2tEQkNvbHVtblR5cGVzTWFwLFxuICBnZXRHZW9tZXRyeUNvbHVtbnMsXG4gIHNldEdlb0Fycm93V0tCRXh0ZW5zaW9uLFxuICBzcGxpdFNxbFN0YXRlbWVudHMsXG4gIGNoZWNrSXNTZWxlY3RRdWVyeSxcbiAgcmVtb3ZlU1FMQ29tbWVudHMsXG4gIHRhYmxlRnJvbUZpbGUsXG4gIFNVUFBPUlRFRF9EVUNLREJfRFJPUF9FWFRFTlNJT05TXG59IGZyb20gJy4uL3RhYmxlL2R1Y2tkYi10YWJsZS11dGlscyc7XG5cbmNvbnN0IFN0eWxlZFNxbFBhbmVsID0gc3R5bGVkLmRpdmBcbiAgZGlzcGxheTogZmxleDtcbiAgaGVpZ2h0OiAxMDAlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAke3NpZGVQYW5lbEJnfTtcbiAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjMzMzO1xuYDtcblxuY29uc3QgU3R5bGVkU3FsQWN0aW9ucyA9IHN0eWxlZC5kaXZgXG4gIGZsZXg6IDAgMCA1MHB4O1xuICBkaXNwbGF5OiBmbGV4O1xuICBwYWRkaW5nLXRvcDogMTJweDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzMzMztcbmA7XG5cbmNvbnN0IFN0eWxlZFNxbEVkaXRvciA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGZsZXg6IDE7XG4gIG1pbi13aWR0aDogMDsgLy8gUHJldmVudHMgZmxleCBjaGlsZCBmcm9tIG92ZXJmbG93aW5nXG4gIGhlaWdodDogMTAwJTtcbmA7XG5cbmNvbnN0IFN0eWxlZEVkaXRvclBhbmVsID0gc3R5bGVkLmRpdmBcbiAgYmFja2dyb3VuZC1jb2xvcjogJHtzaWRlUGFuZWxCZ307XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGhlaWdodDogMTAwJTtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgZ2FwOiA1cHg7XG4gIGZsZXgtZ3JvdzogMTtcbmA7XG5cbmNvbnN0IFN0eWxlZERhdGFQYW5lbCA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGhlaWdodDogMTAwJTtcbiAgYmFja2dyb3VuZDogd2hpdGU7XG5gO1xuXG5jb25zdCBTdHlsZWRFZGl0b3IgPSBzdHlsZWQuZGl2PHtpc1J1bm5pbmc6IGJvb2xlYW59PmBcbiAgZGlzcGxheTogZmxleDtcbiAgcGFkZGluZzogMTJweCAxMnB4IDEycHggMDtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDMwLCAzMCwgMzApO1xuICBvcGFjaXR5OiAke3Byb3BzID0+IChwcm9wcy5pc1J1bm5pbmcgPyAwLjUgOiAxKX07XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIG1pbi1oZWlnaHQ6IDA7IC8vIFByZXZlbnRzIGZsZXggY2hpbGQgZnJvbSBvdmVyZmxvd2luZ1xuYDtcblxuY29uc3QgU3R5bGVkUmVzdWx0QWN0aW9ucyA9IHN0eWxlZC5kaXZgXG4gIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICBwYWRkaW5nOiAycHggMTJweDtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmb250LXNpemU6IDEycHg7XG5gO1xuXG5jb25zdCBTdHlsZWRSZXNpemVIYW5kbGUgPSBzdHlsZWQoUGFuZWxSZXNpemVIYW5kbGUpYFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAke3BhbmVsQm9yZGVyQ29sb3J9O1xuICB3aWR0aDogNHB4O1xuICBjdXJzb3I6IGNvbC1yZXNpemU7XG5cbiAgJjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogIzU1NTtcbiAgfVxuYDtcblxuY29uc3QgU3R5bGVkVmVydGljYWxSZXNpemVIYW5kbGUgPSBzdHlsZWQoUGFuZWxSZXNpemVIYW5kbGUpYFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAke3BhbmVsQm9yZGVyQ29sb3J9O1xuICBoZWlnaHQ6IDRweDtcbiAgY3Vyc29yOiByb3ctcmVzaXplO1xuXG4gICY6aG92ZXIge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICM1NTU7XG4gIH1cbmA7XG5cbmNvbnN0IFN0eWxlZExvYWRpbmdDb250YWluZXIgPSBzdHlsZWQuZGl2YFxuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgaGVpZ2h0OiAxMDAlO1xuYDtcblxuY29uc3QgU3R5bGVkRXJyb3JDb250YWluZXIgPSBzdHlsZWQucHJlYFxuICBwYWRkaW5nOiAxMnB4O1xuICBjb2xvcjogcmVkO1xuICBmb250LXNpemU6IDEycHg7XG4gIGJhY2tncm91bmQtY29sb3I6ICR7c2lkZVBhbmVsQmd9O1xuICBoZWlnaHQ6IDEwMCU7XG4gIG92ZXJmbG93OiBhdXRvO1xuYDtcblxuaW50ZXJmYWNlIFN0eWxlZERyYWdQYW5lbFByb3BzIHtcbiAgZHJhZ092ZXI/OiBib29sZWFuO1xufVxuXG5jb25zdCBTdHlsZWRGaWxlRHJvcEFyZWEgPSBzdHlsZWQoRmlsZURyb3ApPFN0eWxlZERyYWdQYW5lbFByb3BzPmBcbiAgaGVpZ2h0OiAxMDAlO1xuICBib3JkZXItd2lkdGg6IDFweDtcbiAgYm9yZGVyOiAxcHggJHtwcm9wcyA9PiAocHJvcHMuZHJhZ092ZXIgPyAnc29saWQnIDogJ2Rhc2hlZCcpfVxuICAgICR7cHJvcHMgPT4gKHByb3BzLmRyYWdPdmVyID8gcHJvcHMudGhlbWUuc3VidGV4dENvbG9yTFQgOiAndHJhbnNwYXJlbnQnKX07XG4gIC5maWxlLWRyb3AtdGFyZ2V0IHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gIH1cbmA7XG5cbnR5cGUgU3FsUGFuZWxQcm9wcyA9IHtcbiAgaW5pdGlhbFNxbD86IHN0cmluZztcbn07XG5cbmNvbnN0IFNDSEVNQV9QQU5FTF9TVFlMRSA9IHtvdmVyZmxvdzogJ2F1dG8nfTtcblxuZXhwb3J0IGNvbnN0IFNxbFBhbmVsOiBSZWFjdC5GQzxTcWxQYW5lbFByb3BzPiA9ICh7aW5pdGlhbFNxbCA9ICcnfSkgPT4ge1xuICBjb25zdCBbc3FsLCBzZXRTcWxdID0gdXNlU3RhdGUoKCkgPT4ge1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCk7XG4gICAgcmV0dXJuIHBhcmFtcy5nZXQoJ3NxbCcpIHx8IGluaXRpYWxTcWw7XG4gIH0pO1xuICBjb25zdCBbZHJvcHBlZEZpbGUsIHNldERyb3BwZWRGaWxlXSA9IHVzZVN0YXRlPEZpbGUgfCBudWxsPihudWxsKTtcbiAgY29uc3QgW2RyYWdTdGF0ZSwgc2V0RHJhZ1N0YXRlXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW3Jlc3VsdCwgc2V0UmVzdWx0XSA9IHVzZVN0YXRlPG51bGwgfCBRdWVyeVJlc3VsdD4obnVsbCk7XG4gIGNvbnN0IFtzY2hlbWFVcGRhdGVUcmlnZ2VyLCBzZXRTY2hlbWFVcGRhdGVUcmlnZ2VyXSA9IHVzZVN0YXRlPG51bWJlcj4oMCk7XG4gIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gdXNlU3RhdGU8RXJyb3IgfCBudWxsPihudWxsKTtcbiAgY29uc3QgW2NvdW50ZXIsIHNldENvdW50ZXJdID0gdXNlU3RhdGUoMCk7XG4gIGNvbnN0IFt0YWJsZVNjaGVtYSwgc2V0VGFibGVTY2hlbWFdID0gdXNlU3RhdGU8U2NoZW1hU3VnZ2VzdGlvbltdPihbXSk7XG4gIGNvbnN0IFtpc1J1bm5pbmcsIHNldElzUnVubmluZ10gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IFtpc01hY10gPSB1c2VTdGF0ZSgoKSA9PiBpc0FwcGxlRGV2aWNlKCkpO1xuICBjb25zdCBkaXNwYXRjaCA9IHVzZURpc3BhdGNoKCk7XG5cbiAgY29uc3QgZHJvcHBlZEZpbGVBcmVhUmVmID0gdXNlUmVmKG51bGwpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgY3VycmVudFVybCA9IG5ldyBVUkwod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuICAgIGlmIChzcWwpIHtcbiAgICAgIGN1cnJlbnRVcmwuc2VhcmNoUGFyYW1zLnNldCgnc3FsJywgc3FsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudFVybC5zZWFyY2hQYXJhbXMuZGVsZXRlKCdzcWwnKTtcbiAgICB9XG4gICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCAnJywgY3VycmVudFVybC50b1N0cmluZygpKTtcbiAgfSwgW3NxbF0pO1xuXG4gIGNvbnN0IHJ1blF1ZXJ5ID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIHNldElzUnVubmluZyh0cnVlKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWRqdXN0ZWRRdWVyeSA9IHNxbCA/IHJlbW92ZVNRTENvbW1lbnRzKHNxbCkgOiBudWxsO1xuICAgICAgaWYgKCFhZGp1c3RlZFF1ZXJ5KSB7XG4gICAgICAgIHNldEVycm9yKG5ldyBFcnJvcignUXVlcnkgaXMgZW1wdHknKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGIgPSBhd2FpdCBnZXREdWNrREIoKTtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCBkYi5jb25uZWN0KCk7XG5cbiAgICAgIC8vIFRPRE8gZmluZCBhIGNoZWFwIHdheSB0byBnZXQgRHVja0RiIHR5cGVzIHdpdGggYSBzaW5nbGUgcXVlcnkgdG8gYSByZW1vdGUgcmVzb3VyY2UgLSB0ZW1wIHRhYmxlPyBjdGU/XG4gICAgICBjb25zdCB0ZW1wVGFibGVOYW1lID0gJ3RlbXBfa2VwbGVyZ2xfdGFibGUnO1xuXG4gICAgICAvLyByZW1vdmUgY29tbWVudHNcbiAgICAgIGNvbnN0IHNxbFN0YXRlbWVudHMgPSBzcGxpdFNxbFN0YXRlbWVudHMoYWRqdXN0ZWRRdWVyeSk7XG5cbiAgICAgIGxldCBhcnJvd1Jlc3VsdDogYXJyb3cuVGFibGUgfCBudWxsID0gbnVsbDtcbiAgICAgIGxldCB0YWJsZUR1Y2tEQlR5cGVzID0ge307XG5cbiAgICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIHNxbFN0YXRlbWVudHMpIHtcbiAgICAgICAgY29uc3QgaXNMYXN0UXVlcnkgPSBzdGF0ZW1lbnQgPT09IHNxbFN0YXRlbWVudHNbc3FsU3RhdGVtZW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGlzTGFzdFF1ZXJ5ICYmIChhd2FpdCBjaGVja0lzU2VsZWN0UXVlcnkoY29ubmVjdGlvbiwgc3RhdGVtZW50KSkpIHtcbiAgICAgICAgICAvLyAxKSBjcmVhdGUgdGVtcCB0YWJsZSBmcm9tIHRoZSBvcmlnaW5hbCBxdWVyeS5cbiAgICAgICAgICBhd2FpdCBjb25uZWN0aW9uLnF1ZXJ5KGBDUkVBVEUgT1IgUkVQTEFDRSBUQUJMRSAnJHt0ZW1wVGFibGVOYW1lfScgQVMgJHtzdGF0ZW1lbnR9YCk7XG5cbiAgICAgICAgICAvLyAyKSBxdWVyeSBkdWNrZGIgdHlwZXMgYW5kIGRldGVjdCBjYW5kaWRhdGUgY29sdW1ucyBmb3IgU1RfYXNXS0IgdHJhbnNmb3JtLlxuICAgICAgICAgIGNvbnN0IGR1Y2tEYkNvbHVtbnMgPSBhd2FpdCBnZXREdWNrREJDb2x1bW5UeXBlcyhjb25uZWN0aW9uLCB0ZW1wVGFibGVOYW1lKTtcbiAgICAgICAgICB0YWJsZUR1Y2tEQlR5cGVzID0gZ2V0RHVja0RCQ29sdW1uVHlwZXNNYXAoZHVja0RiQ29sdW1ucyk7XG4gICAgICAgICAgY29uc3QgY29sdW1uc1RvQ29udmVydFRvV0tCID0gZ2V0R2VvbWV0cnlDb2x1bW5zKGR1Y2tEYkNvbHVtbnMpO1xuXG4gICAgICAgICAgLy8gMykgcXVlcnkgR0VPTUVUUlkgY29sdW1ucyBhcyBXS0IuXG4gICAgICAgICAgY29uc3QgYWRqdXN0ZWRRdWVyeSA9IGNvbnN0cnVjdFNUX2FzV0tCUXVlcnkodGVtcFRhYmxlTmFtZSwgY29sdW1uc1RvQ29udmVydFRvV0tCKTtcbiAgICAgICAgICBhcnJvd1Jlc3VsdCA9IGF3YWl0IGNvbm5lY3Rpb24ucXVlcnkoYWRqdXN0ZWRRdWVyeSk7XG5cbiAgICAgICAgICAvLyA0KSBzZXQgZ2VvYXJyb3cgZXh0ZW5zaW9uIGZvciB0aGUgYXJyb3cgdGFibGUgYXMgRHVja0RCIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgZ2VvYXJyb3cgZXh0ZW5zaW9uLlxuICAgICAgICAgIHNldEdlb0Fycm93V0tCRXh0ZW5zaW9uKGFycm93UmVzdWx0LCBkdWNrRGJDb2x1bW5zKTtcblxuICAgICAgICAgIC8vIDUpIHJlbW92ZSB0ZW1wIHRhYmxlXG4gICAgICAgICAgYXdhaXQgY29ubmVjdGlvbi5xdWVyeShgRFJPUCBUQUJMRSAke3RlbXBUYWJsZU5hbWV9O2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucXVlcnkoc3RhdGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTaG93IHByZXZpZXcgb25seSBmb3IgdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBxdWVyeVxuICAgICAgaWYgKGFycm93UmVzdWx0KSB7XG4gICAgICAgIHNldFJlc3VsdCh7dGFibGU6IGFycm93UmVzdWx0LCB0YWJsZUR1Y2tEQlR5cGVzfSk7XG4gICAgICAgIHNldEVycm9yKG51bGwpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBjb25uZWN0aW9uLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2V0RXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNldElzUnVubmluZyhmYWxzZSk7XG4gICAgfVxuXG4gICAgLy8gSW5kaWNhdGUgdGhhdCB0aGVyZSBtYXkgYmUgYSBwb3NzaWJsZSBjaGFuZ2UgaW4gRHVja0RCLlxuICAgIHNldFNjaGVtYVVwZGF0ZVRyaWdnZXIoRGF0ZS5ub3coKSk7XG4gIH0sIFtzcWxdKTtcblxuICBjb25zdCBvbkNoYW5nZSA9IHVzZUNhbGxiYWNrKFxuICAgIHZhbHVlID0+IHtcbiAgICAgIHNldFNxbCh2YWx1ZSk7XG4gICAgfSxcbiAgICBbc2V0U3FsXVxuICApO1xuXG4gIGNvbnN0IG9uQWRkUmVzdWx0VG9NYXAgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgaWYgKCFyZXN1bHQpIHJldHVybjtcblxuICAgIGNvbnN0IGtlcGxlckZpZWxkcyA9IGFycm93U2NoZW1hVG9GaWVsZHMocmVzdWx0LnRhYmxlLCByZXN1bHQudGFibGVEdWNrREJUeXBlcyk7XG5cbiAgICBjb25zdCBkYXRhc2V0VG9BZGQgPSB7XG4gICAgICBkYXRhOiB7XG4gICAgICAgIGZpZWxkczoga2VwbGVyRmllbGRzLFxuICAgICAgICAvLyBUT0RPIHR5cGUgQWRkRGF0YVRvTWFwUGF5bG9hZCAtPiByb3dzIC0+ICsgYXJyb3cuVGFibGVcbiAgICAgICAgcm93czogcmVzdWx0LnRhYmxlIGFzIGFueVxuICAgICAgfSxcbiAgICAgIGluZm86IHtcbiAgICAgICAgaWQ6IGdlbmVyYXRlSGFzaElkKCksXG4gICAgICAgIGxhYmVsOiBgcXVlcnlfcmVzdWx0JHtjb3VudGVyID4gMCA/IGBfJHtjb3VudGVyfWAgOiAnJ31gLFxuICAgICAgICBmb3JtYXQ6ICdhcnJvdydcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZGlzcGF0Y2goYWRkRGF0YVRvTWFwKHtkYXRhc2V0czogW2RhdGFzZXRUb0FkZF19KSk7XG4gICAgc2V0Q291bnRlcihjb3VudGVyICsgMSk7XG4gIH0sIFtyZXN1bHQsIGNvdW50ZXIsIGRpc3BhdGNoXSk7XG5cbiAgY29uc3QgaXNWYWxpZEZpbGVUeXBlID0gdXNlQ2FsbGJhY2soZmlsZW5hbWUgPT4ge1xuICAgIGNvbnN0IGZpbGVFeHQgPSBTVVBQT1JURURfRFVDS0RCX0RST1BfRVhURU5TSU9OUy5maW5kKGV4dCA9PiBmaWxlbmFtZS5lbmRzV2l0aChleHQpKTtcbiAgICByZXR1cm4gQm9vbGVhbihmaWxlRXh0KTtcbiAgfSwgW10pO1xuXG4gIGNvbnN0IGNyZWF0ZVRhYmxlRnJvbURyb3BwZWRGaWxlID0gdXNlQ2FsbGJhY2soYXN5bmMgKGRyb3BwZWRGaWxlOiBGaWxlIHwgbnVsbCkgPT4ge1xuICAgIGlmIChkcm9wcGVkRmlsZSkge1xuICAgICAgY29uc3QgZXJyb3IgPSBhd2FpdCB0YWJsZUZyb21GaWxlKGRyb3BwZWRGaWxlKTtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICBzZXRFcnJvcihlcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRFcnJvcihudWxsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXREcm9wcGVkRmlsZShudWxsKTtcbiAgICBzZXREcmFnU3RhdGUoZmFsc2UpO1xuICB9LCBbXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjcmVhdGVUYWJsZUZyb21Ecm9wcGVkRmlsZShkcm9wcGVkRmlsZSk7XG4gIH0sIFtkcm9wcGVkRmlsZSwgY3JlYXRlVGFibGVGcm9tRHJvcHBlZEZpbGVdKTtcblxuICBjb25zdCBoYW5kbGVGaWxlSW5wdXQgPSB1c2VDYWxsYmFjayhcbiAgICAoZmlsZUxpc3Q6IEZpbGVMaXN0LCBldmVudDogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVzID0gWy4uLmZpbGVMaXN0XS5maWx0ZXIoQm9vbGVhbik7XG5cbiAgICAgIGNvbnN0IGRpc2FibGVFeHRlbnNpb25GaWx0ZXIgPSBmYWxzZTtcblxuICAgICAgY29uc3QgZmlsZXNUb0xvYWQ6IEZpbGVbXSA9IFtdO1xuICAgICAgY29uc3QgZXJyb3JGaWxlczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICBpZiAoZGlzYWJsZUV4dGVuc2lvbkZpbHRlciB8fCBpc1ZhbGlkRmlsZVR5cGUoZmlsZS5uYW1lKSkge1xuICAgICAgICAgIGZpbGVzVG9Mb2FkLnB1c2goZmlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXJyb3JGaWxlcy5wdXNoKGZpbGUubmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZpbGVzVG9Mb2FkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2V0RHJvcHBlZEZpbGUoZmlsZXNUb0xvYWRbMF0pO1xuICAgICAgfSBlbHNlIGlmIChlcnJvckZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2V0RXJyb3IobmV3IEVycm9yKGBVbnN1cHBvcnRlZCBmaWxlIGZvcm1hdHM6ICR7ZXJyb3JGaWxlcy5qb2luKCcsICcpfWApKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtpc1ZhbGlkRmlsZVR5cGVdXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8U3R5bGVkU3FsUGFuZWw+XG4gICAgICA8UGFuZWxHcm91cCBkaXJlY3Rpb249XCJob3Jpem9udGFsXCI+XG4gICAgICAgIDxQYW5lbCBkZWZhdWx0U2l6ZT17MjB9IG1pblNpemU9ezE1fSBzdHlsZT17U0NIRU1BX1BBTkVMX1NUWUxFfSBjbGFzc05hbWU9XCJzY2hlbWEtcGFuZWxcIj5cbiAgICAgICAgICA8U3R5bGVkRmlsZURyb3BBcmVhXG4gICAgICAgICAgICBkcmFnT3Zlcj17ZHJhZ1N0YXRlfVxuICAgICAgICAgICAgb25EcmFnT3Zlcj17KCkgPT4gc2V0RHJhZ1N0YXRlKHRydWUpfVxuICAgICAgICAgICAgb25EcmFnTGVhdmU9eygpID0+IHNldERyYWdTdGF0ZShmYWxzZSl9XG4gICAgICAgICAgICBmcmFtZT17ZHJvcHBlZEZpbGVBcmVhUmVmLmN1cnJlbnQgfHwgZG9jdW1lbnR9XG4gICAgICAgICAgICBvbkRyb3A9e2hhbmRsZUZpbGVJbnB1dH1cbiAgICAgICAgICAgIGNsYXNzTmFtZT1cImZpbGUtdXBsb2FkZXJfX2ZpbGUtZHJvcFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPFNjaGVtYVBhbmVsXG4gICAgICAgICAgICAgIHNldFRhYmxlU2NoZW1hPXtzZXRUYWJsZVNjaGVtYX1cbiAgICAgICAgICAgICAgZHJvcHBlZEZpbGU9e2Ryb3BwZWRGaWxlfVxuICAgICAgICAgICAgICBzY2hlbWFVcGRhdGVUcmlnZ2VyPXtzY2hlbWFVcGRhdGVUcmlnZ2VyfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L1N0eWxlZEZpbGVEcm9wQXJlYT5cbiAgICAgICAgPC9QYW5lbD5cblxuICAgICAgICA8U3R5bGVkUmVzaXplSGFuZGxlIC8+XG5cbiAgICAgICAgPFBhbmVsIG1pblNpemU9ezQwfT5cbiAgICAgICAgICA8U3R5bGVkU3FsRWRpdG9yPlxuICAgICAgICAgICAgPFBhbmVsR3JvdXAgZGlyZWN0aW9uPVwidmVydGljYWxcIj5cbiAgICAgICAgICAgICAgPFBhbmVsIGRlZmF1bHRTaXplPXszMH0gY2xhc3NOYW1lPVwiZWRpdG9yLXBhbmVsXCI+XG4gICAgICAgICAgICAgICAgPFN0eWxlZEVkaXRvclBhbmVsPlxuICAgICAgICAgICAgICAgICAgPFN0eWxlZFNxbEFjdGlvbnM+XG4gICAgICAgICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgZGF0YS10aXBcbiAgICAgICAgICAgICAgICAgICAgICBkYXRhLWZvcj1cInJ1bi1xdWVyeS10b29sdGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXtydW5RdWVyeX1cbiAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17aXNSdW5uaW5nIHx8ICFzcWx9XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8SWNvbnMuUGxheSBoZWlnaHQ9XCIxOHB4XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBpZD1cInJ1bi1xdWVyeS10b29sdGlwXCIgcGxhY2U9XCJ0b3BcIiBlZmZlY3Q9XCJzb2xpZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUnVuIFF1ZXJ5ICh7aXNNYWMgPyAn4oyYRW50ZXInIDogJ0N0cmwrRW50ZXInfSBvciBTaGlmdCtFbnRlcilcbiAgICAgICAgICAgICAgICAgICAgICA8L1Rvb2x0aXA+XG4gICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDwvU3R5bGVkU3FsQWN0aW9ucz5cbiAgICAgICAgICAgICAgICAgIDxTdHlsZWRFZGl0b3IgaXNSdW5uaW5nPXtpc1J1bm5pbmd9PlxuICAgICAgICAgICAgICAgICAgICA8TW9uYWNvRWRpdG9yXG4gICAgICAgICAgICAgICAgICAgICAgaXNSZWFkT25seT17aXNSdW5uaW5nfVxuICAgICAgICAgICAgICAgICAgICAgIG9uUnVuUXVlcnk9e3J1blF1ZXJ5fVxuICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgICAgICAgICB0YWJsZVNjaGVtYT17dGFibGVTY2hlbWF9XG4gICAgICAgICAgICAgICAgICAgICAgY29kZT17c3FsfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgPC9TdHlsZWRFZGl0b3I+XG4gICAgICAgICAgICAgICAgPC9TdHlsZWRFZGl0b3JQYW5lbD5cbiAgICAgICAgICAgICAgPC9QYW5lbD5cblxuICAgICAgICAgICAgICA8U3R5bGVkVmVydGljYWxSZXNpemVIYW5kbGUgLz5cbiAgICAgICAgICAgICAgPFBhbmVsIGNsYXNzTmFtZT1cInByZXZpZXctcGFuZWxcIj5cbiAgICAgICAgICAgICAgICB7aXNSdW5uaW5nID8gKFxuICAgICAgICAgICAgICAgICAgPFN0eWxlZExvYWRpbmdDb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxMb2FkaW5nU3Bpbm5lciAvPlxuICAgICAgICAgICAgICAgICAgPC9TdHlsZWRMb2FkaW5nQ29udGFpbmVyPlxuICAgICAgICAgICAgICAgICkgOiBlcnJvciA/IChcbiAgICAgICAgICAgICAgICAgIDxTdHlsZWRFcnJvckNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdj57ZXJyb3IubWVzc2FnZX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvU3R5bGVkRXJyb3JDb250YWluZXI+XG4gICAgICAgICAgICAgICAgKSA6IHJlc3VsdCA/IChcbiAgICAgICAgICAgICAgICAgIDxTdHlsZWREYXRhUGFuZWw+XG4gICAgICAgICAgICAgICAgICAgIDxTdHlsZWRSZXN1bHRBY3Rpb25zPlxuICAgICAgICAgICAgICAgICAgICAgIDxCdXR0b24gc2Vjb25kYXJ5IG9uQ2xpY2s9e29uQWRkUmVzdWx0VG9NYXB9PlxuICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHRvIE1hcFxuICAgICAgICAgICAgICAgICAgICAgIDwvQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXY+e3Jlc3VsdC50YWJsZS5udW1Sb3dzfSByb3dzPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvU3R5bGVkUmVzdWx0QWN0aW9ucz5cbiAgICAgICAgICAgICAgICAgICAgPFByZXZpZXdEYXRhUGFuZWxcbiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ9e3Jlc3VsdH1cbiAgICAgICAgICAgICAgICAgICAgICBkYXRhVGFibGVTdHlsZT17e319XG4gICAgICAgICAgICAgICAgICAgICAgb25BZGRSZXN1bHRUb01hcD17b25BZGRSZXN1bHRUb01hcH1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDwvU3R5bGVkRGF0YVBhbmVsPlxuICAgICAgICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgICAgICA8L1BhbmVsPlxuICAgICAgICAgICAgPC9QYW5lbEdyb3VwPlxuICAgICAgICAgIDwvU3R5bGVkU3FsRWRpdG9yPlxuICAgICAgICA8L1BhbmVsPlxuICAgICAgPC9QYW5lbEdyb3VwPlxuICAgIDwvU3R5bGVkU3FsUGFuZWw+XG4gICk7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBSUEsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsV0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsaUJBQUEsR0FBQUMsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFJLHFCQUFBLEdBQUFKLE9BQUE7QUFFQSxJQUFBSyxRQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxZQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxXQUFBLEdBQUFQLE9BQUE7QUFDQSxJQUFBUSxXQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxPQUFBLEdBQUFULE9BQUE7QUFDQSxJQUFBVSxNQUFBLEdBQUFWLE9BQUE7QUFFQSxJQUFBVyxhQUFBLEdBQUFSLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBWSxZQUFBLEdBQUFaLE9BQUE7QUFDQSxJQUFBYSxpQkFBQSxHQUFBYixPQUFBO0FBQ0EsSUFBQWMsS0FB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