UNPKG

kepler.gl.geoiq

Version:

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

474 lines (389 loc) 54.3 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); 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 _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); 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 _exportConfigModal = _interopRequireDefault(require("./modals/export-config-modal")); var _addMapStyleModal = _interopRequireDefault(require("./modals/add-map-style-modal")); var _defaultSettings = require("../constants/default-settings"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _templateObject3() { var data = (0, _taggedTemplateLiteral2["default"])(["\n top: 60px;\n"]); _templateObject3 = function _templateObject3() { return data; }; return data; } function _templateObject2() { var data = (0, _taggedTemplateLiteral2["default"])(["\n width: 40%;\n padding: 40px 40px 32px 40px;\n"]); _templateObject2 = function _templateObject2() { return data; }; return data; } function _templateObject() { var data = (0, _taggedTemplateLiteral2["default"])(["\n height: 85%;\n width: 90%;\n top: 80px;\n padding: 32px 0 0 0;\n max-width: unset;\n"]); _templateObject = function _templateObject() { return data; }; return data; } var DataTableModalStyle = (0, _styledComponents.css)(_templateObject()); var DeleteDatasetModalStyled = (0, _styledComponents.css)(_templateObject2()); var LoadDataModalStyle = (0, _styledComponents.css)(_templateObject3()); ModalContainerFactory.deps = [_loadExternalDataModal["default"], _dataTableModal["default"], _deleteDataModal["default"], _loadDataModal["default"], _exportImageModal["default"], _exportDataModal["default"], _exportConfigModal["default"], _addMapStyleModal["default"]]; function ModalContainerFactory(LoadExternalDataModal, DataTableModal, DeleteDatasetModal, LoadDataModal, ExportImageModal, ExportDataModal, ExportConfigModal, AddMapStyleModal) { var ModalWrapper = /*#__PURE__*/ function (_Component) { (0, _inherits2["default"])(ModalWrapper, _Component); function ModalWrapper() { var _getPrototypeOf2; 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 = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(ModalWrapper)).call.apply(_getPrototypeOf2, [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), "_onExportConfig", function () { var data = _this.props.uiState.exportData.data; // we pass all props because we avoid to create new variables var dump = data ? _schemas["default"].save(_this.props) : _schemas["default"].getConfigToSave(_this.props); _this._downloadFile(JSON.stringify(dump, null, 2), 'application/json', 'keplergl.json'); _this._closeModal(); }); 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", /* eslint-disable complexity */ value: 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({}, 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 = _react["default"].createElement(currentModal.template, null); modalProps = currentModal.modalProps; } else { switch (currentModal) { case _defaultSettings.DATA_TABLE_ID: template = _react["default"].createElement(DataTableModal, { width: containerW * 0.9, height: containerH * 0.85, datasets: datasets, dataId: editingDataset, showDatasetTable: visStateActions.showDatasetTable }); modalProps.cssStyle = DataTableModalStyle; break; case _defaultSettings.ADD_EXTERNAL_DATA_ID: template = _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 = _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 = _react["default"].createElement(LoadDataModal, { onClose: this._closeModal, onFileUpload: this._onFileUpload }); modalProps = { title: 'Add Data To Map', cssStyle: LoadDataModalStyle, footer: false, onConfirm: this._closeModal }; break; case _defaultSettings.EXPORT_IMAGE_ID: var _uiState$exportImage = uiState.exportImage, ratio = _uiState$exportImage.ratio, legend = _uiState$exportImage.legend, resolution = _uiState$exportImage.resolution, exporting = _uiState$exportImage.exporting, imageDataUri = _uiState$exportImage.imageDataUri; template = _react["default"].createElement(ExportImageModal, { width: containerW, height: containerH, legend: legend, ratio: ratio, resolution: resolution, exporting: exporting, imageDataUri: imageDataUri, 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: exporting, children: 'Download' } }; break; case _defaultSettings.EXPORT_DATA_ID: template = _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_CONFIG_ID: var keplerGlConfig = _schemas["default"].getConfigToSave({ mapStyle: mapStyle, visState: visState, mapState: mapState, uiState: uiState }); template = _react["default"].createElement(ExportConfigModal, { config: keplerGlConfig, data: uiState.exportData.data, onClose: this._closeModal, onChangeExportData: this.props.uiStateActions.setExportData }); modalProps = { close: false, title: 'Export Config', footer: true, onCancel: this._closeModal, onConfirm: this._onExportConfig, confirmButton: { large: true, children: 'Export' } }; break; case _defaultSettings.ADD_MAP_STYLE_ID: template = _react["default"].createElement(AddMapStyleModal, { mapboxApiAccessToken: this.props.mapboxApiAccessToken, 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; case _defaultSettings.ADD_WIDGET_ID: template = _react["default"].createElement(LoadDataModal, { onClose: this._closeModal, onFileUpload: this._onFileUpload }); modalProps = { title: 'Add Widget', cssStyle: LoadDataModalStyle, footer: false, onConfirm: this._closeModal }; break; // TODO: add this options once we merge dropbox onto kepelr.gl core // case SAVE_TO_CLOUD_ID default: break; } } return this.props.rootNode ? _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, 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL21vZGFsLWNvbnRhaW5lci5qcyJdLCJuYW1lcyI6WyJEYXRhVGFibGVNb2RhbFN0eWxlIiwiY3NzIiwiRGVsZXRlRGF0YXNldE1vZGFsU3R5bGVkIiwiTG9hZERhdGFNb2RhbFN0eWxlIiwiTW9kYWxDb250YWluZXJGYWN0b3J5IiwiZGVwcyIsIkxvYWRFeHRlcm5hbERhdGFNb2RhbEZhY3RvcnkiLCJEYXRhVGFibGVNb2RhbEZhY3RvcnkiLCJEZWxldGVEYXRhc2V0TW9kYWxGYWN0b3J5IiwiTG9hZERhdGFNb2RhbEZhY3RvcnkiLCJFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSIsIkV4cG9ydERhdGFNb2RhbEZhY3RvcnkiLCJFeHBvcnRDb25maWdNb2RhbEZhY3RvcnkiLCJBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSIsIkxvYWRFeHRlcm5hbERhdGFNb2RhbCIsIkRhdGFUYWJsZU1vZGFsIiwiRGVsZXRlRGF0YXNldE1vZGFsIiwiTG9hZERhdGFNb2RhbCIsIkV4cG9ydEltYWdlTW9kYWwiLCJFeHBvcnREYXRhTW9kYWwiLCJFeHBvcnRDb25maWdNb2RhbCIsIkFkZE1hcFN0eWxlTW9kYWwiLCJNb2RhbFdyYXBwZXIiLCJwcm9wcyIsInVpU3RhdGVBY3Rpb25zIiwidG9nZ2xlTW9kYWwiLCJrZXkiLCJ2aXNTdGF0ZUFjdGlvbnMiLCJyZW1vdmVEYXRhc2V0IiwiX2Nsb3NlTW9kYWwiLCJtYXBTdHlsZUFjdGlvbnMiLCJhZGRDdXN0b21NYXBTdHlsZSIsImJsb2IiLCJsb2FkRmlsZXMiLCJ1aVN0YXRlIiwiZXhwb3J0SW1hZ2UiLCJleHBvcnRpbmciLCJpbWFnZURhdGFVcmkiLCJmaWxlIiwiREVGQVVMVF9FWFBPUlRfSU1BR0VfTkFNRSIsImNsZWFudXBFeHBvcnRJbWFnZSIsInZpc1N0YXRlIiwiZGF0YXNldHMiLCJleHBvcnREYXRhIiwic2VsZWN0ZWREYXRhc2V0IiwiZGF0YVR5cGUiLCJmaWx0ZXJlZCIsImZpbGVuYW1lIiwic2VsZWN0ZWREYXRhc2V0cyIsIk9iamVjdCIsInZhbHVlcyIsImxlbmd0aCIsImZvckVhY2giLCJzZWxlY3RlZERhdGEiLCJhbGxEYXRhIiwiZGF0YSIsImZpZWxkcyIsImxhYmVsIiwiZXh0ZXJuYWxEYXRhIiwiRVhQT1JUX0RBVEFfVFlQRSIsIkNTViIsInR5cGUiLCJjc3YiLCJfZG93bmxvYWRGaWxlIiwiZHVtcCIsIktlcGxlckdsU2NoZW1hIiwic2F2ZSIsImdldENvbmZpZ1RvU2F2ZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJmaWxlQmxvYiIsIkJsb2IiLCJjb250YWluZXJXIiwiY29udGFpbmVySCIsIm1hcFN0eWxlIiwibWFwU3RhdGUiLCJyb290Tm9kZSIsImN1cnJlbnRNb2RhbCIsImRhdGFzZXRLZXlUb1JlbW92ZSIsImxheWVycyIsImVkaXRpbmdEYXRhc2V0IiwiZXhwb3J0RGF0YXNldHMiLCJkYXRhc2V0S2V5cyIsImtleXMiLCJtYXAiLCJkayIsInRlbXBsYXRlIiwibW9kYWxQcm9wcyIsImlkIiwiREFUQV9UQUJMRV9JRCIsInNob3dEYXRhc2V0VGFibGUiLCJjc3NTdHlsZSIsIkFERF9FWFRFUk5BTF9EQVRBX0lEIiwidGl0bGUiLCJmb290ZXIiLCJERUxFVEVfREFUQV9JRCIsIm9uQ29uZmlybSIsIl9kZWxldGVEYXRhc2V0Iiwib25DYW5jZWwiLCJjb25maXJtQnV0dG9uIiwibmVnYXRpdmUiLCJsYXJnZSIsImNoaWxkcmVuIiwiQUREX0RBVEFfSUQiLCJfb25GaWxlVXBsb2FkIiwiRVhQT1JUX0lNQUdFX0lEIiwicmF0aW8iLCJsZWdlbmQiLCJyZXNvbHV0aW9uIiwic2V0UmF0aW8iLCJzZXRSZXNvbHV0aW9uIiwidG9nZ2xlTGVnZW5kIiwiY2xvc2UiLCJfb25FeHBvcnRJbWFnZSIsImRpc2FibGVkIiwiRVhQT1JUX0RBVEFfSUQiLCJzZXRFeHBvcnREYXRhVHlwZSIsInNldEV4cG9ydFNlbGVjdGVkRGF0YXNldCIsInNldEV4cG9ydEZpbHRlcmVkIiwiX29uRXhwb3J0RGF0YSIsIkVYUE9SVF9DT05GSUdfSUQiLCJrZXBsZXJHbENvbmZpZyIsInNldEV4cG9ydERhdGEiLCJfb25FeHBvcnRDb25maWciLCJBRERfTUFQX1NUWUxFX0lEIiwibWFwYm94QXBpQWNjZXNzVG9rZW4iLCJpbnB1dFN0eWxlIiwiaW5wdXRNYXBTdHlsZSIsImxvYWRDdXN0b21NYXBTdHlsZSIsIl9vbkFkZEN1c3RvbU1hcFN0eWxlIiwic3R5bGUiLCJBRERfV0lER0VUX0lEIiwiQm9vbGVhbiIsIkNvbXBvbmVudCIsIlByb3BUeXBlcyIsIm9iamVjdCIsIm51bWJlciIsInN0cmluZyIsImlzUmVxdWlyZWQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjQSxJQUFNQSxtQkFBbUIsT0FBR0MscUJBQUgsb0JBQXpCO0FBUUEsSUFBTUMsd0JBQXdCLE9BQUdELHFCQUFILHFCQUE5QjtBQUtBLElBQU1FLGtCQUFrQixPQUFHRixxQkFBSCxxQkFBeEI7QUFJQUcscUJBQXFCLENBQUNDLElBQXRCLEdBQTZCLENBQzNCQyxpQ0FEMkIsRUFFM0JDLDBCQUYyQixFQUczQkMsMkJBSDJCLEVBSTNCQyx5QkFKMkIsRUFLM0JDLDRCQUwyQixFQU0zQkMsMkJBTjJCLEVBTzNCQyw2QkFQMkIsRUFRM0JDLDRCQVIyQixDQUE3Qjs7QUFXZSxTQUFTVCxxQkFBVCxDQUNiVSxxQkFEYSxFQUViQyxjQUZhLEVBR2JDLGtCQUhhLEVBSWJDLGFBSmEsRUFLYkMsZ0JBTGEsRUFNYkMsZUFOYSxFQU9iQyxpQkFQYSxFQVFiQyxnQkFSYSxFQVNiO0FBQUEsTUFDTUMsWUFETjtBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQUFBOztBQUFB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LFVBQUEsTUFBTSxFQUFFd0QsT0FBTyxDQUFDdkQsWUFBRCxDQUhqQjtBQUlFLFVBQUEsS0FBSyxFQUFFLEtBQUtoRDtBQUpkLFlBTUd5RCxRQU5ILENBREssR0FTSCxJQVRKO0FBVUQ7QUFDRDs7QUFoV0Y7QUFBQTtBQUFBLElBQzJCK0MsZ0JBRDNCOztBQUFBLG1DQUNNL0csWUFETixlQUVxQjtBQUNqQnNELElBQUFBLFFBQVEsRUFBRTBELHNCQUFVQyxNQURIO0FBRWpCL0QsSUFBQUEsVUFBVSxFQUFFOEQsc0JBQVVFLE1BRkw7QUFHakIvRCxJQUFBQSxVQUFVLEVBQUU2RCxzQkFBVUUsTUFITDtBQUlqQlgsSUFBQUEsb0JBQW9CLEVBQUVTLHNCQUFVRyxNQUFWLENBQWlCQyxVQUp0QjtBQUtqQi9ELElBQUFBLFFBQVEsRUFBRTJELHNCQUFVQyxNQUFWLENBQWlCRyxVQUxWO0FBTWpCaEUsSUFBQUEsUUFBUSxFQUFFNEQsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBTlY7QUFPakJ4RyxJQUFBQSxPQUFPLEVBQUVvRyxzQkFBVUMsTUFBVixDQUFpQkcsVUFQVDtBQVFqQmpHLElBQUFBLFFBQVEsRUFBRTZGLHNCQUFVQyxNQUFWLENBQWlCRyxVQVJWO0FBU2pCL0csSUFBQUEsZUFBZSxFQUFFMkcsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBVGpCO0FBVWpCbEgsSUFBQUEsY0FBYyxFQUFFOEcsc0JBQVVDLE1BQVYsQ0FBaUJHLFVBVmhCO0FBV2pCNUcsSUFBQUEsZUFBZSxFQUFFd0csc0JBQVVDLE1BQVYsQ0FBaUJHO0FBWGpCLEdBRnJCO0FBbVdBLFNBQU9wSCxZQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMTkgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgUmVhY3QsIHtDb21wb25lbnR9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQge2Nzc30gZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtmaW5kRE9NTm9kZX0gZnJvbSAncmVhY3QtZG9tJztcbmltcG9ydCB7QmxvYn0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5cbmltcG9ydCBNb2RhbERpYWxvZyBmcm9tICcuL2NvbW1vbi9tb2RhbCc7XG5pbXBvcnQge2Zvcm1hdENzdn0gZnJvbSAncHJvY2Vzc29ycy9kYXRhLXByb2Nlc3Nvcic7XG5pbXBvcnQgS2VwbGVyR2xTY2hlbWEgZnJvbSAnc2NoZW1hcyc7XG5pbXBvcnQge2Rvd25sb2FkRmlsZSwgZGF0YVVSSXRvQmxvYn0gZnJvbSAndXRpbHMvZXhwb3J0LWltYWdlLXV0aWxzJztcbi8vIG1vZGFsc1xuaW1wb3J0IERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZGVsZXRlLWRhdGEtbW9kYWwnO1xuaW1wb3J0IERhdGFUYWJsZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9kYXRhLXRhYmxlLW1vZGFsJztcbmltcG9ydCBMb2FkRGF0YU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9sb2FkLWRhdGEtbW9kYWwnO1xuaW1wb3J0IExvYWRFeHRlcm5hbERhdGFNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvbG9hZC1leHRlcm5hbC1kYXRhLW1vZGFsJztcbmltcG9ydCBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtaW1hZ2UtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydERhdGFNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZXhwb3J0LWRhdGEtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydENvbmZpZ01vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtY29uZmlnLW1vZGFsJztcbmltcG9ydCBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9hZGQtbWFwLXN0eWxlLW1vZGFsJztcblxuaW1wb3J0IHtcbiAgQUREX0RBVEFfSUQsXG4gIERBVEFfVEFCTEVfSUQsXG4gIERFRkFVTFRfRVhQT1JUX0lNQUdFX05BTUUsXG4gIERFTEVURV9EQVRBX0lELFxuICBFWFBPUlRfREFUQV9JRCxcbiAgRVhQT1JUX0RBVEFfVFlQRSxcbiAgRVhQT1JUX0lNQUdFX0lELFxuICBFWFBPUlRfQ09ORklHX0lELFxuICBBRERfTUFQX1NUWUxFX0lELFxuICBBRERfV0lER0VUX0lELFxuICBBRERfRVhURVJOQUxfREFUQV9JRFxufSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbmNvbnN0IERhdGFUYWJsZU1vZGFsU3R5bGUgPSBjc3NgXG4gIGhlaWdodDogODUlO1xuICB3aWR0aDogOTAlO1xuICB0b3A6IDgwcHg7XG4gIHBhZGRpbmc6IDMycHggMCAwIDA7XG4gIG1heC13aWR0aDogdW5zZXQ7XG5gO1xuXG5jb25zdCBEZWxldGVEYXRhc2V0TW9kYWxTdHlsZWQgPSBjc3NgXG4gIHdpZHRoOiA0MCU7XG4gIHBhZGRpbmc6IDQwcHggNDBweCAzMnB4IDQwcHg7XG5gO1xuXG5jb25zdCBMb2FkRGF0YU1vZGFsU3R5bGUgPSBjc3NgXG4gIHRvcDogNjBweDtcbmA7XG5cbk1vZGFsQ29udGFpbmVyRmFjdG9yeS5kZXBzID0gW1xuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWxGYWN0b3J5LFxuICBEYXRhVGFibGVNb2RhbEZhY3RvcnksXG4gIERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnksXG4gIExvYWREYXRhTW9kYWxGYWN0b3J5LFxuICBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeSxcbiAgRXhwb3J0Q29uZmlnTW9kYWxGYWN0b3J5LFxuICBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeVxuXTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kYWxDb250YWluZXJGYWN0b3J5KFxuICBMb2FkRXh0ZXJuYWxEYXRhTW9kYWwsXG4gIERhdGFUYWJsZU1vZGFsLFxuICBEZWxldGVEYXRhc2V0TW9kYWwsXG4gIExvYWREYXRhTW9kYWwsXG4gIEV4cG9ydEltYWdlTW9kYWwsXG4gIEV4cG9ydERhdGFNb2RhbCxcbiAgRXhwb3J0Q29uZmlnTW9kYWwsXG4gIEFkZE1hcFN0eWxlTW9kYWxcbikge1xuICBjbGFzcyBNb2RhbFdyYXBwZXIgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICByb290Tm9kZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgIGNvbnRhaW5lclc6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgICBjb250YWluZXJIOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgICAgbWFwYm94QXBpQWNjZXNzVG9rZW46IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0YXRlOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBTdHlsZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdmlzU3RhdGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIHZpc1N0YXRlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZUFjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0eWxlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG4gICAgfTtcblxuICAgIF9jbG9zZU1vZGFsID0gKCkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy50b2dnbGVNb2RhbChudWxsKTtcbiAgICB9O1xuXG4gICAgX2RlbGV0ZURhdGFzZXQgPSBrZXkgPT4ge1xuICAgICAgdGhpcy5wcm9wcy52aXNTdGF0ZUFjdGlvbnMucmVtb3ZlRGF0YXNldChrZXkpO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfb25BZGRDdXN0b21NYXBTdHlsZSA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvcHMubWFwU3R5bGVBY3Rpb25zLmFkZEN1c3RvbU1hcFN0eWxlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkZpbGVVcGxvYWQgPSBibG9iID0+IHtcbiAgICAgIHRoaXMucHJvcHMudmlzU3RhdGVBY3Rpb25zLmxvYWRGaWxlcyhibG9iKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0SW1hZ2UgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7ZXhwb3J0aW5nLCBpbWFnZURhdGFVcml9ID0gdGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydEltYWdlO1xuICAgICAgaWYgKCFleHBvcnRpbmcgJiYgaW1hZ2VEYXRhVXJpKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBkYXRhVVJJdG9CbG9iKGltYWdlRGF0YVVyaSk7XG4gICAgICAgIGRvd25sb2FkRmlsZShmaWxlLCBERUZBVUxUX0VYUE9SVF9JTUFHRV9OQU1FKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMuY2xlYW51cEV4cG9ydEltYWdlKCk7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9kb3dubG9hZEZpbGUoZGF0YSwgdHlwZSwgZmlsZW5hbWUpIHtcbiAgICAgIGNvbnN0IGZpbGVCbG9iID0gbmV3IEJsb2IoW2RhdGFdLCB7dHlwZX0pO1xuICAgICAgZG93bmxvYWRGaWxlKGZpbGVCbG9iLCBmaWxlbmFtZSk7XG4gICAgfVxuXG4gICAgX29uRXhwb3J0RGF0YSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHt2aXNTdGF0ZSwgdWlTdGF0ZX0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2RhdGFzZXRzfSA9IHZpc1N0YXRlO1xuICAgICAgY29uc3Qge3NlbGVjdGVkRGF0YXNldCwgZGF0YVR5cGUsIGZpbHRlcmVkfSA9IHVpU3RhdGUuZXhwb3J0RGF0YTtcbiAgICAgIC8vIGdldCB0aGUgc2VsZWN0ZWQgZGF0YVxuICAgICAgY29uc3QgZmlsZW5hbWUgPSAnZ2VvaXEuaW8nO1xuICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhc2V0cyA9IGRhdGFzZXRzW3NlbGVjdGVkRGF0YXNldF1cbiAgICAgICAgPyBbZGF0YXNldHNbc2VsZWN0ZWREYXRhc2V0XV1cbiAgICAgICAgOiBPYmplY3QudmFsdWVzKGRhdGFzZXRzKTtcbiAgICAgIGlmICghc2VsZWN0ZWREYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gZXJyb3I6IHNlbGVjdGVkIGRhdGFzZXQgbm90IGZvdW5kLlxuICAgICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgICB9XG5cbiAgICAgIHNlbGVjdGVkRGF0YXNldHMuZm9yRWFjaChzZWxlY3RlZERhdGEgPT4ge1xuICAgICAgICBjb25zdCB7YWxsRGF0YSwgZGF0YSwgZmllbGRzLCBsYWJlbCwgZXh0ZXJuYWxEYXRhfSA9IHNlbGVjdGVkRGF0YTtcbiAgICAgICAgY29uc3QgZXhwb3J0RGF0YSA9IGZpbHRlcmVkID8gZGF0YSA6IGFsbERhdGE7XG4gICAgICAgIGlmIChleHRlcm5hbERhdGEgJiYgZXh0ZXJuYWxEYXRhID09PSB0cnVlKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RhcnQgdG8gZXhwb3J0IGRhdGEgYWNjb3JkaW5nIHRvIHNlbGVjdGVkIGRhdGEgdHlwZVxuICAgICAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICAgICAgY2FzZSBFWFBPUlRfREFUQV9UWVBFLkNTVjoge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9ICd0ZXh0L2Nzdic7XG4gICAgICAgICAgICBjb25zdCBjc3YgPSBmb3JtYXRDc3YoZXhwb3J0RGF0YSwgZmllbGRzKTtcbiAgICAgICAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShjc3YsIHR5cGUsIGAke2ZpbGVuYW1lfV8ke2xhYmVsfS5jc3ZgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IG1vcmUgZmlsZSB0eXBlcy5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydENvbmZpZyA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHtkYXRhfSA9IHRoaXMucHJvcHMudWlTdGF0ZS5leHBvcnREYXRhO1xuXG4gICAgICAvLyB3ZSBwYXNzIGFsbCBwcm9wcyBiZWNhdXNlIHdlIGF2b2lkIHRvIGNyZWF0ZSBuZXcgdmFyaWFibGVzXG4gICAgICBjb25zdCBkdW1wID0gZGF0YVxuICAgICAgICA/IEtlcGxlckdsU2NoZW1hLnNhdmUodGhpcy5wcm9wcylcbiAgICAgICAgOiBLZXBsZXJHbFNjaGVtYS5nZXRDb25maWdUb1NhdmUodGhpcy5wcm9wcyk7XG5cbiAgICAgIHRoaXMuX2Rvd25sb2FkRmlsZShcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZHVtcCwgbnVsbCwgMiksXG4gICAgICAgICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ2tlcGxlcmdsLmpzb24nXG4gICAgICApO1xuXG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgfTtcblxuICAgIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbiAgICByZW5kZXIoKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGNvbnRhaW5lclcsXG4gICAgICAgIGNvbnRhaW5lckgsXG4gICAgICAgIG1hcFN0eWxlLFxuICAgICAgICBtYXBTdGF0ZSxcbiAgICAgICAgdWlTdGF0ZSxcbiAgICAgICAgdmlzU3RhdGUsXG4gICAgICAgIHJvb3ROb2RlLFxuICAgICAgICB2aXNTdGF0ZUFjdGlvbnNcbiAgICAgIH0gPSB0aGlzLnByb3BzO1xuICAgICAgY29uc3Qge2N1cnJlbnRNb2RhbCwgZGF0YXNldEtleVRvUmVtb3ZlfSA9IHVpU3RhdGU7XG4gICAgICBjb25zdCB7ZGF0YXNldHMsIGxheWVycywgZWRpdGluZ0RhdGFzZXR9ID0gdmlzU3RhdGU7XG4gICAgICB2YXIgZXhwb3J0RGF0YXNldHMgPSB7fTtcbiAgICAgIGNvbnN0IGRhdGFzZXRLZXlzID0gT2JqZWN0LmtleXMoZGF0YXNldHMpO1xuICAgICAgZGF0YXNldEtleXMubWFwKGRrID0+IHtcbiAgICAgICAgY29uc3QgZXh0ZXJuYWxEYXRhID0gZGF0YXNldHNbZGtdLmV4dGVybmFsRGF0YTtcbiAgICAgICAgZXh0ZXJuYWxEYXRhICYmIGV4dGVybmFsRGF0YSA9PT0gdHJ1ZVxuICAgICAgICAgID8gbnVsbFxuICAgICAgICAgIDogKGV4cG9ydERhdGFzZXRzID0gey4uLmV4cG9ydERhdGFzZXRzLCBbZGtdOiBkYXRhc2V0c1tka119KTtcbiAgICAgIH0pO1xuICAgICAgbGV0IHRlbXBsYXRlID0gbnVsbDtcbiAgICAgIGxldCBtb2RhbFByb3BzID0ge307XG5cbiAgICAgIGlmIChjdXJyZW50TW9kYWwgJiYgY3VycmVudE1vZGFsLmlkICYmIGN1cnJlbnRNb2RhbC50ZW1wbGF0ZSkge1xuICAgICAgICAvLyBpZiBjdXJyZW50TWRvYWwgdGVtcGxhdGUgaXMgYWxyZWFkeSBwcm92aWRlZFxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGVtcGxhdGUgaXMgdmFsaWRcbiAgICAgICAgdGVtcGxhdGUgPSA8Y3VycmVudE1vZGFsLnRlbXBsYXRlIC8+O1xuICAgICAgICBtb2RhbFByb3BzID0gY3VycmVudE1vZGFsLm1vZGFsUHJvcHM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2l0Y2ggKGN1cnJlbnRNb2RhbCkge1xuICAgICAgICAgIGNhc2UgREFUQV9UQUJMRV9JRDpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gKFxuICAgICAgICAgICAgICA8RGF0YVRhYmxlTW9kYWxcbiAgICAgICAgICAgICAgICB3aWR0aD17Y29udGFpbmVyVyAqIDAuOX1cbiAgICAgICAgICAgICAgICBoZWlnaHQ9e2NvbnRhaW5lckggKiAwLjg1fVxuICAgICAgICAgICAgICAgIGRhdGFzZXRzPXtkYXRhc2V0c31cbiAgICAgICAgICAgICAgICBkYXRhSWQ9e2VkaXRpbmdEYXRhc2V0fVxuICAgICAgICAgICAgICAgIHNob3dEYXRhc2V0VGFibGU9e3Zpc1N0YXRlQWN0aW9ucy5zaG93RGF0YXNldFRhYmxlfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG1vZGFsUHJvcHMuY3NzU3R5bGUgPSBEYXRhVGFibGVNb2RhbFN0eWxlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBBRERfRVhURVJOQUxfREFUQV9JRDpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gPExvYWRFeHRlcm5hbERhdGFNb2RhbCAvPjtcbiAgICAgICAgICAgIG1vZGFsUHJvcHMgPSB7XG4gICAgICAgICAgICAgIHRpdGxlOiAnQWRkIEV4dGVybmFsIERhdGEgVG8gTWFwJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiBmYWxzZVxuICAgICAgICAgICAgICAvLyBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgIC8vICAgbGFyZ2U6IHRydWUsXG4gICAgICAgICAgICAgIC8vICAgY2hpbGRyZW46ICdBZGQgRXh0ZXJuYWwgRGF0YXNldCdcbiAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgREVMRVRFX0RBVEFfSUQ6XG4gICAgICAgICAgICAvLyB2YWxpZGF0ZSBvcHRpb25zXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGRhdGFzZXRLZXlUb1JlbW92ZSAmJlxuICAgICAgICAgICAgICBkYXRhc2V0cyAmJlxuICAgICAgICAgICAgICBkYXRhc2V0c1tkYXRhc2V0S2V5VG9SZW1vdmVdXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgICAgPERlbGV0ZURhdGFzZXRNb2RhbFxuICAgICAgICAgICAgICAgICAgZGF0YXNldD17ZGF0YXNldHNbZGF0YXNldEtleVRvUmVtb3ZlXX1cbiAgICAgICAgICAgICAgICAgIGxheWVycz17bGF5ZXJzfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgbW9kYWxQcm9wcyA9IHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0RlbGV0ZSBEYXRhc2V0JyxcbiAgICAgICAgICAgICAgICBjc3NTdHlsZTogRGVsZXRlRGF0YXNldE1vZGFsU3R5bGVkLFxuICAgICAgICAgICAgICAgIGZvb3RlcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvbkNvbmZpcm06ICgpID0+IHRoaXMuX2RlbGV0ZURhdGFzZXQoZGF0YXNldEtleVRvUmVtb3ZlKSxcbiAgICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgICAgICBuZWdhdGl2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGxhcmdlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgY2hpbGRyZW46ICdEZWxldGUnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7IC8vIGluIGNhc2Ugd2UgYWRkIGEgbmV3IGNhc2UgYWZ0ZXIgdGhpcyBvbmVcbiAgICAgICAgICBjYXNlIEFERF9EQVRBX0lEOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxMb2FkRGF0YU1vZGFsXG4gICAgICAgICAgICAgICAgb25DbG9zZT17dGhpcy5fY2xvc2VNb2RhbH1cbiAgICAgICAgICAgICAgICBvbkZpbGVVcGxvYWQ9e3RoaXMuX29uRmlsZVVwbG9hZH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICB0aXRsZTogJ0FkZCBEYXRhIFRvIE1hcCcsXG4gICAgICAgICAgICAgIGNzc1N0eWxlOiBMb2FkRGF0YU1vZGFsU3R5bGUsXG4gICAgICAgICAgICAgIGZvb3RlcjogZmFsc2UsXG4gICAgICAgICAgICAgIG9uQ29uZmlybTogdGhpcy5fY2xvc2VNb2RhbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBFWFBPUlRfSU1BR0VfSUQ6XG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHJhdGlvLFxuICAgICAgICAgICAgICBsZWdlbmQsXG4gICAgICAgICAgICAgIHJlc29sdXRpb24sXG4gICAgICAgICAgICAgIGV4cG9ydGluZyxcbiAgICAgICAgICAgICAgaW1hZ2VEYXRhVXJpXG4gICAgICAgICAgICB9ID0gdWlTdGF0ZS5leHBvcnRJbWFnZTtcbiAgICAgICAgICAgIHRlbXBsYXRlID0gKFxuICAgICAgICAgICAgICA8RXhwb3J0SW1hZ2VNb2RhbFxuICAgICAgICAgICAgICAgIHdpZHRoPXtjb250YWluZXJXfVxuICAgICAgICAgICAgICAgIGhlaWdodD17Y29udGFpbmVySH1cbiAgICAgICAgICAgICAgICBsZWdlbmQ9e2xlZ2VuZH1cbiAgICAgICAgICAgICAgICByYXRpbz17cmF0aW99XG4gICAgICAgICAgICAgICAgcmVzb2x1dGlvbj17cmVzb2x1dGlvbn1cbiAgICAgICAgICAgICAgICBleHBvcnRpbmc9e2V4cG9ydGluZ31cbiAgICAgICAgICAgICAgICBpbWFnZURhdGFVcmk9e2ltYWdlRGF0YVVyaX1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZVJhdGlvPXt0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLnNldFJhdGlvfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlUmVzb2x1dGlvbj17dGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy5zZXRSZXNvbHV0aW9ufVxuICAgICAgICAgICAgICAgIG9uVG9nZ2xlTGVnZW5kPXt0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLnRvZ2dsZUxlZ2VuZH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICBjbG9zZTogZmFsc2UsXG4gICAgICAgICAgICAgIHRpdGxlOiAnRXhwb3J0IEltYWdlJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiB0cnVlLFxuICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgb25Db25maXJtOiB0aGlzLl9vbkV4cG9ydEltYWdlLFxuICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgICAgbGFyZ2U6IHRydWUsXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGV4cG9ydGluZyxcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogJ0Rvd25sb2FkJ1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIEVYUE9SVF9EQVRBX0lEOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxFeHBvcnREYXRhTW9kYWxcbiAgICAgICAgICAgICAgICB7Li4udWlTdGF0ZS5leHBvcnREYXRhfVxuICAgICAgICAgICAgICAgIGRhdGFzZXRzPXtleHBvcnREYXRhc2V0c31cbiAgICAgICAgICAgICAgICBvbkNsb3NlPXt0aGlzLl9jbG9zZU1vZGFsfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlRXhwb3J0RGF0YVR5cGU9e1xuICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy51aVN0YXRlQWN0aW9ucy5zZXRFeHBvcnREYXRhVHlwZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydFNlbGVjdGVkRGF0YXNldD17XG4gICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLnNldEV4cG9ydFNlbGVjdGVkRGF0YXNldFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydEZpbHRlcmVkPXtcbiAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMuc2V0RXhwb3J0RmlsdGV