UNPKG

kepler.gl.geoiq

Version:

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

460 lines (374 loc) 60 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = ModalContainerFactory; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _styledComponents = require("styled-components"); var _reactDom = require("react-dom"); var _window = require("global/window"); var _modal = _interopRequireDefault(require("./common/modal")); var _dataProcessor = require("../processors/data-processor"); var _schemas = _interopRequireDefault(require("../schemas")); var _exportImageUtils = require("../utils/export-image-utils"); var _deleteDataModal = _interopRequireDefault(require("./modals/delete-data-modal")); var _dataTableModal = _interopRequireDefault(require("./modals/data-table-modal")); var _loadDataModal = _interopRequireDefault(require("./modals/load-data-modal")); var _loadExternalDataModal = _interopRequireDefault(require("./modals/load-external-data-modal")); var _exportImageModal = _interopRequireDefault(require("./modals/export-image-modal")); var _exportDataModal = _interopRequireDefault(require("./modals/export-data-modal")); var _exportMapModal = _interopRequireDefault(require("./modals/export-map-modal")); var _addMapStyleModal = _interopRequireDefault(require("./modals/add-map-style-modal")); var _mediaBreakpoints = require("../styles/media-breakpoints"); var _exportMapHtml = require("../templates/export-map-html"); var _defaultSettings = require("../constants/default-settings"); var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var DataTableModalStyle = (0, _styledComponents.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n top: 80px;\n padding: 32px 0 0 0;\n\n ", "\n\n ", "\n"])), _mediaBreakpoints.media.portable(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0;\n "]))), _mediaBreakpoints.media.palm(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0;\n margin: 0 auto;\n "])))); var DeleteDatasetModalStyled = (0, _styledComponents.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n width: 40%;\n padding: 40px 40px 32px 40px;\n"]))); var LoadDataModalStyle = (0, _styledComponents.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n top: 110px;\n"]))); ModalContainerFactory.deps = [_loadExternalDataModal["default"], _dataTableModal["default"], _deleteDataModal["default"], _loadDataModal["default"], _exportImageModal["default"], _exportDataModal["default"], _exportMapModal["default"], _addMapStyleModal["default"]]; function ModalContainerFactory(LoadExternalDataModal, DataTableModal, DeleteDatasetModal, LoadDataModal, ExportImageModal, ExportDataModal, ExportMapModal, AddMapStyleModal) { var ModalWrapper = /*#__PURE__*/function (_Component) { (0, _inherits2["default"])(ModalWrapper, _Component); var _super = _createSuper(ModalWrapper); function ModalWrapper() { var _this; (0, _classCallCheck2["default"])(this, ModalWrapper); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_closeModal", function () { _this.props.uiStateActions.toggleModal(null); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_deleteDataset", function (key) { _this.props.visStateActions.removeDataset(key); _this._closeModal(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onAddCustomMapStyle", function () { _this.props.mapStyleActions.addCustomMapStyle(); _this._closeModal(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onFileUpload", function (blob) { _this.props.visStateActions.loadFiles(blob); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportImage", function () { var _this$props$uiState$e = _this.props.uiState.exportImage, exporting = _this$props$uiState$e.exporting, imageDataUri = _this$props$uiState$e.imageDataUri; if (!exporting && imageDataUri) { var file = (0, _exportImageUtils.dataURItoBlob)(imageDataUri); (0, _exportImageUtils.downloadFile)(file, _defaultSettings.DEFAULT_EXPORT_IMAGE_NAME); } _this.props.uiStateActions.cleanupExportImage(); _this._closeModal(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportData", function () { var _this$props = _this.props, visState = _this$props.visState, uiState = _this$props.uiState; var datasets = visState.datasets; var _uiState$exportData = uiState.exportData, selectedDataset = _uiState$exportData.selectedDataset, dataType = _uiState$exportData.dataType, filtered = _uiState$exportData.filtered; // get the selected data var filename = 'geoiq.io'; var selectedDatasets = datasets[selectedDataset] ? [datasets[selectedDataset]] : Object.values(datasets); if (!selectedDatasets.length) { // error: selected dataset not found. _this._closeModal(); } selectedDatasets.forEach(function (selectedData) { var allData = selectedData.allData, data = selectedData.data, fields = selectedData.fields, label = selectedData.label, externalData = selectedData.externalData; var exportData = filtered ? data : allData; if (externalData && externalData === true) { return null; } // start to export data according to selected data type switch (dataType) { case _defaultSettings.EXPORT_DATA_TYPE.CSV: { var type = 'text/csv'; var csv = (0, _dataProcessor.formatCsv)(exportData, fields); _this._downloadFile(csv, type, "".concat(filename, "_").concat(label, ".csv")); break; } // TODO: support more file types. default: break; } }); _this._closeModal(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportJSONMap", function () { var uiState = _this.props.uiState; var hasData = uiState.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.JSON].hasData; // we pass all props because we avoid to create new variables var data = hasData ? _schemas["default"].save(_this.props) : _schemas["default"].getConfigToSave(_this.props); _this._downloadFile(JSON.stringify(data, null, 2), 'application/json', 'keplergl.json'); _this._closeModal(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportHTMLMap", function () { var uiState = _this.props.uiState; var _uiState$exportMap$EX = uiState.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.HTML], userMapboxToken = _uiState$exportMap$EX.userMapboxToken, exportMapboxAccessToken = _uiState$exportMap$EX.exportMapboxAccessToken, mode = _uiState$exportMap$EX.mode; var data = _objectSpread(_objectSpread({}, _schemas["default"].save(_this.props)), {}, { mapboxApiAccessToken: (userMapboxToken || '') !== '' ? userMapboxToken : exportMapboxAccessToken, mode: mode }); _this._downloadFile((0, _exportMapHtml.exportMapToHTML)(data), 'text/html', 'kepler.gl.html'); _this._closeModal(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onExportMap", function () { var _EXPORT_MAP_FORMATS$H; var uiState = _this.props.uiState; var format = uiState.exportMap.format; var downloader = (_EXPORT_MAP_FORMATS$H = {}, (0, _defineProperty2["default"])(_EXPORT_MAP_FORMATS$H, _defaultSettings.EXPORT_MAP_FORMATS.HTML, _this._onExportHTMLMap), (0, _defineProperty2["default"])(_EXPORT_MAP_FORMATS$H, _defaultSettings.EXPORT_MAP_FORMATS.JSON, _this._onExportJSONMap), _EXPORT_MAP_FORMATS$H)[format]; downloader && downloader(); }); return _this; } (0, _createClass2["default"])(ModalWrapper, [{ key: "_downloadFile", value: function _downloadFile(data, type, filename) { var fileBlob = new _window.Blob([data], { type: type }); (0, _exportImageUtils.downloadFile)(fileBlob, filename); } }, { key: "render", value: /* eslint-disable complexity */ function render() { var _this2 = this; var _this$props2 = this.props, containerW = _this$props2.containerW, containerH = _this$props2.containerH, mapStyle = _this$props2.mapStyle, mapState = _this$props2.mapState, uiState = _this$props2.uiState, visState = _this$props2.visState, rootNode = _this$props2.rootNode, visStateActions = _this$props2.visStateActions; var currentModal = uiState.currentModal, datasetKeyToRemove = uiState.datasetKeyToRemove; var datasets = visState.datasets, layers = visState.layers, editingDataset = visState.editingDataset; var exportDatasets = {}; var datasetKeys = Object.keys(datasets); datasetKeys.map(function (dk) { var externalData = datasets[dk].externalData; externalData && externalData === true ? null : exportDatasets = _objectSpread(_objectSpread({}, exportDatasets), {}, (0, _defineProperty2["default"])({}, dk, datasets[dk])); }); var template = null; var modalProps = {}; if (currentModal && currentModal.id && currentModal.template) { // if currentMdoal template is already provided // TODO: need to check whether template is valid template = /*#__PURE__*/_react["default"].createElement(currentModal.template, null); modalProps = currentModal.modalProps; } else { switch (currentModal) { case _defaultSettings.DATA_TABLE_ID: var width = containerW * 0.9; template = /*#__PURE__*/_react["default"].createElement(DataTableModal, { width: containerW * 0.9, height: containerH * 0.85, datasets: datasets, dataId: editingDataset, showDatasetTable: visStateActions.showDatasetTable }); // TODO: we need to make this width consistent with the css rule defined modal.js:32 max-width: 70vw modalProps.cssStyle = (0, _styledComponents.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n ", ";\n ", "\n "])), DataTableModalStyle, _mediaBreakpoints.media.palm(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n width: ", "px;\n "])), width)); break; case _defaultSettings.ADD_EXTERNAL_DATA_ID: template = /*#__PURE__*/_react["default"].createElement(LoadExternalDataModal, null); modalProps = { title: 'Add External Data To Map', footer: false // confirmButton: { // large: true, // children: 'Add External Dataset' // } }; break; case _defaultSettings.DELETE_DATA_ID: // validate options if (datasetKeyToRemove && datasets && datasets[datasetKeyToRemove]) { template = /*#__PURE__*/_react["default"].createElement(DeleteDatasetModal, { dataset: datasets[datasetKeyToRemove], layers: layers }); modalProps = { title: 'Delete Dataset', cssStyle: DeleteDatasetModalStyled, footer: true, onConfirm: function onConfirm() { return _this2._deleteDataset(datasetKeyToRemove); }, onCancel: this._closeModal, confirmButton: { negative: true, large: true, children: 'Delete' } }; } break; // in case we add a new case after this one case _defaultSettings.ADD_DATA_ID: template = /*#__PURE__*/_react["default"].createElement(LoadDataModal, (0, _extends2["default"])({ onClose: this._closeModal, onFileUpload: this._onFileUpload }, uiState.loadFiles)); modalProps = { title: 'Add Data From Datahub', cssStyle: LoadDataModalStyle, footer: false, onConfirm: this._closeModal }; break; case _defaultSettings.EXPORT_IMAGE_ID: template = /*#__PURE__*/_react["default"].createElement(ExportImageModal, (0, _extends2["default"])({}, uiState.exportImage, { width: containerW, height: containerH, onChangeRatio: this.props.uiStateActions.setRatio, onChangeResolution: this.props.uiStateActions.setResolution, onToggleLegend: this.props.uiStateActions.toggleLegend })); modalProps = { close: false, title: 'Export Image', footer: true, onCancel: this._closeModal, onConfirm: this._onExportImage, confirmButton: { large: true, disabled: uiState.exportImage.exporting, children: 'Download' } }; break; case _defaultSettings.EXPORT_DATA_ID: template = /*#__PURE__*/_react["default"].createElement(ExportDataModal, (0, _extends2["default"])({}, uiState.exportData, { datasets: exportDatasets, onClose: this._closeModal, onChangeExportDataType: this.props.uiStateActions.setExportDataType, onChangeExportSelectedDataset: this.props.uiStateActions.setExportSelectedDataset, onChangeExportFiltered: this.props.uiStateActions.setExportFiltered })); modalProps = { close: false, title: 'Export Data', footer: true, onCancel: this._closeModal, onConfirm: this._onExportData, confirmButton: { large: true, children: 'Export' } }; break; case _defaultSettings.EXPORT_MAP_ID: var keplerGlConfig = _schemas["default"].getConfigToSave({ mapStyle: mapStyle, visState: visState, mapState: mapState, uiState: uiState }); template = /*#__PURE__*/_react["default"].createElement(ExportMapModal, { config: keplerGlConfig, options: uiState.exportMap, onChangeExportMapFormat: this.props.uiStateActions.setExportMapFormat, onEditUserMapboxAccessToken: this.props.uiStateActions.setUserMapboxAccessToken, onChangeExportMapHTMLMode: this.props.uiStateActions.setExportHTMLMapMode }); modalProps = { close: false, title: 'Export Map', footer: true, onCancel: this._closeModal, onConfirm: this._onExportMap, confirmButton: { large: true, children: 'Export' } }; break; case _defaultSettings.ADD_MAP_STYLE_ID: template = /*#__PURE__*/_react["default"].createElement(AddMapStyleModal, { mapboxApiAccessToken: this.props.mapboxApiAccessToken, mapboxApiUrl: this.props.mapboxApiUrl, mapState: this.props.mapState, inputStyle: mapStyle.inputStyle, inputMapStyle: this.props.mapStyleActions.inputMapStyle, loadCustomMapStyle: this.props.mapStyleActions.loadCustomMapStyle }); modalProps = { close: false, title: 'Add Custom Mapbox Style', footer: true, onCancel: this._closeModal, onConfirm: this._onAddCustomMapStyle, confirmButton: { large: true, disabled: !mapStyle.inputStyle.style, children: 'Add Style' } }; break; default: break; } } return this.props.rootNode ? /*#__PURE__*/_react["default"].createElement(_modal["default"], (0, _extends2["default"])({}, modalProps, { parentSelector: function parentSelector() { return (0, _reactDom.findDOMNode)(rootNode); }, isOpen: Boolean(currentModal), close: this._closeModal }), template) : null; } /* eslint-enable complexity */ }]); return ModalWrapper; }(_react.Component); (0, _defineProperty2["default"])(ModalWrapper, "propTypes", { rootNode: _propTypes["default"].object, containerW: _propTypes["default"].number, containerH: _propTypes["default"].number, mapboxApiAccessToken: _propTypes["default"].string.isRequired, mapboxApiUrl: _propTypes["default"].string, mapState: _propTypes["default"].object.isRequired, mapStyle: _propTypes["default"].object.isRequired, uiState: _propTypes["default"].object.isRequired, visState: _propTypes["default"].object.isRequired, visStateActions: _propTypes["default"].object.isRequired, uiStateActions: _propTypes["default"].object.isRequired, mapStyleActions: _propTypes["default"].object.isRequired }); return ModalWrapper; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL21vZGFsLWNvbnRhaW5lci5qcyJdLCJuYW1lcyI6WyJEYXRhVGFibGVNb2RhbFN0eWxlIiwiY3NzIiwibWVkaWEiLCJwb3J0YWJsZSIsInBhbG0iLCJEZWxldGVEYXRhc2V0TW9kYWxTdHlsZWQiLCJMb2FkRGF0YU1vZGFsU3R5bGUiLCJNb2RhbENvbnRhaW5lckZhY3RvcnkiLCJkZXBzIiwiTG9hZEV4dGVybmFsRGF0YU1vZGFsRmFjdG9yeSIsIkRhdGFUYWJsZU1vZGFsRmFjdG9yeSIsIkRlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnkiLCJMb2FkRGF0YU1vZGFsRmFjdG9yeSIsIkV4cG9ydEltYWdlTW9kYWxGYWN0b3J5IiwiRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSIsIkV4cG9ydE1hcE1vZGFsRmFjdG9yeSIsIkFkZE1hcFN0eWxlTW9kYWxGYWN0b3J5IiwiTG9hZEV4dGVybmFsRGF0YU1vZGFsIiwiRGF0YVRhYmxlTW9kYWwiLCJEZWxldGVEYXRhc2V0TW9kYWwiLCJMb2FkRGF0YU1vZGFsIiwiRXhwb3J0SW1hZ2VNb2RhbCIsIkV4cG9ydERhdGFNb2RhbCIsIkV4cG9ydE1hcE1vZGFsIiwiQWRkTWFwU3R5bGVNb2RhbCIsIk1vZGFsV3JhcHBlciIsInByb3BzIiwidWlTdGF0ZUFjdGlvbnMiLCJ0b2dnbGVNb2RhbCIsImtleSIsInZpc1N0YXRlQWN0aW9ucyIsInJlbW92ZURhdGFzZXQiLCJfY2xvc2VNb2RhbCIsIm1hcFN0eWxlQWN0aW9ucyIsImFkZEN1c3RvbU1hcFN0eWxlIiwiYmxvYiIsImxvYWRGaWxlcyIsInVpU3RhdGUiLCJleHBvcnRJbWFnZSIsImV4cG9ydGluZyIsImltYWdlRGF0YVVyaSIsImZpbGUiLCJERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FIiwiY2xlYW51cEV4cG9ydEltYWdlIiwidmlzU3RhdGUiLCJkYXRhc2V0cyIsImV4cG9ydERhdGEiLCJzZWxlY3RlZERhdGFzZXQiLCJkYXRhVHlwZSIsImZpbHRlcmVkIiwiZmlsZW5hbWUiLCJzZWxlY3RlZERhdGFzZXRzIiwiT2JqZWN0IiwidmFsdWVzIiwibGVuZ3RoIiwiZm9yRWFjaCIsInNlbGVjdGVkRGF0YSIsImFsbERhdGEiLCJkYXRhIiwiZmllbGRzIiwibGFiZWwiLCJleHRlcm5hbERhdGEiLCJFWFBPUlRfREFUQV9UWVBFIiwiQ1NWIiwidHlwZSIsImNzdiIsIl9kb3dubG9hZEZpbGUiLCJoYXNEYXRhIiwiZXhwb3J0TWFwIiwiRVhQT1JUX01BUF9GT1JNQVRTIiwiSlNPTiIsIktlcGxlckdsU2NoZW1hIiwic2F2ZSIsImdldENvbmZpZ1RvU2F2ZSIsInN0cmluZ2lmeSIsIkhUTUwiLCJ1c2VyTWFwYm94VG9rZW4iLCJleHBvcnRNYXBib3hBY2Nlc3NUb2tlbiIsIm1vZGUiLCJtYXBib3hBcGlBY2Nlc3NUb2tlbiIsImZvcm1hdCIsImRvd25sb2FkZXIiLCJfb25FeHBvcnRIVE1MTWFwIiwiX29uRXhwb3J0SlNPTk1hcCIsImZpbGVCbG9iIiwiQmxvYiIsImNvbnRhaW5lclciLCJjb250YWluZXJIIiwibWFwU3R5bGUiLCJtYXBTdGF0ZSIsInJvb3ROb2RlIiwiY3VycmVudE1vZGFsIiwiZGF0YXNldEtleVRvUmVtb3ZlIiwibGF5ZXJzIiwiZWRpdGluZ0RhdGFzZXQiLCJleHBvcnREYXRhc2V0cyIsImRhdGFzZXRLZXlzIiwia2V5cyIsIm1hcCIsImRrIiwidGVtcGxhdGUiLCJtb2RhbFByb3BzIiwiaWQiLCJEQVRBX1RBQkxFX0lEIiwid2lkdGgiLCJzaG93RGF0YXNldFRhYmxlIiwiY3NzU3R5bGUiLCJBRERfRVhURVJOQUxfREFUQV9JRCIsInRpdGxlIiwiZm9vdGVyIiwiREVMRVRFX0RBVEFfSUQiLCJvbkNvbmZpcm0iLCJfZGVsZXRlRGF0YXNldCIsIm9uQ2FuY2VsIiwiY29uZmlybUJ1dHRvbiIsIm5lZ2F0aXZlIiwibGFyZ2UiLCJjaGlsZHJlbiIsIkFERF9EQVRBX0lEIiwiX29uRmlsZVVwbG9hZCIsIkVYUE9SVF9JTUFHRV9JRCIsInNldFJhdGlvIiwic2V0UmVzb2x1dGlvbiIsInRvZ2dsZUxlZ2VuZCIsImNsb3NlIiwiX29uRXhwb3J0SW1hZ2UiLCJkaXNhYmxlZCIsIkVYUE9SVF9EQVRBX0lEIiwic2V0RXhwb3J0RGF0YVR5cGUiLCJzZXRFeHBvcnRTZWxlY3RlZERhdGFzZXQiLCJzZXRFeHBvcnRGaWx0ZXJlZCIsIl9vbkV4cG9ydERhdGEiLCJFWFBPUlRfTUFQX0lEIiwia2VwbGVyR2xDb25maWciLCJzZXRFeHBvcnRNYXBGb3JtYXQiLCJzZXRVc2VyTWFwYm94QWNjZXNzVG9rZW4iLCJzZXRFeHBvcnRIVE1MTWFwTW9kZSIsIl9vbkV4cG9ydE1hcCIsIkFERF9NQVBfU1RZTEVfSUQiLCJtYXBib3hBcGlVcmwiLCJpbnB1dFN0eWxlIiwiaW5wdXRNYXBTdHlsZSIsImxvYWRDdXN0b21NYXBTdHlsZSIsIl9vbkFkZEN1c3RvbU1hcFN0eWxlIiwic3R5bGUiLCJCb29sZWFuIiwiQ29tcG9uZW50IiwiUHJvcFR5cGVzIiwib2JqZWN0IiwibnVtYmVyIiwic3RyaW5nIiwiaXNSZXF1aXJlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0E7O0FBR0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjQSxJQUFNQSxtQkFBbUIsT0FBR0MscUJBQUgsb0pBSXJCQyx3QkFBTUMsUUFKZSwrR0FRckJELHdCQUFNRSxJQVJlLG1JQUF6QjtBQWNBLElBQU1DLHdCQUF3QixPQUFHSixxQkFBSCwySUFBOUI7QUFLQSxJQUFNSyxrQkFBa0IsT0FBR0wscUJBQUgsMEdBQXhCO0FBSUFNLHFCQUFxQixDQUFDQyxJQUF0QixHQUE2QixDQUMzQkMsaUNBRDJCLEVBRTNCQywwQkFGMkIsRUFHM0JDLDJCQUgyQixFQUkzQkMs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VUQ7QUFDRDs7QUF0WEY7QUFBQTtBQUFBLElBQzJCOEMsZ0JBRDNCOztBQUFBLG1DQUNNekgsWUFETixlQUVxQjtBQUNqQmlFLElBQUFBLFFBQVEsRUFBRXlELHNCQUFVQyxNQURIO0FBRWpCOUQsSUFBQUEsVUFBVSxFQUFFNkQsc0JBQVVFLE1BRkw7QUFHakI5RCxJQUFBQSxVQUFVLEVBQUU0RCxzQkFBVUUsTUFITDtBQUlqQnRFLElBQUFBLG9CQUFvQixFQUFFb0Usc0JBQVVHLE1BQVYsQ0FBaUJDLFVBSnRCO0FBS2pCWixJQUFBQSxZQUFZLEVBQUVRLHNCQUFVRyxNQUxQO0FBTWpCN0QsSUFBQUEsUUFBUSxFQUFFMEQsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBTlY7QUFPakIvRCxJQUFBQSxRQUFRLEVBQUUyRCxzQkFBVUMsTUFBVixDQUFpQkcsVUFQVjtBQVFqQmxILElBQUFBLE9BQU8sRUFBRThHLHNCQUFVQyxNQUFWLENBQWlCRyxVQVJUO0FBU2pCM0csSUFBQUEsUUFBUSxFQUFFdUcsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBVFY7QUFVakJ6SCxJQUFBQSxlQUFlLEVBQUVxSCxzQkFBVUMsTUFBVixDQUFpQkcsVUFWakI7QUFXakI1SCxJQUFBQSxjQUFjLEVBQUV3SCxzQkFBVUMsTUFBVixDQUFpQkcsVUFYaEI7QUFZakJ0SCxJQUFBQSxlQUFlLEVBQUVrSCxzQkFBVUMsTUFBVixDQUFpQkc7QUFaakIsR0FGckI7QUF5WEEsU0FBTzlILFlBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCB7Y3NzfSBmcm9tICdzdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQge2ZpbmRET01Ob2RlfSBmcm9tICdyZWFjdC1kb20nO1xuaW1wb3J0IHtCbG9ifSBmcm9tICdnbG9iYWwvd2luZG93JztcblxuaW1wb3J0IE1vZGFsRGlhbG9nIGZyb20gJy4vY29tbW9uL21vZGFsJztcbmltcG9ydCB7Zm9ybWF0Q3N2fSBmcm9tICdwcm9jZXNzb3JzL2RhdGEtcHJvY2Vzc29yJztcbmltcG9ydCBLZXBsZXJHbFNjaGVtYSBmcm9tICdzY2hlbWFzJztcbmltcG9ydCB7ZG93bmxvYWRGaWxlLCBkYXRhVVJJdG9CbG9ifSBmcm9tICd1dGlscy9leHBvcnQtaW1hZ2UtdXRpbHMnO1xuLy8gbW9kYWxzXG5pbXBvcnQgRGVsZXRlRGF0YXNldE1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9kZWxldGUtZGF0YS1tb2RhbCc7XG5pbXBvcnQgRGF0YVRhYmxlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2RhdGEtdGFibGUtbW9kYWwnO1xuaW1wb3J0IExvYWREYXRhTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2xvYWQtZGF0YS1tb2RhbCc7XG5pbXBvcnQgTG9hZEV4dGVybmFsRGF0YU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9sb2FkLWV4dGVybmFsLWRhdGEtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydEltYWdlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2V4cG9ydC1pbWFnZS1tb2RhbCc7XG5pbXBvcnQgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtZGF0YS1tb2RhbCc7XG5pbXBvcnQgRXhwb3J0TWFwTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2V4cG9ydC1tYXAtbW9kYWwnO1xuaW1wb3J0IEFkZE1hcFN0eWxlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2FkZC1tYXAtc3R5bGUtbW9kYWwnO1xuXG4vLyBCcmVha3BvaW50c1xuaW1wb3J0IHttZWRpYX0gZnJvbSAnc3R5bGVzL21lZGlhLWJyZWFrcG9pbnRzJztcblxuLy8gVGVtcGxhdGVcbmltcG9ydCB7ZXhwb3J0TWFwVG9IVE1MfSBmcm9tICd0ZW1wbGF0ZXMvZXhwb3J0LW1hcC1odG1sJztcbmltcG9ydCB7XG4gIEFERF9EQVRBX0lELFxuICBEQVRBX1RBQkxFX0lELFxuICBERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FLFxuICBERUxFVEVfREFUQV9JRCxcbiAgRVhQT1JUX0RBVEFfSUQsXG4gIEVYUE9SVF9EQVRBX1RZUEUsXG4gIEVYUE9SVF9JTUFHRV9JRCxcbiAgRVhQT1JUX01BUF9JRCxcbiAgQUREX01BUF9TVFlMRV9JRCxcbiAgQUREX0VYVEVSTkFMX0RBVEFfSURcbn0gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuaW1wb3J0IHtFWFBPUlRfTUFQX0ZPUk1BVFN9IGZyb20gJy4uL2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcblxuY29uc3QgRGF0YVRhYmxlTW9kYWxTdHlsZSA9IGNzc2BcbiAgdG9wOiA4MHB4O1xuICBwYWRkaW5nOiAzMnB4IDAgMCAwO1xuXG4gICR7bWVkaWEucG9ydGFibGVgXG4gICAgcGFkZGluZzogMDtcbiAgYH1cblxuICAke21lZGlhLnBhbG1gXG4gICAgcGFkZGluZzogMDtcbiAgICBtYXJnaW46IDAgYXV0bztcbiAgYH1cbmA7XG5cbmNvbnN0IERlbGV0ZURhdGFzZXRNb2RhbFN0eWxlZCA9IGNzc2BcbiAgd2lkdGg6IDQwJTtcbiAgcGFkZGluZzogNDBweCA0MHB4IDMycHggNDBweDtcbmA7XG5cbmNvbnN0IExvYWREYXRhTW9kYWxTdHlsZSA9IGNzc2BcbiAgdG9wOiAxMTBweDtcbmA7XG5cbk1vZGFsQ29udGFpbmVyRmFjdG9yeS5kZXBzID0gW1xuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWxGYWN0b3J5LFxuICBEYXRhVGFibGVNb2RhbEZhY3RvcnksXG4gIERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnksXG4gIExvYWREYXRhTW9kYWxGYWN0b3J5LFxuICBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0TWFwTW9kYWxGYWN0b3J5LFxuICBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeVxuXTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kYWxDb250YWluZXJGYWN0b3J5KFxuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWwsXG4gIERhdGFUYWJsZU1vZGFsLFxuICBEZWxldGVEYXRhc2V0TW9kYWwsXG4gIExvYWREYXRhTW9kYWwsXG4gIEV4cG9ydEltYWdlTW9kYWwsXG4gIEV4cG9ydERhdGFNb2RhbCxcbiAgRXhwb3J0TWFwTW9kYWwsXG4gIEFkZE1hcFN0eWxlTW9kYWxcbikge1xuICBjbGFzcyBNb2RhbFdyYXBwZXIgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICByb290Tm9kZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgIGNvbnRhaW5lclc6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgICBjb250YWluZXJIOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgICAgbWFwYm94QXBpQWNjZXNzVG9rZW46IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgIG1hcGJveEFwaVVybDogUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgIG1hcFN0YXRlOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBTdHlsZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdmlzU3RhdGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIHZpc1N0YXRlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZUFjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0eWxlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG4gICAgfTtcblxuICAgIF9jbG9zZU1vZGFsID0gKCkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy50b2dnbGVNb2RhbChudWxsKTtcbiAgICB9O1xuXG4gICAgX2RlbGV0ZURhdGFzZXQgPSBrZXkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy52aXNTdGF0ZUFjdGlvbnMucmVtb3ZlRGF0YXNldChrZXkpO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfb25BZGRDdXN0b21NYXBTdHlsZSA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvcHMubWFwU3R5bGVBY3Rpb25zLmFkZEN1c3RvbU1hcFN0eWxlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkZpbGVVcGxvYWQgPSBibG9iID0+IHtcbiAgICAgIHRoaXMucHJvcHMudmlzU3RhdGVBY3Rpb25zLmxvYWRGaWxlcyhibG9iKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0SW1hZ2UgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7ZXhwb3J0aW5nLCBpbWFnZURhdGFVcml9ID0gdGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydEltYWdlO1xuICAgICAgaWYgKCFleHBvcnRpbmcgJiYgaW1hZ2VEYXRhVXJpKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBkYXRhVVJJdG9CbG9iKGltYWdlRGF0YVVyaSk7XG4gICAgICAgIGRvd25sb2FkRmlsZShmaWxlLCBERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMuY2xlYW51cEV4cG9ydEltYWdlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9kb3dubG9hZEZpbGUoZGF0YSwgdHlwZSwgZmlsZW5hbWUpIHtcbiAgICAgIGNvbnN0IGZpbGVCbG9iID0gbmV3IEJsb2IoW2RhdGFdLCB7dHlwZX0pO1xuICAgICAgZG93bmxvYWRGaWxlKGZpbGVCbG9iLCBmaWxlbmFtZSk7XG4gICAgfVxuXG4gICAgX29uRXhwb3J0RGF0YSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHt2aXNTdGF0ZSwgdWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2RhdGFzZXRzfSA9IHZpc1N0YXRlO1xuICAgICAgY29uc3Qge3NlbGVjdGVkRGF0YXNldCwgZGF0YVR5cGUsIGZpbHRlcmVkfSA9IHVpU3RhdGUuZXhwb3J0RGF0YTtcbiAgICAgIC8vIGdldCB0aGUgc2VsZWN0ZWQgZGF0YVxuICAgICAgY29uc3QgZmlsZW5hbWUgPSAnZ2VvaXEuaW8nO1xuICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhc2V0cyA9IGRhdGFzZXRzW3NlbGVjdGVkRGF0YXNldF1cbiAgICAgICAgPyBbZGF0YXNldHNbc2VsZWN0ZWREYXRhc2V0XV1cbiAgICAgICAgOiBPYmplY3QudmFsdWVzKGRhdGFzZXRzKTtcbiAgICAgIGlmICghc2VsZWN0ZWREYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gZXJyb3I6IHNlbGVjdGVkIGRhdGFzZXQgbm90IGZvdW5kLlxuICAgICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgICB9XG5cbiAgICAgIHNlbGVjdGVkRGF0YXNldHMuZm9yRWFjaChzZWxlY3RlZERhdGEgPT4ge1xuICAgICAgICBjb25zdCB7YWxsRGF0YSwgZGF0YSwgZmllbGRzLCBsYWJlbCwgZXh0ZXJuYWxEYXRhfSA9IHNlbGVjdGVkRGF0YTtcbiAgICAgICAgY29uc3QgZXhwb3J0RGF0YSA9IGZpbHRlcmVkID8gZGF0YSA6IGFsbERhdGE7XG4gICAgICAgIGlmIChleHRlcm5hbERhdGEgJiYgZXh0ZXJuYWxEYXRhID09PSB0cnVlKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RhcnQgdG8gZXhwb3J0IGRhdGEgYWNjb3JkaW5nIHRvIHNlbGVjdGVkIGRhdGEgdHlwZVxuICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICAgICAgY2FzZSBFWFBPUlRfREFUQV9UWVBFLkNTVjoge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9ICd0ZXh0L2Nzdic7XG4gICAgICAgICAgICBjb25zdCBjc3YgPSBmb3JtYXRDc3YoZXhwb3J0RGF0YSwgZmllbGRzKTtcbiAgICAgICAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShjc3YsIHR5cGUsIGAke2ZpbGVuYW1lfV8ke2xhYmVsfS5jc3ZgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IG1vcmUgZmlsZSB0eXBlcy5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydEpTT05NYXAgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7dWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2hhc0RhdGF9ID0gdWlTdGF0ZS5leHBvcnRNYXBbRVhQT1JUX01BUF9GT1JNQVRTLkpTT05dO1xuXG4gICAgICAvLyB3ZSBwYXNzIGFsbCBwcm9wcyBiZWNhdXNlIHdlIGF2b2lkIHRvIGNyZWF0ZSBuZXcgdmFyaWFibGVzXG4gICAgICBjb25zdCBkYXRhID0gaGFzRGF0YVxuICAgICAgICA/IEtlcGxlckdsU2NoZW1hLnNhdmUodGhpcy5wcm9wcylcbiAgICAgICAgOiBLZXBsZXJHbFNjaGVtYS5nZXRDb25maWdUb1NhdmUodGhpcy5wcm9wcyk7XG5cbiAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMiksXG4gICAgICAgICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ2tlcGxlcmdsLmpzb24nXG4gICAgICApO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydEhUTUxNYXAgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7dWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge1xuICAgICAgICB1c2VyTWFwYm94VG9rZW4sXG4gICAgICAgIGV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuLFxuICAgICAgICBtb2RlXG4gICAgICB9ID0gdWlTdGF0ZS5leHBvcnRNYXBbRVhQT1JUX01BUF9GT1JNQVRTLkhUTUxdO1xuXG4gICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAuLi5LZXBsZXJHbFNjaGVtYS5zYXZlKHRoaXMucHJvcHMpLFxuICAgICAgICBtYXBib3hBcGlBY2Nlc3NUb2tlbjpcbiAgICAgICAgICAodXNlck1hcGJveFRva2VuIHx8ICcnKSAhPT0gJydcbiAgICAgICAgICAgID8gdXNlck1hcGJveFRva2VuXG4gICAgICAgICAgICA6IGV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuLFxuICAgICAgICBtb2RlXG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9kb3dubG9hZEZpbGUoZXhwb3J0TWFwVG9IVE1MKGRhdGEpLCAndGV4dC9odG1sJywgJ2tlcGxlci5nbC5odG1sJyk7XG5cbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0TWFwID0gKCkgPT4ge1xuICAgICAgY29uc3Qge3VpU3RhdGV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtmb3JtYXR9ID0gdWlTdGF0ZS5leHBvcnRNYXA7XG5cbiAgICAgIGNvbnN0IGRvd25sb2FkZXIgPSB7XG4gICAgICAgIFtFWFBPUlRfTUFQX0ZPUk1BVFMuSFRNTF06IHRoaXMuX29uRXhwb3J0SFRNTE1hcCxcbiAgICAgICAgW0VYUE9SVF9NQVBfRk9STUFUUy5KU09OXTogdGhpcy5fb25FeHBvcnRKU09OTWFwXG4gICAgICB9W2Zvcm1hdF07XG5cbiAgICAgIGRvd25sb2FkZXIgJiYgZG93bmxvYWRlcigpO1xuICAgIH07XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG4gICAgcmVuZGVyKCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBjb250YWluZXJXLFxuICAgICAgICBjb250YWluZXJILFxuICAgICAgICBtYXBTdHlsZSxcbiAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgIHVpU3RhdGUsXG4gICAgICAgIHZpc1N0YXRlLFxuICAgICAgICByb290Tm9kZSxcbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zXG4gICAgICB9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtjdXJyZW50TW9kYWwsIGRhdGFzZXRLZXlUb1JlbW92ZX0gPSB1aVN0YXRlO1xuICAgICAgY29uc3Qge2RhdGFzZXRzLCBsYXllcnMsIGVkaXRpbmdEYXRhc2V0fSA9IHZpc1N0YXRlO1xuICAgICAgdmFyIGV4cG9ydERhdGFzZXRzID0ge307XG4gICAgICBjb25zdCBkYXRhc2V0S2V5cyA9IE9iamVjdC5rZXlzKGRhdGFzZXRzKTtcbiAgICAgIGRhdGFzZXRLZXlzLm1hcChkayA9PiB7XG4gICAgICAgIGNvbnN0IGV4dGVybmFsRGF0YSA9IGRhdGFzZXRzW2RrXS5leHRlcm5hbERhdGE7XG4gICAgICA