kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
435 lines (432 loc) • 74.5 kB
JavaScript
"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 _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
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 _styledComponents = require("styled-components");
var _lodash = _interopRequireDefault(require("lodash.get"));
var _document = _interopRequireDefault(require("global/document"));
var _constants = require("@kepler.gl/constants");
var _reducers = require("@kepler.gl/reducers");
var _utils = require("@kepler.gl/utils");
var _modalDialog = _interopRequireDefault(require("./modals/modal-dialog"));
var _deleteDataModal = _interopRequireDefault(require("./modals/delete-data-modal"));
var _overwriteMapModal = _interopRequireDefault(require("./modals/overwrite-map-modal"));
var _dataTableModal = _interopRequireDefault(require("./modals/data-table-modal"));
var _loadDataModal = _interopRequireDefault(require("./modals/load-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/export-map-modal"));
var _addMapStyleModal = _interopRequireDefault(require("./modals/add-map-style-modal"));
var _saveMapModal = _interopRequireDefault(require("./modals/save-map-modal"));
var _shareMapModal = _interopRequireDefault(require("./modals/share-map-modal"));
var _styles = require("@kepler.gl/styles");
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8; // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// modals
// Breakpoints
// Template
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 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 _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
var DataTableModalStyle = (0, _styledComponents.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n top: 70px;\n padding: 0;\n width: 90vw;\n max-width: 90vw;\n\n ", " ", ";\n"])), _styles.media.portable(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0;\n "]))), _styles.media.palm(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 0;\n margin: 0 auto;\n "]))));
var smallModalCss = (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: 60px;\n"])));
var DefaultStyle = (0, _styledComponents.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n max-width: 960px;\n"])));
ModalContainerFactory.deps = [_deleteDataModal["default"], _overwriteMapModal["default"], _dataTableModal["default"], _loadDataModal["default"], _exportImageModal["default"], _exportDataModal["default"], _exportMapModal["default"], _addMapStyleModal["default"], _modalDialog["default"], _saveMapModal["default"], _shareMapModal["default"]];
function ModalContainerFactory(DeleteDatasetModal, OverWriteMapModal, DataTableModal, LoadDataModal, ExportImageModal, ExportDataModal, ExportMapModal, AddMapStyleModal, ModalDialog, SaveMapModal, ShareMapModal) {
/** @augments React.Component<ModalContainerProps> */
var ModalContainer = /*#__PURE__*/function (_Component) {
function ModalContainer() {
var _this;
(0, _classCallCheck2["default"])(this, ModalContainer);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _callSuper(this, ModalContainer, [].concat(args));
// TODO - remove when prop types are fully exported
(0, _defineProperty2["default"])(_this, "componentDidMount", function () {
_document["default"].addEventListener('keyup', _this._onKeyUp);
});
(0, _defineProperty2["default"])(_this, "_onKeyUp", function (event) {
var keyCode = event.keyCode;
if (keyCode === _constants.KeyEvent.DOM_VK_ESCAPE) {
_this._closeModal();
}
});
(0, _defineProperty2["default"])(_this, "_closeModal", function () {
_this.props.uiStateActions.toggleModal(null);
});
(0, _defineProperty2["default"])(_this, "_deleteDataset", function (key) {
_this.props.visStateActions.removeDataset(key);
_this._closeModal();
});
(0, _defineProperty2["default"])(_this, "_onAddCustomMapStyle", function () {
_this.props.mapStyleActions.addCustomMapStyle();
_this._closeModal();
});
(0, _defineProperty2["default"])(_this, "_onFileUpload", function (fileList) {
_this.props.visStateActions.loadFiles(fileList);
});
(0, _defineProperty2["default"])(_this, "_onTilesetAdded", function (tileset, processedMetadata) {
_this.props.visStateActions.updateVisData({
info: {
label: tileset.name,
type: tileset.type,
format: 'rows'
},
data: {
fields: (processedMetadata === null || processedMetadata === void 0 ? void 0 : processedMetadata.fields) || [],
rows: []
},
metadata: _objectSpread(_objectSpread({}, processedMetadata), tileset.metadata),
// vector tile layer only supports gpu filtering for now
supportedFilterTypes: [_constants.ALL_FIELD_TYPES.real, _constants.ALL_FIELD_TYPES.integer],
disableDataOperation: true
}, {
autoCreateLayers: true,
centerMap: true
});
_this._closeModal();
});
(0, _defineProperty2["default"])(_this, "_onExportImage", function () {
if (!_this.props.uiState.exportImage.processing) {
(0, _utils.exportImage)(_this.props.uiState.exportImage, "".concat(_this.props.appName, ".png"));
_this.props.uiStateActions.cleanupExportImage();
_this._closeModal();
}
});
(0, _defineProperty2["default"])(_this, "_onExportData", function () {
(0, _reducers.exportData)(_this.props, _this.props.uiState.exportData);
_this._closeModal();
});
(0, _defineProperty2["default"])(_this, "_onExportMap", function () {
var uiState = _this.props.uiState;
var format = uiState.exportMap.format;
(format === _constants.EXPORT_MAP_FORMATS.HTML ? _utils.exportHtml : _utils.exportJson)(_this.props, _this.props.uiState.exportMap[format] || {});
_this._closeModal();
});
(0, _defineProperty2["default"])(_this, "_exportFileToCloud", function (_ref) {
var provider = _ref.provider,
isPublic = _ref.isPublic,
overwrite = _ref.overwrite,
closeModal = _ref.closeModal;
var toSave = (0, _utils.exportMap)(_this.props);
_this.props.providerActions.exportFileToCloud({
mapData: toSave,
provider: provider,
options: {
isPublic: isPublic,
overwrite: overwrite,
mapIdToOverwrite: _this.props.providerState.savedMapId
},
closeModal: closeModal,
onSuccess: _this.props.onExportToCloudSuccess,
onError: _this.props.onExportToCloudError
});
});
(0, _defineProperty2["default"])(_this, "_onSaveMap", function (provider) {
var overwrite = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
_this._exportFileToCloud({
provider: provider,
isPublic: false,
overwrite: overwrite,
closeModal: true
});
});
(0, _defineProperty2["default"])(_this, "_onOverwriteMap", function (provider) {
_this._onSaveMap(provider, true);
});
(0, _defineProperty2["default"])(_this, "_onShareMapUrl", function (provider) {
_this._exportFileToCloud({
provider: provider,
isPublic: true,
overwrite: false,
closeModal: false
});
});
(0, _defineProperty2["default"])(_this, "_onCloseSaveMap", function () {
_this.props.providerActions.resetProviderStatus();
_this._closeModal();
});
(0, _defineProperty2["default"])(_this, "_onLoadCloudMap", function (payload) {
_this.props.providerActions.loadCloudMap(_objectSpread(_objectSpread({}, payload), {}, {
onSuccess: _this.props.onLoadCloudMapSuccess,
onError: _this.props.onLoadCloudMapError
}));
});
return _this;
}
(0, _inherits2["default"])(ModalContainer, _Component);
return (0, _createClass2["default"])(ModalContainer, [{
key: "componentWillUnmount",
value: function componentWillUnmount() {
_document["default"].removeEventListener('keyup', this._onKeyUp);
}
}, {
key: "render",
value: /* eslint-disable complexity */
function render() {
var _this2 = this;
var _this$props = this.props,
containerW = _this$props.containerW,
containerH = _this$props.containerH,
mapStyle = _this$props.mapStyle,
mapState = _this$props.mapState,
uiState = _this$props.uiState,
visState = _this$props.visState,
rootNode = _this$props.rootNode,
visStateActions = _this$props.visStateActions,
uiStateActions = _this$props.uiStateActions,
providerState = _this$props.providerState;
var currentModal = uiState.currentModal,
datasetKeyToRemove = uiState.datasetKeyToRemove;
var datasets = visState.datasets,
layers = visState.layers,
editingDataset = visState.editingDataset;
var template = null;
var modalProps = {};
// TODO - currentModal is a string
// @ts-ignore
if (currentModal && currentModal.id && currentModal.template) {
// if currentMdoal template is already provided
// TODO: need to check whether template is valid
// @ts-ignore
template = /*#__PURE__*/_react["default"].createElement(currentModal.template, null);
// @ts-ignore
modalProps = currentModal.modalProps;
} else {
switch (currentModal) {
case _constants.DATA_TABLE_ID:
{
var width = containerW * 0.9;
template = /*#__PURE__*/_react["default"].createElement(DataTableModal, {
datasets: datasets,
dataId: editingDataset,
showDatasetTable: visStateActions.showDatasetTable,
sortTableColumn: visStateActions.sortTableColumn,
pinTableColumn: visStateActions.pinTableColumn,
copyTableColumn: visStateActions.copyTableColumn,
setColumnDisplayFormat: visStateActions.setColumnDisplayFormat,
uiStateActions: uiStateActions,
uiState: uiState
});
// TODO: we need to make this width consistent with the css rule defined modal.js:32 max-width: 70vw
// @ts-ignore // TODO fix this after add types to Theme
modalProps.cssStyle = (0, _styledComponents.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n ", ";\n ", ";\n "])), DataTableModalStyle, _styles.media.palm(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n width: ", "px;\n "])), width));
break;
}
case _constants.DELETE_DATA_ID:
{
// validate options
if (datasetKeyToRemove && datasets && datasets[datasetKeyToRemove]) {
template = /*#__PURE__*/_react["default"].createElement(DeleteDatasetModal, {
dataset: datasets[datasetKeyToRemove],
layers: layers
});
modalProps = {
title: 'modal.title.deleteDataset',
cssStyle: smallModalCss,
footer: true,
onConfirm: function onConfirm() {
return _this2._deleteDataset(datasetKeyToRemove);
},
onCancel: this._closeModal,
confirmButton: {
negative: true,
large: true,
children: 'modal.button.delete'
}
};
}
break; // in case we add a new case after this one
}
case _constants.ADD_DATA_ID:
template = /*#__PURE__*/_react["default"].createElement(LoadDataModal, (0, _extends2["default"])({}, providerState, {
onClose: this._closeModal,
onFileUpload: this._onFileUpload,
onTilesetAdded: this._onTilesetAdded,
onLoadCloudMap: this._onLoadCloudMap,
loadFiles: uiState.loadFiles,
fileLoading: visState.fileLoading,
fileLoadingProgress: visState.fileLoadingProgress,
fileFormatNames: (0, _reducers.getFileFormatNames)(this.props.visState),
fileExtensions: (0, _reducers.getFileExtensions)(this.props.visState)
}));
modalProps = {
title: 'modal.title.addDataToMap',
cssStyle: LoadDataModalStyle,
footer: false,
onConfirm: this._closeModal
};
break;
case _constants.EXPORT_IMAGE_ID:
template = /*#__PURE__*/_react["default"].createElement(ExportImageModal, {
exportImage: uiState.exportImage,
mapW: containerW,
mapH: containerH,
onUpdateImageSetting: uiStateActions.setExportImageSetting,
cleanupExportImage: uiStateActions.cleanupExportImage
});
modalProps = {
title: 'modal.title.exportImage',
cssStyle: '',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportImage,
confirmButton: {
large: true,
disabled: uiState.exportImage.processing,
children: 'modal.button.download'
}
};
break;
case _constants.EXPORT_DATA_ID:
template = /*#__PURE__*/_react["default"].createElement(ExportDataModal, (0, _extends2["default"])({}, uiState.exportData, {
supportedDataTypes: _constants.EXPORT_DATA_TYPE_OPTIONS,
datasets: datasets,
applyCPUFilter: this.props.visStateActions.applyCPUFilter,
onChangeExportDataType: uiStateActions.setExportDataType,
onChangeExportSelectedDataset: uiStateActions.setExportSelectedDataset,
onChangeExportFiltered: uiStateActions.setExportFiltered
}));
modalProps = {
title: 'modal.title.exportData',
cssStyle: '',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportData,
confirmButton: {
large: true,
children: 'modal.button.export'
}
};
break;
case _constants.EXPORT_MAP_ID:
{
var keplerGlConfig = visState.schema.getConfigToSave({
mapStyle: mapStyle,
visState: visState,
mapState: mapState,
uiState: uiState
});
template = /*#__PURE__*/_react["default"].createElement(ExportMapModal, {
config: keplerGlConfig,
options: uiState.exportMap,
onChangeExportMapFormat: uiStateActions.setExportMapFormat,
onEditUserMapboxAccessToken: uiStateActions.setUserMapboxAccessToken,
onChangeExportMapHTMLMode: uiStateActions.setExportHTMLMapMode
});
modalProps = {
title: 'modal.title.exportMap',
cssStyle: '',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onExportMap,
confirmButton: {
large: true,
children: 'modal.button.export'
}
};
break;
}
case _constants.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 = {
title: 'modal.title.addCustomMapboxStyle',
cssStyle: '',
footer: true,
onCancel: this._closeModal,
onConfirm: this._onAddCustomMapStyle,
confirmButton: {
large: true,
disabled: mapStyle.inputStyle.error || !mapStyle.inputStyle.url || !mapStyle.inputStyle.label,
children: 'modal.button.addStyle'
}
};
break;
case _constants.SAVE_MAP_ID:
template = /*#__PURE__*/_react["default"].createElement(SaveMapModal, (0, _extends2["default"])({}, providerState, {
exportImage: uiState.exportImage,
mapInfo: visState.mapInfo,
onSetMapInfo: visStateActions.setMapInfo,
cleanupExportImage: uiStateActions.cleanupExportImage,
onUpdateImageSetting: uiStateActions.setExportImageSetting,
onCancel: this._closeModal,
onConfirm: function onConfirm(provider) {
return _this2._onSaveMap(provider, false);
}
}));
modalProps = {
title: 'modal.title.saveMap',
cssStyle: '',
footer: false
};
break;
case _constants.OVERWRITE_MAP_ID:
template = /*#__PURE__*/_react["default"].createElement(OverWriteMapModal, (0, _extends2["default"])({}, providerState, {
title: (0, _lodash["default"])(visState, ['mapInfo', 'title']),
onUpdateImageSetting: uiStateActions.setExportImageSetting,
cleanupExportImage: uiStateActions.cleanupExportImage,
onConfirm: this._onOverwriteMap,
onCancel: this._closeModal
}));
modalProps = {
title: 'Overwrite Existing File?',
cssStyle: smallModalCss,
footer: false
};
break;
case _constants.SHARE_MAP_ID:
template = /*#__PURE__*/_react["default"].createElement(ShareMapModal, (0, _extends2["default"])({}, providerState, {
onExport: this._onShareMapUrl,
cleanupExportImage: uiStateActions.cleanupExportImage,
onUpdateImageSetting: uiStateActions.setExportImageSetting
}));
modalProps = {
title: 'modal.title.shareURL',
cssStyle: '',
onCancel: this._onCloseSaveMap
};
break;
default:
break;
}
}
return rootNode ? /*#__PURE__*/_react["default"].createElement(ModalDialog, (0, _extends2["default"])({
parentSelector: function parentSelector() {
return rootNode;
},
isOpen: Boolean(currentModal),
onCancel: this._closeModal
}, modalProps, {
cssStyle: DefaultStyle.concat(modalProps.cssStyle)
}), template) : null;
}
/* eslint-enable complexity */
}]);
}(_react.Component);
return ModalContainer;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc3R5bGVkQ29tcG9uZW50cyIsIl9sb2Rhc2giLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2RvY3VtZW50IiwiX2NvbnN0YW50cyIsIl9yZWR1Y2VycyIsIl91dGlscyIsIl9tb2RhbERpYWxvZyIsIl9kZWxldGVEYXRhTW9kYWwiLCJfb3ZlcndyaXRlTWFwTW9kYWwiLCJfZGF0YVRhYmxlTW9kYWwiLCJfbG9hZERhdGFNb2RhbCIsIl9leHBvcnRJbWFnZU1vZGFsIiwiX2V4cG9ydERhdGFNb2RhbCIsIl9leHBvcnRNYXBNb2RhbCIsIl9hZGRNYXBTdHlsZU1vZGFsIiwiX3NhdmVNYXBNb2RhbCIsIl9zaGFyZU1hcE1vZGFsIiwiX3N0eWxlcyIsIl90ZW1wbGF0ZU9iamVjdCIsIl90ZW1wbGF0ZU9iamVjdDIiLCJfdGVtcGxhdGVPYmplY3QzIiwiX3RlbXBsYXRlT2JqZWN0NCIsIl90ZW1wbGF0ZU9iamVjdDUiLCJfdGVtcGxhdGVPYmplY3Q2IiwiX3RlbXBsYXRlT2JqZWN0NyIsIl90ZW1wbGF0ZU9iamVjdDgiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJfY2FsbFN1cGVyIiwiX2dldFByb3RvdHlwZU9mMiIsIl9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMiIsIl9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QiLCJSZWZsZWN0IiwiY29uc3RydWN0IiwiY29uc3RydWN0b3IiLCJCb29sZWFuIiwicHJvdG90eXBlIiwidmFsdWVPZiIsIkRhdGFUYWJsZU1vZGFsU3R5bGUiLCJjc3MiLCJfdGFnZ2VkVGVtcGxhdGVMaXRlcmFsMiIsIm1lZGlhIiwicG9ydGFibGUiLCJwYWxtIiwic21hbGxNb2RhbENzcyIsIkxvYWREYXRhTW9kYWxTdHlsZSIsIkRlZmF1bHRTdHlsZSIsIk1vZGFsQ29udGFpbmVyRmFjdG9yeSIsImRlcHMiLCJEZWxldGVEYXRhc2V0TW9kYWxGYWN0b3J5IiwiT3ZlcldyaXRlTWFwTW9kYWxGYWN0b3J5IiwiRGF0YVRhYmxlTW9kYWxGYWN0b3J5IiwiTG9hZERhdGFNb2RhbEZhY3RvcnkiLCJFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSIsIkV4cG9ydERhdGFNb2RhbEZhY3RvcnkiLCJFeHBvcnRNYXBNb2RhbEZhY3RvcnkiLCJBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSIsIk1vZGFsRGlhbG9nRmFjdG9yeSIsIlNhdmVNYXBNb2RhbEZhY3RvcnkiLCJTaGFyZU1hcE1vZGFsRmFjdG9yeSIsIkRlbGV0ZURhdGFzZXRNb2RhbCIsIk92ZXJXcml0ZU1hcE1vZGFsIiwiRGF0YVRhYmxlTW9kYWwiLCJMb2FkRGF0YU1vZGFsIiwiRXhwb3J0SW1hZ2VNb2RhbCIsIkV4cG9ydERhdGFNb2RhbCIsIkV4cG9ydE1hcE1vZGFsIiwiQWRkTWFwU3R5bGVNb2RhbCIsIk1vZGFsRGlhbG9nIiwiU2F2ZU1hcE1vZGFsIiwiU2hhcmVNYXBNb2RhbCIsIk1vZGFsQ29udGFpbmVyIiwiX0NvbXBvbmVudCIsIl90aGlzIiwiX2NsYXNzQ2FsbENoZWNrMiIsIl9sZW4iLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiY29uY2F0IiwiZG9jdW1lbnQiLCJhZGRFdmVudExpc3RlbmVyIiwiX29uS2V5VXAiLCJldmVudCIsImtleUNvZGUiLCJLZXlFdmVudCIsIkRPTV9WS19FU0NBUEUiLCJfY2xvc2VNb2RhbCIsInByb3BzIiwidWlTdGF0ZUFjdGlvbnMiLCJ0b2dnbGVNb2RhbCIsImtleSIsInZpc1N0YXRlQWN0aW9ucyIsInJlbW92ZURhdGFzZXQiLCJtYXBTdHlsZUFjdGlvbnMiLCJhZGRDdXN0b21NYXBTdHlsZSIsImZpbGVMaXN0IiwibG9hZEZpbGVzIiwidGlsZXNldCIsInByb2Nlc3NlZE1ldGFkYXRhIiwidXBkYXRlVmlzRGF0YSIsImluZm8iLCJsYWJlbCIsIm5hbWUiLCJ0eXBlIiwiZm9ybWF0IiwiZGF0YSIsImZpZWxkcyIsInJvd3MiLCJtZXRhZGF0YSIsInN1cHBvcnRlZEZpbHRlclR5cGVzIiwiQUxMX0ZJRUxEX1RZUEVTIiwicmVhbCIsImludGVnZXIiLCJkaXNhYmxlRGF0YU9wZXJhdGlvbiIsImF1dG9DcmVhdGVMYXllcnMiLCJjZW50ZXJNYXAiLCJ1aVN0YXRlIiwiZXhwb3J0SW1hZ2UiLCJwcm9jZXNzaW5nIiwiYXBwTmFtZSIsImNsZWFudXBFeHBvcnRJbWFnZSIsImV4cG9ydERhdGEiLCJleHBvcnRNYXAiLCJFWFBPUlRfTUFQX0ZPUk1BVFMiLCJIVE1MIiwiZXhwb3J0SHRtbCIsImV4cG9ydEpzb24iLCJfcmVmIiwicHJvdmlkZXIiLCJpc1B1YmxpYyIsIm92ZXJ3cml0ZSIsImNsb3NlTW9kYWwiLCJ0b1NhdmUiLCJwcm92aWRlckFjdGlvbnMiLCJleHBvcnRGaWxlVG9DbG91ZCIsIm1hcERhdGEiLCJvcHRpb25zIiwibWFwSWRUb092ZXJ3cml0ZSIsInByb3ZpZGVyU3RhdGUiLCJzYXZlZE1hcElkIiwib25TdWNjZXNzIiwib25FeHBvcnRUb0Nsb3VkU3VjY2VzcyIsIm9uRXJyb3IiLCJvbkV4cG9ydFRvQ2xvdWRFcnJvciIsInVuZGVmaW5lZCIsIl9leHBvcnRGaWxlVG9DbG91ZCIsIl9vblNhdmVNYXAiLCJyZXNldFByb3ZpZGVyU3RhdHVzIiwicGF5bG9hZCIsImxvYWRDbG91ZE1hcCIsIm9uTG9hZENsb3VkTWFwU3VjY2VzcyIsIm9uTG9hZENsb3VkTWFwRXJyb3IiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsInZhbHVlIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwicmVuZGVyIiwiX3RoaXMyIiwiX3RoaXMkcHJvcHMiLCJjb250YWluZXJXIiwiY29udGFpbmVySCIsIm1hcFN0eWxlIiwibWFwU3RhdGUiLCJ2aXNTdGF0ZSIsInJvb3ROb2RlIiwiY3VycmVudE1vZGFsIiwiZGF0YXNldEtleVRvUmVtb3ZlIiwiZGF0YXNldHMiLCJsYXllcnMiLCJlZGl0aW5nRGF0YXNldCIsInRlbXBsYXRlIiwibW9kYWxQcm9wcyIsImlkIiwiY3JlYXRlRWxlbWVudCIsIkRBVEFfVEFCTEVfSUQiLCJ3aWR0aCIsImRhdGFJZCIsInNob3dEYXRhc2V0VGFibGUiLCJzb3J0VGFibGVDb2x1bW4iLCJwaW5UYWJsZUNvbHVtbiIsImNvcHlUYWJsZUNvbHVtbiIsInNldENvbHVtbkRpc3BsYXlGb3JtYXQiLCJjc3NTdHlsZSIsIkRFTEVURV9EQVRBX0lEIiwiZGF0YXNldCIsInRpdGxlIiwiZm9vdGVyIiwib25Db25maXJtIiwiX2RlbGV0ZURhdGFzZXQiLCJvbkNhbmNlbCIsImNvbmZpcm1CdXR0b24iLCJuZWdhdGl2ZSIsImxhcmdlIiwiY2hpbGRyZW4iLCJBRERfREFUQV9JRCIsIl9leHRlbmRzMiIsIm9uQ2xvc2UiLCJvbkZpbGVVcGxvYWQiLCJfb25GaWxlVXBsb2FkIiwib25UaWxlc2V0QWRkZWQiLCJfb25UaWxlc2V0QWRkZWQiLCJvbkxvYWRDbG91ZE1hcCIsIl9vbkxvYWRDbG91ZE1hcCIsImZpbGVMb2FkaW5nIiwiZmlsZUxvYWRpbmdQcm9ncmVzcyIsImZpbGVGb3JtYXROYW1lcyIsImdldEZpbGVGb3JtYXROYW1lcyIsImZpbGVFeHRlbnNpb25zIiwiZ2V0RmlsZUV4dGVuc2lvbnMiLCJFWFBPUlRfSU1BR0VfSUQiLCJtYXBXIiwibWFwSCIsIm9uVXBkYXRlSW1hZ2VTZXR0aW5nIiwic2V0RXhwb3J0SW1hZ2VTZXR0aW5nIiwiX29uRXhwb3J0SW1hZ2UiLCJkaXNhYmxlZCIsIkVYUE9SVF9EQVRBX0lEIiwic3VwcG9ydGVkRGF0YVR5cGVzIiwiRVhQT1JUX0RBVEFfVFlQRV9PUFRJT05TIiwiYXBwbHlDUFVGaWx0ZXIiLCJvbkNoYW5nZUV4cG9ydERhdGFUeXBlIiwic2V0RXhwb3J0RGF0YVR5cGUiLCJvbkNoYW5nZUV4cG9ydFNlbGVjdGVkRGF0YXNldCIsInNldEV4cG9ydFNlbGVjdGVkRGF0YXNldCIsIm9uQ2hhbmdlRXhwb3J0RmlsdGVyZWQiLCJzZXRFeHBvcnRGaWx0ZXJlZCIsIl9vbkV4cG9ydERhdGEiLCJFWFBPUlRfTUFQX0lEIiwia2VwbGVyR2xDb25maWciLCJzY2hlbWEiLCJnZXRDb25maWdUb1NhdmUiLCJjb25maWciLCJvbkNoYW5nZUV4cG9ydE1hcEZvcm1hdCIsInNldEV4cG9ydE1hcEZvcm1hdCIsIm9uRWRpdFVzZXJNYXBib3hBY2Nlc3NUb2tlbiIsInNldFVzZXJNYXBib3hBY2Nlc3NUb2tlbiIsIm9uQ2hhbmdlRXhwb3J0TWFwSFRNTE1vZGUiLCJzZXRFeHBvcnRIVE1MTWFwTW9kZSIsIl9vbkV4cG9ydE1hcCIsIkFERF9NQVBfU1RZTEVfSUQiLCJtYXBib3hBcGlBY2Nlc3NUb2tlbiIsIm1hcGJveEFwaVVybCIsImlucHV0U3R5bGUiLCJpbnB1dE1hcFN0eWxlIiwibG9hZEN1c3RvbU1hcFN0eWxlIiwiX29uQWRkQ3VzdG9tTWFwU3R5bGUiLCJlcnJvciIsInVybCIsIlNBVkVfTUFQX0lEIiwibWFwSW5mbyIsIm9uU2V0TWFwSW5mbyIsInNldE1hcEluZm8iLCJPVkVSV1JJVEVfTUFQX0lEIiwiX29uT3ZlcndyaXRlTWFwIiwiU0hBUkVfTUFQX0lEIiwib25FeHBvcnQiLCJfb25TaGFyZU1hcFVybCIsIl9vbkNsb3NlU2F2ZU1hcCIsInBhcmVudFNlbGVjdG9yIiwiaXNPcGVuIiwiQ29tcG9uZW50Il0sInNvdXJjZXMiOlsiLi4vc3JjL21vZGFsLWNvbnRhaW5lci50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IFJlYWN0LCB7Q29tcG9uZW50fSBmcm9tICdyZWFjdCc7XG5pbXBvcnQge2Nzc30gZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IGdldCBmcm9tICdsb2Rhc2guZ2V0JztcbmltcG9ydCBkb2N1bWVudCBmcm9tICdnbG9iYWwvZG9jdW1lbnQnO1xuXG5pbXBvcnQge0FMTF9GSUVMRF9UWVBFU30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgZXhwb3J0RGF0YSxcbiAgZ2V0RmlsZUZvcm1hdE5hbWVzLFxuICBnZXRGaWxlRXh0ZW5zaW9ucyxcbiAgTWFwU3R5bGUsXG4gIFByb3ZpZGVyU3RhdGVcbn0gZnJvbSAnQGtlcGxlci5nbC9yZWR1Y2Vycyc7XG5pbXBvcnQge2V4cG9ydEh0bWwsIGV4cG9ydE1hcCwgZXhwb3J0SnNvbiwgZXhwb3J0SW1hZ2V9IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuXG5pbXBvcnQgTW9kYWxEaWFsb2dGYWN0b3J5IGZyb20gJy4vbW9kYWxzL21vZGFsLWRpYWxvZyc7XG5cbi8vIG1vZGFsc1xuaW1wb3J0IERlbGV0ZURhdGFzZXRNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZGVsZXRlLWRhdGEtbW9kYWwnO1xuaW1wb3J0IE92ZXJXcml0ZU1hcE1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9vdmVyd3JpdGUtbWFwLW1vZGFsJztcbmltcG9ydCBEYXRhVGFibGVNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZGF0YS10YWJsZS1tb2RhbCc7XG5pbXBvcnQgTG9hZERhdGFNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvbG9hZC1kYXRhLW1vZGFsJztcbmltcG9ydCBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtaW1hZ2UtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydERhdGFNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvZXhwb3J0LWRhdGEtbW9kYWwnO1xuaW1wb3J0IEV4cG9ydE1hcE1vZGFsRmFjdG9yeSBmcm9tICcuL21vZGFscy9leHBvcnQtbWFwLW1vZGFsL2V4cG9ydC1tYXAtbW9kYWwnO1xuaW1wb3J0IEFkZE1hcFN0eWxlTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL2FkZC1tYXAtc3R5bGUtbW9kYWwnO1xuaW1wb3J0IFNhdmVNYXBNb2RhbEZhY3RvcnkgZnJvbSAnLi9tb2RhbHMvc2F2ZS1tYXAtbW9kYWwnO1xuaW1wb3J0IFNoYXJlTWFwTW9kYWxGYWN0b3J5IGZyb20gJy4vbW9kYWxzL3NoYXJlLW1hcC1tb2RhbCc7XG5cbi8vIEJyZWFrcG9pbnRzXG5pbXBvcnQge21lZGlhfSBmcm9tICdAa2VwbGVyLmdsL3N0eWxlcyc7XG5cbi8vIFRlbXBsYXRlXG5pbXBvcnQge1xuICBFWFBPUlRfREFUQV9UWVBFX09QVElPTlMsXG4gIEVYUE9SVF9NQVBfRk9STUFUUyxcbiAgS2V5RXZlbnQsXG4gIEFERF9EQVRBX0lELFxuICBEQVRBX1RBQkxFX0lELFxuICBERUxFVEVfREFUQV9JRCxcbiAgRVhQT1JUX0RBVEFfSUQsXG4gIEVYUE9SVF9JTUFHRV9JRCxcbiAgRVhQT1JUX01BUF9JRCxcbiAgQUREX01BUF9TVFlMRV9JRCxcbiAgU0FWRV9NQVBfSUQsXG4gIFNIQVJFX01BUF9JRCxcbiAgT1ZFUldSSVRFX01BUF9JRFxufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5cbmltcG9ydCB7TWFwU3RhdGUsIFVpU3RhdGUsIE9uU3VjY2Vzc0NhbGxCYWNrLCBPbkVycm9yQ2FsbEJhY2t9IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuXG5pbXBvcnQge1xuICBWaXNTdGF0ZUFjdGlvbnMsXG4gIFVJU3RhdGVBY3Rpb25zLFxuICBNYXBTdHlsZUFjdGlvbnMsXG4gIFByb3ZpZGVyQWN0aW9uc1xufSBmcm9tICdAa2VwbGVyLmdsL2FjdGlvbnMnO1xuaW1wb3J0IHtNb2RhbERpYWxvZ1Byb3BzfSBmcm9tICcuL2NvbW1vbi9tb2RhbCc7XG5pbXBvcnQge1Byb3ZpZGVyfSBmcm9tICdAa2VwbGVyLmdsL2Nsb3VkLXByb3ZpZGVycyc7XG5pbXBvcnQge1Zpc1N0YXRlfSBmcm9tICdAa2VwbGVyLmdsL3NjaGVtYXMnO1xuXG5jb25zdCBEYXRhVGFibGVNb2RhbFN0eWxlID0gY3NzYFxuICB0b3A6IDcwcHg7XG4gIHBhZGRpbmc6IDA7XG4gIHdpZHRoOiA5MHZ3O1xuICBtYXgtd2lkdGg6IDkwdnc7XG5cbiAgJHttZWRpYS5wb3J0YWJsZWBcbiAgICBwYWRkaW5nOiAwO1xuICBgfSAke21lZGlhLnBhbG1gXG4gICAgcGFkZGluZzogMDtcbiAgICBtYXJnaW46IDAgYXV0bztcbiAgYH07XG5gO1xuY29uc3Qgc21hbGxNb2RhbENzcyA9IGNzc2BcbiAgd2lkdGg6IDQwJTtcbiAgcGFkZGluZzogNDBweCA0MHB4IDMycHggNDBweDtcbmA7XG5cbmNvbnN0IExvYWREYXRhTW9kYWxTdHlsZSA9IGNzc2BcbiAgdG9wOiA2MHB4O1xuYDtcblxuY29uc3QgRGVmYXVsdFN0eWxlID0gY3NzYFxuICBtYXgtd2lkdGg6IDk2MHB4O1xuYDtcblxuZXhwb3J0IHR5cGUgTW9kYWxDb250YWluZXJQcm9wcyA9IHtcbiAgYXBwTmFtZTogc3RyaW5nO1xuICByb290Tm9kZTogUmVhY3QuUmVhY3RJbnN0YW5jZSB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIGNvbnRhaW5lclc6IG51bWJlcjtcbiAgY29udGFpbmVySDogbnVtYmVyO1xuICBtYXBib3hBcGlBY2Nlc3NUb2tlbjogc3RyaW5nO1xuICBtYXBib3hBcGlVcmw/OiBzdHJpbmc7XG4gIG1hcFN0YXRlOiBNYXBTdGF0ZTtcbiAgbWFwU3R5bGU6IE1hcFN0eWxlO1xuICB1aVN0YXRlOiBVaVN0YXRlO1xuICB2aXNTdGF0ZTogVmlzU3RhdGU7XG4gIHByb3ZpZGVyU3RhdGU6IFByb3ZpZGVyU3RhdGU7XG4gIHZpc1N0YXRlQWN0aW9uczogdHlwZW9mIFZpc1N0YXRlQWN0aW9ucztcbiAgdWlTdGF0ZUFjdGlvbnM6IHR5cGVvZiBVSVN0YXRlQWN0aW9ucztcbiAgbWFwU3R5bGVBY3Rpb25zOiB0eXBlb2YgTWFwU3R5bGVBY3Rpb25zO1xuICBwcm92aWRlckFjdGlvbnM6IHR5cGVvZiBQcm92aWRlckFjdGlvbnM7XG4gIG9uU2F2ZVRvU3RvcmFnZT86ICgpID0+IHZvaWQ7XG4gIGNsb3VkUHJvdmlkZXJzOiBQcm92aWRlcltdO1xuICBvbkxvYWRDbG91ZE1hcFN1Y2Nlc3M/OiBPblN1Y2Nlc3NDYWxsQmFjaztcbiAgb25Mb2FkQ2xvdWRNYXBFcnJvcj86IE9uRXJyb3JDYWxsQmFjaztcbiAgb25FeHBvcnRUb0Nsb3VkU3VjY2Vzcz86IE9uU3VjY2Vzc0NhbGxCYWNrO1xuICBvbkV4cG9ydFRvQ2xvdWRFcnJvcj86IE9uRXJyb3JDYWxsQmFjaztcbn07XG5cbk1vZGFsQ29udGFpbmVyRmFjdG9yeS5kZXBzID0gW1xuICBEZWxldGVEYXRhc2V0TW9kYWxGYWN0b3J5LFxuICBPdmVyV3JpdGVNYXBNb2RhbEZhY3RvcnksXG4gIERhdGFUYWJsZU1vZGFsRmFjdG9yeSxcbiAgTG9hZERhdGFNb2RhbEZhY3RvcnksXG4gIEV4cG9ydEltYWdlTW9kYWxGYWN0b3J5LFxuICBFeHBvcnREYXRhTW9kYWxGYWN0b3J5LFxuICBFeHBvcnRNYXBNb2RhbEZhY3RvcnksXG4gIEFkZE1hcFN0eWxlTW9kYWxGYWN0b3J5LFxuICBNb2RhbERpYWxvZ0ZhY3RvcnksXG4gIFNhdmVNYXBNb2RhbEZhY3RvcnksXG4gIFNoYXJlTWFwTW9kYWxGYWN0b3J5XG5dO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb2RhbENvbnRhaW5lckZhY3RvcnkoXG4gIERlbGV0ZURhdGFzZXRNb2RhbDogUmV0dXJuVHlwZTx0eXBlb2YgRGVsZXRlRGF0YXNldE1vZGFsRmFjdG9yeT4sXG4gIE92ZXJXcml0ZU1hcE1vZGFsOiBSZXR1cm5UeXBlPHR5cGVvZiBPdmVyV3JpdGVNYXBNb2RhbEZhY3Rvcnk+LFxuICBEYXRhVGFibGVNb2RhbDogUmV0dXJuVHlwZTx0eXBlb2YgRGF0YVRhYmxlTW9kYWxGYWN0b3J5PixcbiAgTG9hZERhdGFNb2RhbDogUmV0dXJuVHlwZTx0eXBlb2YgTG9hZERhdGFNb2RhbEZhY3Rvcnk+LFxuICBFeHBvcnRJbWFnZU1vZGFsOiBSZXR1cm5UeXBlPHR5cGVvZiBFeHBvcnRJbWFnZU1vZGFsRmFjdG9yeT4sXG4gIEV4cG9ydERhdGFNb2RhbDogUmV0dXJuVHlwZTx0eXBlb2YgRXhwb3J0RGF0YU1vZGFsRmFjdG9yeT4sXG4gIEV4cG9ydE1hcE1vZGFsOiBSZXR1cm5UeXBlPHR5cGVvZiBFeHBvcnRNYXBNb2RhbEZhY3Rvcnk+LFxuICBBZGRNYXBTdHlsZU1vZGFsOiBSZXR1cm5UeXBlPHR5cGVvZiBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeT4sXG4gIE1vZGFsRGlhbG9nOiBSZXR1cm5UeXBlPHR5cGVvZiBNb2RhbERpYWxvZ0ZhY3Rvcnk+LFxuICBTYXZlTWFwTW9kYWw6IFJldHVyblR5cGU8dHlwZW9mIFNhdmVNYXBNb2RhbEZhY3Rvcnk+LFxuICBTaGFyZU1hcE1vZGFsOiBSZXR1cm5UeXBlPHR5cGVvZiBTaGFyZU1hcE1vZGFsRmFjdG9yeT5cbik6IFJlYWN0LkVsZW1lbnRUeXBlPE1vZGFsQ29udGFpbmVyUHJvcHM+IHtcbiAgLyoqIEBhdWdtZW50cyBSZWFjdC5Db21wb25lbnQ8TW9kYWxDb250YWluZXJQcm9wcz4gKi9cbiAgY2xhc3MgTW9kYWxDb250YWluZXIgZXh0ZW5kcyBDb21wb25lbnQ8TW9kYWxDb250YWluZXJQcm9wcz4ge1xuICAgIC8vIFRPRE8gLSByZW1vdmUgd2hlbiBwcm9wIHR5cGVzIGFyZSBmdWxseSBleHBvcnRlZFxuICAgIGNvbXBvbmVudERpZE1vdW50ID0gKCkgPT4ge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLl9vbktleVVwKTtcbiAgICB9O1xuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLl9vbktleVVwKTtcbiAgICB9XG5cbiAgICBfb25LZXlVcCA9IGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGtleUNvZGUgPSBldmVudC5rZXlDb2RlO1xuICAgICAgaWYgKGtleUNvZGUgPT09IEtleUV2ZW50LkRPTV9WS19FU0NBUEUpIHtcbiAgICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBfY2xvc2VNb2RhbCA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvcHMudWlTdGF0ZUFjdGlvbnMudG9nZ2xlTW9kYWwobnVsbCk7XG4gICAgfTtcblxuICAgIF9kZWxldGVEYXRhc2V0ID0ga2V5ID0+IHtcbiAgICAgIHRoaXMucHJvcHMudmlzU3RhdGVBY3Rpb25zLnJlbW92ZURhdGFzZXQoa2V5KTtcbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoKTtcbiAgICB9O1xuXG4gICAgX29uQWRkQ3VzdG9tTWFwU3R5bGUgPSAoKSA9PiB7XG4gICAgICB0aGlzLnByb3BzLm1hcFN0eWxlQWN0aW9ucy5hZGRDdXN0b21NYXBTdHlsZSgpO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfb25GaWxlVXBsb2FkID0gZmlsZUxpc3QgPT4ge1xuICAgICAgdGhpcy5wcm9wcy52aXNTdGF0ZUFjdGlvbnMubG9hZEZpbGVzKGZpbGVMaXN0KTtcbiAgICB9O1xuXG4gICAgX29uVGlsZXNldEFkZGVkID0gKFxuICAgICAgdGlsZXNldDoge25hbWU6IHN0cmluZzsgdHlwZTogc3RyaW5nOyBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgYW55Pn0sXG4gICAgICBwcm9jZXNzZWRNZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICApID0+IHtcbiAgICAgIHRoaXMucHJvcHMudmlzU3RhdGVBY3Rpb25zLnVwZGF0ZVZpc0RhdGEoXG4gICAgICAgIHtcbiAgICAgICAgICBpbmZvOiB7bGFiZWw6IHRpbGVzZXQubmFtZSwgdHlwZTogdGlsZXNldC50eXBlLCBmb3JtYXQ6ICdyb3dzJ30sXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgZmllbGRzOiBwcm9jZXNzZWRNZXRhZGF0YT8uZmllbGRzIHx8IFtdLFxuICAgICAgICAgICAgcm93czogW11cbiAgICAgICAgICB9LFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAuLi5wcm9jZXNzZWRNZXRhZGF0YSxcbiAgICAgICAgICAgIC4uLnRpbGVzZXQubWV0YWRhdGFcbiAgICAgICAgICB9LFxuICAgICAgICAgIC8vIHZlY3RvciB0aWxlIGxheWVyIG9ubHkgc3VwcG9ydHMgZ3B1IGZpbHRlcmluZyBmb3Igbm93XG4gICAgICAgICAgc3VwcG9ydGVkRmlsdGVyVHlwZXM6IFtBTExfRklFTERfVFlQRVMucmVhbCwgQUxMX0ZJRUxEX1RZUEVTLmludGVnZXJdLFxuICAgICAgICAgIGRpc2FibGVEYXRhT3BlcmF0aW9uOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBhdXRvQ3JlYXRlTGF5ZXJzOiB0cnVlLFxuICAgICAgICAgIGNlbnRlck1hcDogdHJ1ZVxuICAgICAgICB9XG4gICAgICApO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfb25FeHBvcnRJbWFnZSA9ICgpID0+IHtcbiAgICAgIGlmICghdGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydEltYWdlLnByb2Nlc3NpbmcpIHtcbiAgICAgICAgZXhwb3J0SW1hZ2UodGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydEltYWdlLCBgJHt0aGlzLnByb3BzLmFwcE5hbWV9LnBuZ2ApO1xuICAgICAgICB0aGlzLnByb3BzLnVpU3RhdGVBY3Rpb25zLmNsZWFudXBFeHBvcnRJbWFnZSgpO1xuICAgICAgICB0aGlzLl9jbG9zZU1vZGFsKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIF9vbkV4cG9ydERhdGEgPSAoKSA9PiB7XG4gICAgICBleHBvcnREYXRhKHRoaXMucHJvcHMsIHRoaXMucHJvcHMudWlTdGF0ZS5leHBvcnREYXRhKTtcbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoKTtcbiAgICB9O1xuXG4gICAgX29uRXhwb3J0TWFwID0gKCkgPT4ge1xuICAgICAgY29uc3Qge3VpU3RhdGV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtmb3JtYXR9ID0gdWlTdGF0ZS5leHBvcnRNYXA7XG4gICAgICAoZm9ybWF0ID09PSBFWFBPUlRfTUFQX0ZPUk1BVFMuSFRNTCA/IGV4cG9ydEh0bWwgOiBleHBvcnRKc29uKShcbiAgICAgICAgdGhpcy5wcm9wcyxcbiAgICAgICAgdGhpcy5wcm9wcy51aVN0YXRlLmV4cG9ydE1hcFtmb3JtYXRdIHx8IHt9XG4gICAgICApO1xuICAgICAgdGhpcy5fY2xvc2VNb2RhbCgpO1xuICAgIH07XG5cbiAgICBfZXhwb3J0RmlsZVRvQ2xvdWQgPSAoe3Byb3ZpZGVyLCBpc1B1YmxpYywgb3ZlcndyaXRlLCBjbG9zZU1vZGFsfSkgPT4ge1xuICAgICAgY29uc3QgdG9TYXZlID0gZXhwb3J0TWFwKHRoaXMucHJvcHMpO1xuXG4gICAgICB0aGlzLnByb3BzLnByb3ZpZGVyQWN0aW9ucy5leHBvcnRGaWxlVG9DbG91ZCh7XG4gICAgICAgIG1hcERhdGE6IHRvU2F2ZSxcbiAgICAgICAgcHJvdmlkZXIsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBpc1B1YmxpYyxcbiAgICAgICAgICBvdmVyd3JpdGUsXG4gICAgICAgICAgbWFwSWRUb092ZXJ3cml0ZTogdGhpcy5wcm9wcy5wcm92aWRlclN0YXRlLnNhdmVkTWFwSWRcbiAgICAgICAgfSxcbiAgICAgICAgY2xvc2VNb2RhbCxcbiAgICAgICAgb25TdWNjZXNzOiB0aGlzLnByb3BzLm9uRXhwb3J0VG9DbG91ZFN1Y2Nlc3MsXG4gICAgICAgIG9uRXJyb3I6IHRoaXMucHJvcHMub25FeHBvcnRUb0Nsb3VkRXJyb3JcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBfb25TYXZlTWFwID0gKHByb3ZpZGVyLCBvdmVyd3JpdGUgPSBmYWxzZSkgPT4ge1xuICAgICAgdGhpcy5fZXhwb3J0RmlsZVRvQ2xvdWQoe1xuICAgICAgICBwcm92aWRlcixcbiAgICAgICAgaXNQdWJsaWM6IGZhbHNlLFxuICAgICAgICBvdmVyd3JpdGUsXG4gICAgICAgIGNsb3NlTW9kYWw6IHRydWVcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBfb25PdmVyd3JpdGVNYXAgPSBwcm92aWRlciA9PiB7XG4gICAgICB0aGlzLl9vblNhdmVNYXAocHJvdmlkZXIsIHRydWUpO1xuICAgIH07XG5cbiAgICBfb25TaGFyZU1hcFVybCA9IHByb3ZpZGVyID0+IHtcbiAgICAgIHRoaXMuX2V4cG9ydEZpbGVUb0Nsb3VkKHtwcm92aWRlciwgaXNQdWJsaWM6IHRydWUsIG92ZXJ3cml0ZTogZmFsc2UsIGNsb3NlTW9kYWw6IGZhbHNlfSk7XG4gICAgfTtcblxuICAgIF9vbkNsb3NlU2F2ZU1hcCA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvcHMucHJvdmlkZXJBY3Rpb25zLnJlc2V0UHJvdmlkZXJTdGF0dXMoKTtcbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoKTtcbiAgICB9O1xuXG4gICAgX29uTG9hZENsb3VkTWFwID0gcGF5bG9hZCA9PiB7XG4gICAgICB0aGlzLnByb3BzLnByb3ZpZGVyQWN0aW9ucy5sb2FkQ2xvdWRNYXAoe1xuICAgICAgICAuLi5wYXlsb2FkLFxuICAgICAgICBvblN1Y2Nlc3M6IHRoaXMucHJvcHMub25Mb2FkQ2xvdWRNYXBTdWNjZXNzLFxuICAgICAgICBvbkVycm9yOiB0aGlzLnByb3BzLm9uTG9hZENsb3VkTWFwRXJyb3JcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG4gICAgcmVuZGVyKCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBjb250YWluZXJXLFxuICAgICAgICBjb250YWluZXJILFxuICAgICAgICBtYXBTdHlsZSxcbiAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgIHVpU3RhdGUsXG4gICAgICAgIHZpc1N0YXRlLFxuICAgICAgICByb290Tm9kZSxcbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zLFxuICAgICAgICB1aVN0YXRlQWN0aW9ucyxcbiAgICAgICAgcHJvdmlkZXJTdGF0ZVxuICAgICAgfSA9IHRoaXMucHJvcHM7XG4gICAgICBjb25zdCB7Y3VycmVudE1vZGFsLCBkYXRhc2V0S2V5VG9SZW1vdmV9ID0gdWlTdGF0ZTtcbiAgICAgIGNvbnN0IHtkYXRhc2V0cywgbGF5ZXJzLCBlZGl0aW5nRGF0YXNldH0gPSB2aXNTdGF0ZTtcblxuICAgICAgbGV0IHRlbXBsYXRlOiBKU1guRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICAgICAgbGV0IG1vZGFsUHJvcHM6IFBhcnRpYWw8TW9kYWxEaWFsb2dQcm9wcz4gPSB7fTtcblxuICAgICAgLy8gVE9ETyAtIGN1cnJlbnRNb2RhbCBpcyBhIHN0cmluZ1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgaWYgKGN1cnJlbnRNb2RhbCAmJiBjdXJyZW50TW9kYWwuaWQgJiYgY3VycmVudE1vZGFsLnRlbXBsYXRlKSB7XG4gICAgICAgIC8vIGlmIGN1cnJlbnRNZG9hbCB0ZW1wbGF0ZSBpcyBhbHJlYWR5IHByb3ZpZGVkXG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gY2hlY2sgd2hldGhlciB0ZW1wbGF0ZSBpcyB2YWxpZFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRlbXBsYXRlID0gPGN1cnJlbnRNb2RhbC50ZW1wbGF0ZSAvPjtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBtb2RhbFByb3BzID0gY3VycmVudE1vZGFsLm1vZGFsUHJvcHM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2l0Y2ggKGN1cnJlbnRNb2RhbCkge1xuICAgICAgICAgIGNhc2UgREFUQV9UQUJMRV9JRDoge1xuICAgICAgICAgICAgY29uc3Qgd2lkdGggPSBjb250YWluZXJXICogMC45O1xuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxEYXRhVGFibGVNb2RhbFxuICAgICAgICAgICAgICAgIGRhdGFzZXRzPXtkYXRhc2V0c31cbiAgICAgICAgICAgICAgICBkYXRhSWQ9e2VkaXRpbmdEYXRhc2V0fVxuICAgICAgICAgICAgICAgIHNob3dEYXRhc2V0VGFibGU9e3Zpc1N0YXRlQWN0aW9ucy5zaG93RGF0YXNldFRhYmxlfVxuICAgICAgICAgICAgICAgIHNvcnRUYWJsZUNvbHVtbj17dmlzU3RhdGVBY3Rpb25zLnNvcnRUYWJsZUNvbHVtbn1cbiAgICAgICAgICAgICAgICBwaW5UYWJsZUNvbHVtbj17dmlzU3RhdGVBY3Rpb25zLnBpblRhYmxlQ29sdW1ufVxuICAgICAgICAgICAgICAgIGNvcHlUYWJsZUNvbHVtbj17dmlzU3RhdGVBY3Rpb25zLmNvcHlUYWJsZUNvbHVtbn1cbiAgICAgICAgICAgICAgICBzZXRDb2x1bW5EaXNwbGF5Rm9ybWF0PXt2aXNTdGF0ZUFjdGlvbnMuc2V0Q29sdW1uRGlzcGxheUZvcm1hdH1cbiAgICAgICAgICAgICAgICB1aVN0YXRlQWN0aW9ucz17dWlTdGF0ZUFjdGlvbnN9XG4gICAgICAgICAgICAgICAgdWlTdGF0ZT17dWlTdGF0ZX1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIFRPRE86IHdlIG5lZWQgdG8gbWFrZSB0aGlzIHdpZHRoIGNvbnNpc3RlbnQgd2l0aCB0aGUgY3NzIHJ1bGUgZGVmaW5lZCBtb2RhbC5qczozMiBtYXgtd2lkdGg6IDcwdndcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgLy8gVE9ETyBmaXggdGhpcyBhZnRlciBhZGQgdHlwZXMgdG8gVGhlbWVcbiAgICAgICAgICAgIG1vZGFsUHJvcHMuY3NzU3R5bGUgPSBjc3NgXG4gICAgICAgICAgICAgICR7RGF0YVRhYmxlTW9kYWxTdHlsZX07XG4gICAgICAgICAgICAgICR7bWVkaWEucGFsbWBcbiAgICAgICAgICAgICAgICB3aWR0aDogJHt3aWR0aH1weDtcbiAgICAgICAgICAgICAgYH07XG4gICAgICAgICAgICBgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgREVMRVRFX0RBVEFfSUQ6IHtcbiAgICAgICAgICAgIC8vIHZhbGlkYXRlIG9wdGlvbnNcbiAgICAgICAgICAgIGlmIChkYXRhc2V0S2V5VG9SZW1vdmUgJiYgZGF0YXNldHMgJiYgZGF0YXNldHNbZGF0YXNldEtleVRvUmVtb3ZlXSkge1xuICAgICAgICAgICAgICB0ZW1wbGF0ZSA9IChcbiAgICAgICAgICAgICAgICA8RGVsZXRlRGF0YXNldE1vZGFsIGRhdGFzZXQ9e2RhdGFzZXRzW2RhdGFzZXRLZXlUb1JlbW92ZV19IGxheWVycz17bGF5ZXJzfSAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnbW9kYWwudGl0bGUuZGVsZXRlRGF0YXNldCcsXG4gICAgICAgICAgICAgICAgY3NzU3R5bGU6IHNtYWxsTW9kYWxDc3MsXG4gICAgICAgICAgICAgICAgZm9vdGVyOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9uQ29uZmlybTogKCkgPT4gdGhpcy5fZGVsZXRlRGF0YXNldChkYXRhc2V0S2V5VG9SZW1vdmUpLFxuICAgICAgICAgICAgICAgIG9uQ2FuY2VsOiB0aGlzLl9jbG9zZU1vZGFsLFxuICAgICAgICAgICAgICAgIGNvbmZpcm1CdXR0b246IHtcbiAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgbGFyZ2U6IHRydWUsXG4gICAgICAgICAgICAgICAgICBjaGlsZHJlbjogJ21vZGFsLmJ1dHRvbi5kZWxldGUnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7IC8vIGluIGNhc2Ugd2UgYWRkIGEgbmV3IGNhc2UgYWZ0ZXIgdGhpcyBvbmVcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSBBRERfREFUQV9JRDpcbiAgICAgICAgICAgIHRlbXBsYXRlID0gKFxuICAgICAgICAgICAgICA8TG9hZERhdGFNb2RhbFxuICAgICAgICAgICAgICAgIHsuLi5wcm92aWRlclN0YXRlfVxuICAgICAgICAgICAgICAgIG9uQ2xvc2U9e3RoaXMuX2Nsb3NlTW9kYWx9XG4gICAgICAgICAgICAgICAgb25GaWxlVXBsb2FkPXt0aGlzLl9vbkZpbGVVcGxvYWR9XG4gICAgICAgICAgICAgICAgb25UaWxlc2V0QWRkZWQ9e3RoaXMuX29uVGlsZXNldEFkZGVkfVxuICAgICAgICAgICAgICAgIG9uTG9hZENsb3VkTWFwPXt0aGlzLl9vbkxvYWRDbG91ZE1hcH1cbiAgICAgICAgICAgICAgICBsb2FkRmlsZXM9e3VpU3RhdGUubG9hZEZpbGVzfVxuICAgICAgICAgICAgICAgIGZpbGVMb2FkaW5nPXt2aXNTdGF0ZS5maWxlTG9hZGluZ31cbiAgICAgICAgICAgICAgICBmaWxlTG9hZGluZ1Byb2dyZXNzPXt2aXNTdGF0ZS5maWxlTG9hZGluZ1Byb2dyZXNzfVxuICAgICAgICAgICAgICAgIGZpbGVGb3JtYXROYW1lcz17Z2V0RmlsZUZvcm1hdE5hbWVzKHRoaXMucHJvcHMudmlzU3RhdGUpfVxuICAgICAgICAgICAgICAgIGZpbGVFeHRlbnNpb25zPXtnZXRGaWxlRXh0ZW5zaW9ucyh0aGlzLnByb3BzLnZpc1N0YXRlKX1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICB0aXRsZTogJ21vZGFsLnRpdGxlLmFkZERhdGFUb01hcCcsXG4gICAgICAgICAgICAgIGNzc1N0eWxlOiBMb2FkRGF0YU1vZGFsU3R5bGUsXG4gICAgICAgICAgICAgIGZvb3RlcjogZmFsc2UsXG4gICAgICAgICAgICAgIG9uQ29uZmlybTogdGhpcy5fY2xvc2VNb2RhbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgRVhQT1JUX0lNQUdFX0lEOlxuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxFeHBvcnRJbWFnZU1vZGFsXG4gICAgICAgICAgICAgICAgZXhwb3J0SW1hZ2U9e3VpU3RhdGUuZXhwb3J0SW1hZ2V9XG4gICAgICAgICAgICAgICAgbWFwVz17Y29udGFpbmVyV31cbiAgICAgICAgICAgICAgICBtYXBIPXtjb250YWluZXJIfVxuICAgICAgICAgICAgICAgIG9uVXBkYXRlSW1hZ2VTZXR0aW5nPXt1aVN0YXRlQWN0aW9ucy5zZXRFeHBvcnRJbWFnZVNldHRpbmd9XG4gICAgICAgICAgICAgICAgY2xlYW51cEV4cG9ydEltYWdlPXt1aVN0YXRlQWN0aW9ucy5jbGVhbnVwRXhwb3J0SW1hZ2V9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbW9kYWxQcm9wcyA9IHtcbiAgICAgICAgICAgICAgdGl0bGU6ICdtb2RhbC50aXRsZS5leHBvcnRJbWFnZScsXG4gICAgICAgICAgICAgIGNzc1N0eWxlOiAnJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiB0cnVlLFxuICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgb25Db25maXJtOiB0aGlzLl9vbkV4cG9ydEltYWdlLFxuICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiB7XG4gICAgICAgICAgICAgICAgbGFyZ2U6IHRydWUsXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHVpU3RhdGUuZXhwb3J0SW1hZ2UucHJvY2Vzc2luZyxcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogJ21vZGFsLmJ1dHRvbi5kb3dubG9hZCdcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgRVhQT1JUX0RBVEFfSUQ6XG4gICAgICAgICAgICB0ZW1wbGF0ZSA9IChcbiAgICAgICAgICAgICAgPEV4cG9ydERhdGFNb2RhbFxuICAgICAgICAgICAgICAgIHsuLi51aVN0YXRlLmV4cG9ydERhdGF9XG4gICAgICAgICAgICAgICAgc3VwcG9ydGVkRGF0YVR5cGVzPXtFWFBPUlRfREFUQV9UWVBFX09QVElPTlN9XG4gICAgICAgICAgICAgICAgZGF0YXNldHM9e2RhdGFzZXRzfVxuICAgICAgICAgICAgICAgIGFwcGx5Q1BVRmlsdGVyPXt0aGlzLnByb3BzLnZpc1N0YXRlQWN0aW9ucy5hcHBseUNQVUZpbHRlcn1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydERhdGFUeXBlPXt1aVN0YXRlQWN0aW9ucy5zZXRFeHBvcnREYXRhVHlwZX1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydFNlbGVjdGVkRGF0YXNldD17dWlTdGF0ZUFjdGlvbnMuc2V0RXhwb3J0U2VsZWN0ZWREYXRhc2V0fVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlRXhwb3J0RmlsdGVyZWQ9e3VpU3RhdGVBY3Rpb25zLnNldEV4cG9ydEZpbHRlcmVkfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG1vZGFsUHJvcHMgPSB7XG4gICAgICAgICAgICAgIHRpdGxlOiAnbW9kYWwudGl0bGUuZXhwb3J0RGF0YScsXG4gICAgICAgICAgICAgIGNzc1N0eWxlOiAnJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiB0cnVlLFxuICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgb25Db25maXJtOiB0aGlzLl9vbkV4cG9ydERhdGEsXG4gICAgICAgICAgICAgIGNvbmZpcm1CdXR0b246IHtcbiAgICAgICAgICAgICAgICBsYXJnZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogJ21vZGFsLmJ1dHRvbi5leHBvcnQnXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIEVYUE9SVF9NQVBfSUQ6IHtcbiAgICAgICAgICAgIGNvbnN0IGtlcGxlckdsQ29uZmlnID0gdmlzU3RhdGUuc2NoZW1hLmdldENvbmZpZ1RvU2F2ZSh7XG4gICAgICAgICAgICAgIG1hcFN0eWxlLFxuICAgICAgICAgICAgICB2aXNTdGF0ZSxcbiAgICAgICAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgICAgICAgIHVpU3RhdGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGVtcGxhdGUgPSAoXG4gICAgICAgICAgICAgIDxFeHBvcnRNYXBNb2RhbFxuICAgICAgICAgICAgICAgIGNvbmZpZz17a2VwbGVyR2xDb25maWd9XG4gICAgICAgICAgICAgICAgb3B0aW9ucz17dWlTdGF0ZS5leHBvcnRNYXB9XG4gICAgICAgICAgICAgICAgb25DaGFuZ2VFeHBvcnRNYXBGb3JtYXQ9e3VpU3RhdGVBY3Rpb25zLnNldEV4cG9ydE1hcEZvcm1hdH1cbiAgICAgICAgICAgICAgICBvbkVkaXRVc2VyTWFwYm94QWNjZXNzVG9rZW49e3VpU3RhdGVBY3Rpb25zLnNldFVzZXJNYXBib3hBY2Nlc3NUb2tlbn1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZUV4cG9ydE1hcEhUTUxNb2RlPXt1aVN0YXRlQWN0aW9ucy5zZXRFeHBvcnRIVE1MTWFwTW9kZX1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtb2RhbFByb3BzID0ge1xuICAgICAgICAgICAgICB0aXRsZTogJ21vZGFsLnRpdGxlLmV4cG9ydE1hcCcsXG4gICAgICAgICAgICAgIGNzc1N0eWxlOiAnJyxcbiAgICAgICAgICAgICAgZm9vdGVyOiB0cnVlLFxuICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5fY2xvc2VNb2RhbCxcbiAgICAgICAgICAgICAgb25Db25maXJtOiB0aGlzLl9vbkV4cG9ydE1hcCxcbiAgICAgICAgICAgICAgY29uZmlybUJ1dHRvbjoge1xuICAgICAgICAgICAgICAgIGxhcmdlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoaWxkcmVuOiAnbW9kYWwuYnV0dG9uLmV4cG9ydCdcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIEFERF9NQVBfU1RZTEVfSUQ6XG4gICAgICAgICAgICB0ZW1wbGF0ZSA9IChcbiAgICAgICAgICAgICAgPEFkZE1hcFN0eWxlTW9kYWxcbiAgICAgICAgICAgICAgICBtYXBib3hBcGlBY2Nlc3NUb2tlbj17dGhpcy5wcm9wcy5tYXBib3hBcGlBY2Nlc3NUb2tlbn1cbiAgICAgICAgICAgICAgICBtYXBib3hBcGlVcmw9e3RoaXMucHJvcHMubWFwYm94QXBpVXJsfVxuICAgICAgICAgICAgICAgIG1hcFN0YXRlPXt0aGlzLnByb3BzLm1hcFN0YXRlfVxuICAgICAgICAgICAgICAgIGlucHV0U3R5bGU9e21hcFN0eWxlLmlucHV0U3R5bGV9XG4gICAgICAgICAgICAgICAgaW5wdXRNYXBTdHlsZT17dGhpcy5wcm9wcy5tYXBTdHlsZUFjdGlvbnMuaW5wdXRNYXBTdHlsZX1cbiAgICAgICAgICAgICAgICBsb2FkQ3VzdG9tTWFwU3R5bGU9e3RoaXMucHJvcHMubWFwU3R5bGVBY3Rpb25zLmxvYWRDdXN0b21NYXBTdHlsZX1cbiAgICAgICAgICAgIC