kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
463 lines (384 loc) • 56.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof3 = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
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 _window = require("global/window");
var _redux = require("redux");
var _styledComponents = _interopRequireWildcard(require("styled-components"));
var _reselect = require("reselect");
var _keplerglConnect = require("../connect/keplergl-connect");
var VisStateActions = _interopRequireWildcard(require("../actions/vis-state-actions"));
var MapStateActions = _interopRequireWildcard(require("../actions/map-state-actions"));
var MapStyleActions = _interopRequireWildcard(require("../actions/map-style-actions"));
var UIStateActions = _interopRequireWildcard(require("../actions/ui-state-actions"));
var _defaultSettings = require("../constants/default-settings");
var _userFeedbacks = require("../constants/user-feedbacks");
var _sidePanel = _interopRequireDefault(require("./side-panel"));
var _mapContainer = _interopRequireDefault(require("./map-container"));
var _bottomWidget = _interopRequireDefault(require("./bottom-widget"));
var _modalContainer = _interopRequireDefault(require("./modal-container"));
var _plotContainer = _interopRequireDefault(require("./plot-container"));
var _notificationPanel = _interopRequireDefault(require("./notification-panel"));
var _utils = require("../utils/utils");
var _mapboxUtils = require("../utils/mapbox-utils");
var _base = require("../styles/base");
var _continuousColorLegend = _interopRequireDefault(require("react-vis/dist/legends/continuous-color-legend"));
var _templateObject;
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 || _typeof3(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; } }
// Maybe we should think about exporting this or creating a variable
// as part of the base.js theme
var GlobalStyle = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n font-family: ", ";\n font-weight: ", ";\n font-size: ", ";\n line-height: ", ";\n margin-left: ", ";\n margin-right: 0px;\n *,\n *:before,\n *:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n }\n\n ul {\n margin: 0;\n padding: 0;\n }\n\n li {\n margin: 0;\n }\n\n a {\n text-decoration: none;\n color: ", ";\n }\n"])), function (props) {
return props.theme.fontFamily;
}, function (props) {
return props.theme.fontWeight;
}, function (props) {
return props.theme.fontSize;
}, function (props) {
return props.theme.lineHeight;
}, function (props) {
return props.sidePanel === null ? '0px' : '381px';
}, function (props) {
return props.theme.labelColor;
});
KeplerGlFactory.deps = [_bottomWidget["default"], _mapContainer["default"], _modalContainer["default"], _sidePanel["default"], _plotContainer["default"], _notificationPanel["default"]];
function KeplerGlFactory(BottomWidget, MapContainer, ModalWrapper, SidePanel, PlotContainer, NotificationPanel) {
var KeplerGL = /*#__PURE__*/function (_Component) {
(0, _inherits2["default"])(KeplerGL, _Component);
var _super = _createSuper(KeplerGL);
function KeplerGL() {
var _this;
(0, _classCallCheck2["default"])(this, KeplerGL);
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), "root", (0, _react.createRef)());
/* selector */
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "themeSelector", function (props) {
return props.theme;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "availableThemeSelector", (0, _reselect.createSelector)(_this.themeSelector, function (theme) {
return (0, _typeof2["default"])(theme) === 'object' ? _objectSpread(_objectSpread({}, _base.theme), theme) : theme === _defaultSettings.THEME.light ? _base.themeLT : theme;
}));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_loadMapStyle", function () {
var defaultStyles = Object.values(_this.props.mapStyle.mapStyles); // add id to custom map styles if not given
var customStyles = (_this.props.mapStyles || []).map(function (ms) {
return _objectSpread(_objectSpread({}, ms), {}, {
id: ms.id || (0, _utils.generateHashId)()
});
});
var allStyles = [].concat((0, _toConsumableArray2["default"])(customStyles), (0, _toConsumableArray2["default"])(defaultStyles)).reduce(function (accu, style) {
var hasStyleObject = style.style && (0, _typeof2["default"])(style.style) === 'object';
accu[hasStyleObject ? 'toLoad' : 'toRequest'][style.id] = style;
return accu;
}, {
toLoad: {},
toRequest: {}
});
_this.props.mapStyleActions.loadMapStyles(allStyles.toLoad);
_this.props.mapStyleActions.requestMapStyles(allStyles.toRequest);
});
return _this;
}
(0, _createClass2["default"])(KeplerGL, [{
key: "componentWillMount",
value: function componentWillMount() {
this._validateMapboxToken();
this._loadMapStyle(this.props.mapStyles);
this._handleResize(this.props);
}
}, {
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(nextProps) {
if ( // if dimension props has changed
this.props.height !== nextProps.height || this.props.width !== nextProps.width || // react-map-gl will dispatch updateViewport after this._handleResize is called
// here we check if this.props.mapState.height is sync with props.height
nextProps.height !== this.props.mapState.height || nextProps.uiState.activeSidePanel !== this.props.uiState.activeSidePanel) {
this._handleResize(nextProps);
}
}
}, {
key: "_validateMapboxToken",
value: function _validateMapboxToken() {
var mapboxApiAccessToken = this.props.mapboxApiAccessToken;
if (!(0, _mapboxUtils.validateToken)(mapboxApiAccessToken)) {
_window.console.warn(_userFeedbacks.MISSING_MAPBOX_TOKEN);
}
}
}, {
key: "_handleResize",
value: function _handleResize(_ref) {
var width = _ref.width,
height = _ref.height,
uiState = _ref.uiState;
width = uiState.activeSidePanel === null ? width : width - 381;
if (!Number.isFinite(width) || !Number.isFinite(height)) {
_window.console.warn('width and height is required');
return;
}
this.props.mapStateActions.updateMap({
width: width / (1 + Number(this.props.mapState.isSplit)),
height: height
});
}
}, {
key: "render",
value: function render() {
var _this$props = this.props,
auth = _this$props.auth,
project = _this$props.project,
id = _this$props.id,
appName = _this$props.appName,
version = _this$props.version,
onSaveMap = _this$props.onSaveMap,
onViewStateChange = _this$props.onViewStateChange,
width = _this$props.width,
height = _this$props.height,
mapboxApiAccessToken = _this$props.mapboxApiAccessToken,
mapboxApiUrl = _this$props.mapboxApiUrl,
getMapboxRef = _this$props.getMapboxRef,
mapStyle = _this$props.mapStyle,
mapState = _this$props.mapState,
uiState = _this$props.uiState,
visState = _this$props.visState,
visStateActions = _this$props.visStateActions,
mapStateActions = _this$props.mapStateActions,
mapStyleActions = _this$props.mapStyleActions,
uiStateActions = _this$props.uiStateActions;
var filters = visState.filters,
layers = visState.layers,
widgets = visState.widgets,
splitMaps = visState.splitMaps,
layerOrder = visState.layerOrder,
layerBlending = visState.layerBlending,
layerClasses = visState.layerClasses,
widgetOrder = visState.widgetOrder,
widgetClasses = visState.widgetClasses,
interactionConfig = visState.interactionConfig,
datasets = visState.datasets,
layerData = visState.layerData,
hoverInfo = visState.hoverInfo,
clicked = visState.clicked,
mousePos = visState.mousePos,
animationConfig = visState.animationConfig;
var notificationPanelFields = {
removeNotification: uiStateActions.removeNotification,
notifications: uiState.notifications
};
var sideFields = {
appName: appName,
version: version,
auth: auth,
project: project,
datasets: datasets,
filters: filters,
layers: layers,
layerOrder: layerOrder,
layerClasses: layerClasses,
widgets: widgets,
widgetOrder: widgetOrder,
widgetClasses: widgetClasses,
interactionConfig: interactionConfig,
mapStyle: mapStyle,
layerBlending: layerBlending,
onSaveMap: onSaveMap,
uiState: uiState,
mapState: mapState,
mapStyleActions: mapStyleActions,
visStateActions: visStateActions,
uiStateActions: uiStateActions,
width: this.props.sidePanelWidth
};
var mapFields = {
auth: auth,
project: project,
datasets: datasets,
getMapboxRef: getMapboxRef,
mapboxApiAccessToken: mapboxApiAccessToken,
mapboxApiUrl: mapboxApiUrl,
mapState: mapState,
uiState: uiState,
editor: visState.editor,
mapStyle: mapStyle,
layers: layers,
layerOrder: layerOrder,
layerData: layerData,
layerBlending: layerBlending,
filters: filters,
widgets: widgets,
interactionConfig: interactionConfig,
hoverInfo: hoverInfo,
clicked: clicked,
mousePos: mousePos,
readOnly: uiState.readOnly,
onViewStateChange: onViewStateChange,
uiStateActions: uiStateActions,
visStateActions: visStateActions,
mapStateActions: mapStateActions,
animationConfig: animationConfig
};
var isSplit = splitMaps && splitMaps.length > 1;
var containerW = mapState.width * (Number(isSplit) + 1);
var mapContainers = !isSplit ? [/*#__PURE__*/_react["default"].createElement(MapContainer, (0, _extends2["default"])({
id: "save",
key: 0,
index: 0
}, mapFields, {
mapLayers: isSplit ? splitMaps[0].layers : null
}))] : splitMaps.map(function (settings, index) {
return (/*#__PURE__*/_react["default"].createElement(MapContainer, (0, _extends2["default"])({
id: "save",
key: index,
index: index
}, mapFields, {
mapLayers: splitMaps[index].layers
}))
);
});
var isExporting = uiState.exportImage.exporting;
var theme = this.availableThemeSelector(this.props); // width = uiState.activeSidePanel === null ? width : width - 381;
return (/*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(SidePanel, sideFields), /*#__PURE__*/_react["default"].createElement(_styledComponents.ThemeProvider, {
theme: theme
}, /*#__PURE__*/_react["default"].createElement(GlobalStyle, {
width: width,
height: height,
sidePanel: uiState.activeSidePanel,
className: "kepler-gl",
id: "kepler-gl__".concat(id),
ref: this.root
}, /*#__PURE__*/_react["default"].createElement("div", {
className: "maps",
style: {
display: 'flex'
}
}, mapContainers), isExporting && /*#__PURE__*/_react["default"].createElement(PlotContainer, {
width: width,
height: height,
exportImageSetting: uiState.exportImage,
mapFields: mapFields,
addNotification: uiStateActions.addNotification,
startExportingImage: uiStateActions.startExportingImage,
setExportImageDataUri: uiStateActions.setExportImageDataUri,
setExportImageError: uiStateActions.setExportImageError
}), /*#__PURE__*/_react["default"].createElement(BottomWidget, {
filters: filters,
datasets: datasets,
uiState: uiState,
layers: layers,
animationConfig: animationConfig,
visStateActions: visStateActions,
sidePanelWidth: uiState.readOnly ? 0 : this.props.sidePanelWidth + _defaultSettings.DIMENSIONS.sidePanel.margin.left,
containerW: containerW
}), /*#__PURE__*/_react["default"].createElement(ModalWrapper, {
mapStyle: mapStyle,
visState: visState,
mapState: mapState,
uiState: uiState,
mapboxApiAccessToken: mapboxApiAccessToken,
mapboxApiUrl: mapboxApiUrl,
visStateActions: visStateActions,
uiStateActions: uiStateActions,
mapStyleActions: mapStyleActions,
rootNode: this.root.current,
containerW: containerW,
containerH: mapState.height
}))))
);
}
}]);
return KeplerGL;
}(_react.Component);
(0, _defineProperty2["default"])(KeplerGL, "defaultProps", {
mapStyles: [],
mapStylesReplaceDefault: false,
mapboxApiUrl: _defaultSettings.DEFAULT_MAPBOX_API_URL,
width: 800,
height: 800,
appName: _defaultSettings.KEPLER_GL_NAME,
version: _defaultSettings.KEPLER_GL_VERSION,
sidePanelWidth: _defaultSettings.DIMENSIONS.sidePanel.width,
theme: {}
});
return (0, _keplerglConnect.connect)(mapStateToProps, makeMapDispatchToProps)((0, _styledComponents.withTheme)(KeplerGL));
}
function mapStateToProps(state, props) {
return _objectSpread(_objectSpread({}, props), {}, {
visState: state.visState,
mapStyle: state.mapStyle,
mapState: state.mapState,
uiState: state.uiState,
auth: props.state.auth,
project: props.state.project
});
}
var defaultUserActions = {};
var getDispatch = function getDispatch(dispatch) {
return dispatch;
};
var getUserActions = function getUserActions(dispatch, props) {
return props.actions || defaultUserActions;
};
function makeGetActionCreators() {
return (0, _reselect.createSelector)([getDispatch, getUserActions], function (dispatch, userActions) {
var _map = [VisStateActions, MapStateActions, MapStyleActions, UIStateActions].map(function (actions) {
return (0, _redux.bindActionCreators)(mergeActions(actions, userActions), dispatch);
}),
_map2 = (0, _slicedToArray2["default"])(_map, 4),
visStateActions = _map2[0],
mapStateActions = _map2[1],
mapStyleActions = _map2[2],
uiStateActions = _map2[3];
return {
visStateActions: visStateActions,
mapStateActions: mapStateActions,
mapStyleActions: mapStyleActions,
uiStateActions: uiStateActions,
dispatch: dispatch
};
});
}
function makeMapDispatchToProps() {
var getActionCreators = makeGetActionCreators();
var mapDispatchToProps = function mapDispatchToProps(dispatch, ownProps) {
var groupedActionCreators = getActionCreators(dispatch, ownProps);
return _objectSpread(_objectSpread({}, groupedActionCreators), {}, {
dispatch: dispatch
});
};
return mapDispatchToProps;
}
/**
* Override default kepler.gl actions with user defined actions using the same key
*/
function mergeActions(actions, userActions) {
var overrides = {};
for (var key in userActions) {
if (userActions.hasOwnProperty(key) && actions.hasOwnProperty(key)) {
overrides[key] = userActions[key];
}
}
return _objectSpread(_objectSpread({}, actions), overrides);
}
var _default = exports["default"] = KeplerGlFactory;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL2tlcGxlci1nbC5qcyJdLCJuYW1lcyI6WyJHbG9iYWxTdHlsZSIsInN0eWxlZCIsImRpdiIsInByb3BzIiwidGhlbWUiLCJmb250RmFtaWx5IiwiZm9udFdlaWdodCIsImZvbnRTaXplIiwibGluZUhlaWdodCIsInNpZGVQYW5lbCIsImxhYmVsQ29sb3IiLCJLZXBsZXJHbEZhY3RvcnkiLCJkZXBzIiwiQm90dG9tV2lkZ2V0RmFjdG9yeSIsIk1hcENvbnRhaW5lckZhY3RvcnkiLCJNb2RhbENvbnRhaW5lckZhY3RvcnkiLCJTaWRlUGFuZWxGYWN0b3J5IiwiUGxvdENvbnRhaW5lckZhY3RvcnkiLCJOb3RpZmljYXRpb25QYW5lbEZhY3RvcnkiLCJCb3R0b21XaWRnZXQiLCJNYXBDb250YWluZXIiLCJNb2RhbFdyYXBwZXIiLCJTaWRlUGFuZWwiLCJQbG90Q29udGFpbmVyIiwiTm90aWZpY2F0aW9uUGFuZWwiLCJLZXBsZXJHTCIsInRoZW1lU2VsZWN0b3IiLCJiYXNpY1RoZW1lIiwiVEhFTUUiLCJsaWdodCIsInRoZW1lTFQiLCJkZWZhdWx0U3R5bGVzIiwiT2JqZWN0IiwidmFsdWVzIiwibWFwU3R5bGUiLCJtYXBTdHlsZXMiLCJjdXN0b21TdHlsZXMiLCJtYXAiLCJtcyIsImlkIiwiYWxsU3R5bGVzIiwicmVkdWNlIiwiYWNjdSIsInN0eWxlIiwiaGFzU3R5bGVPYmplY3QiLCJ0b0xvYWQiLCJ0b1JlcXVlc3QiLCJtYXBTdHlsZUFjdGlvbnMiLCJsb2FkTWFwU3R5bGVzIiwicmVxdWVzdE1hcFN0eWxlcyIsIl92YWxpZGF0ZU1hcGJveFRva2VuIiwiX2xvYWRNYXBTdHlsZSIsIl9oYW5kbGVSZXNpemUiLCJuZXh0UHJvcHMiLCJoZWlnaHQiLCJ3aWR0aCIsIm1hcFN0YXRlIiwidWlTdGF0ZSIsImFjdGl2ZVNpZGVQYW5lbCIsIm1hcGJveEFwaUFjY2Vzc1Rva2VuIiwiQ29uc29sZSIsIndhcm4iLCJNSVNTSU5HX01BUEJPWF9UT0tFTiIsIk51bWJlciIsImlzRmluaXRlIiwibWFwU3RhdGVBY3Rpb25zIiwidXBkYXRlTWFwIiwiaXNTcGxpdCIsImF1dGgiLCJwcm9qZWN0IiwiYXBwTmFtZSIsInZlcnNpb24iLCJvblNhdmVNYXAiLCJvblZpZXdTdGF0ZUNoYW5nZSIsIm1hcGJveEFwaVVybCIsImdldE1hcGJveFJlZiIsInZpc1N0YXRlIiwidmlzU3RhdGVBY3Rpb25zIiwidWlTdGF0ZUFjdGlvbnMiLCJmaWx0ZXJzIiwibGF5ZXJzIiwid2lkZ2V0cyIsInNwbGl0TWFwcyIsImxheWVyT3JkZXIiLCJsYXllckJsZW5kaW5nIiwibGF5ZXJDbGFzc2VzIiwid2lkZ2V0T3JkZXIiLCJ3aWRnZXRDbGFzc2VzIiwiaW50ZXJhY3Rpb25Db25maWciLCJkYXRhc2V0cyIsImxheWVyRGF0YSIsImhvdmVySW5mbyIsImNsaWNrZWQiLCJtb3VzZVBvcyIsImFuaW1hdGlvbkNvbmZpZyIsIm5vdGlmaWNhdGlvblBhbmVsRmllbGRzIiwicmVtb3ZlTm90aWZpY2F0aW9uIiwibm90aWZpY2F0aW9ucyIsInNpZGVGaWVsZHMiLCJzaWRlUGFuZWxXaWR0aCIsIm1hcEZpZWxkcyIsImVkaXRvciIsInJlYWRPbmx5IiwibGVuZ3RoIiwiY29udGFpbmVyVyIsIm1hcENvbnRhaW5lcnMiLCJzZXR0aW5ncyIsImluZGV4IiwiaXNFeHBvcnRpbmciLCJleHBvcnRJbWFnZSIsImV4cG9ydGluZyIsImF2YWlsYWJsZVRoZW1lU2VsZWN0b3IiLCJyb290IiwiZGlzcGxheSIsImFkZE5vdGlmaWNhdGlvbiIsInN0YXJ0RXhwb3J0aW5nSW1hZ2UiLCJzZXRFeHBvcnRJbWFnZURhdGFVcmkiLCJzZXRFeHBvcnRJbWFnZUVycm9yIiwiRElNRU5TSU9OUyIsIm1hcmdpbiIsImxlZnQiLCJjdXJyZW50IiwiQ29tcG9uZW50IiwibWFwU3R5bGVzUmVwbGFjZURlZmF1bHQiLCJERUZBVUxUX01BUEJPWF9BUElfVVJMIiwiS0VQTEVSX0dMX05BTUUiLCJLRVBMRVJfR0xfVkVSU0lPTiIsIm1hcFN0YXRlVG9Qcm9wcyIsIm1ha2VNYXBEaXNwYXRjaFRvUHJvcHMiLCJzdGF0ZSIsImRlZmF1bHRVc2VyQWN0aW9ucyIsImdldERpc3BhdGNoIiwiZGlzcGF0Y2giLCJnZXRVc2VyQWN0aW9ucyIsImFjdGlvbnMiLCJtYWtlR2V0QWN0aW9uQ3JlYXRvcnMiLCJ1c2VyQWN0aW9ucyIsIlZpc1N0YXRlQWN0aW9ucyIsIk1hcFN0YXRlQWN0aW9ucyIsIk1hcFN0eWxlQWN0aW9ucyIsIlVJU3RhdGVBY3Rpb25zIiwibWVyZ2VBY3Rpb25zIiwiZ2V0QWN0aW9uQ3JlYXRvcnMiLCJtYXBEaXNwYXRjaFRvUHJvcHMiLCJvd25Qcm9wcyIsImdyb3VwZWRBY3Rpb25DcmVhdG9ycyIsIm92ZXJyaWRlcyIsImtleSIsImhhc093blByb3BlcnR5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFRQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFFQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQUVBO0FBQ0E7QUFDQSxJQUFNQSxXQUFXLEdBQUdDLDZCQUFPQyxHQUFWLCtlQUNBLFVBQUFDLEtBQUs7QUFBQSxTQUFJQSxLQUFLLENBQUNDLEtBQU4sQ0FBWUMsVUFBaEI7QUFBQSxDQURMLEVBRUEsVUFBQUYsS0FBSztBQUFBLFNBQUlBLEtBQUssQ0FBQ0MsS0FBTixDQUFZRSxVQUFoQjtBQUFBLENBRkwsRUFHRixVQUFBSCxLQUFLO0FBQUEsU0FBSUEsS0FBSyxDQUFDQyxLQUFOLENBQVlHLFFBQWhCO0FBQUEsQ0FISCxFQUlBLFVBQUFKLEtBQUs7QUFBQSxTQUFJQSxLQUFLLENBQUNDLEtBQU4sQ0FBWUksVUFBaEI7QUFBQSxDQUpMLEVBS0EsVUFBQUwsS0FBSztBQUFBLFNBQUtB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QUFDYyxjQUFSLENBQXVCRCxHQUF2QixDQUF2QyxFQUFvRTtBQUNsRUQsTUFBQUEsU0FBUyxDQUFDQyxHQUFELENBQVQsR0FBaUJYLFdBQVcsQ0FBQ1csR0FBRCxDQUE1QjtBQUNEO0FBQ0Y7O0FBRUQseUNBQVdiLE9BQVgsR0FBdUJZLFNBQXZCO0FBQ0Q7O29DQUVjdkksZSIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudCwgY3JlYXRlUmVmfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQge2JpbmRBY3Rpb25DcmVhdG9yc30gZnJvbSAncmVkdXgnO1xuaW1wb3J0IHN0eWxlZCwge1RoZW1lUHJvdmlkZXIsIHdpdGhUaGVtZX0gZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtjcmVhdGVTZWxlY3Rvcn0gZnJvbSAncmVzZWxlY3QnO1xuaW1wb3J0IHtjb25uZWN0IGFzIGtlcGxlckdsQ29ubmVjdH0gZnJvbSAnY29ubmVjdC9rZXBsZXJnbC1jb25uZWN0JztcblxuaW1wb3J0ICogYXMgVmlzU3RhdGVBY3Rpb25zIGZyb20gJ2FjdGlvbnMvdmlzLXN0YXRlLWFjdGlvbnMnO1xuaW1wb3J0ICogYXMgTWFwU3RhdGVBY3Rpb25zIGZyb20gJ2FjdGlvbnMvbWFwLXN0YXRlLWFjdGlvbnMnO1xuaW1wb3J0ICogYXMgTWFwU3R5bGVBY3Rpb25zIGZyb20gJ2FjdGlvbnMvbWFwLXN0eWxlLWFjdGlvbnMnO1xuaW1wb3J0ICogYXMgVUlTdGF0ZUFjdGlvbnMgZnJvbSAnYWN0aW9ucy91aS1zdGF0ZS1hY3Rpb25zJztcblxuaW1wb3J0IHtcbiAgRVhQT1JUX0lNQUdFX0lELFxuICBESU1FTlNJT05TLFxuICBLRVBMRVJfR0xfTkFNRSxcbiAgS0VQTEVSX0dMX1ZFUlNJT04sXG4gIFRIRU1FLFxuICBERUZBVUxUX01BUEJPWF9BUElfVVJMXG59IGZyb20gJ2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcbmltcG9ydCB7TUlTU0lOR19NQVBCT1hfVE9LRU59IGZyb20gJ2NvbnN0YW50cy91c2VyLWZlZWRiYWNrcyc7XG5cbmltcG9ydCBTaWRlUGFuZWxGYWN0b3J5IGZyb20gJy4vc2lkZS1wYW5lbCc7XG5pbXBvcnQgTWFwQ29udGFpbmVyRmFjdG9yeSBmcm9tICcuL21hcC1jb250YWluZXInO1xuaW1wb3J0IEJvdHRvbVdpZGdldEZhY3RvcnkgZnJvbSAnLi9ib3R0b20td2lkZ2V0JztcbmltcG9ydCBNb2RhbENvbnRhaW5lckZhY3RvcnkgZnJvbSAnLi9tb2RhbC1jb250YWluZXInO1xuaW1wb3J0IFBsb3RDb250YWluZXJGYWN0b3J5IGZyb20gJy4vcGxvdC1jb250YWluZXInO1xuaW1wb3J0IE5vdGlmaWNhdGlvblBhbmVsRmFjdG9yeSBmcm9tICcuL25vdGlmaWNhdGlvbi1wYW5lbCc7XG5cbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWR9IGZyb20gJ3V0aWxzL3V0aWxzJztcbmltcG9ydCB7dmFsaWRhdGVUb2tlbn0gZnJvbSAndXRpbHMvbWFwYm94LXV0aWxzJztcblxuaW1wb3J0IHt0aGVtZSBhcyBiYXNpY1RoZW1lLCB0aGVtZUxUfSBmcm9tICdzdHlsZXMvYmFzZSc7XG5pbXBvcnQgY29udGludW91c0NvbG9yTGVnZW5kIGZyb20gJ3JlYWN0LXZpcy9kaXN0L2xlZ2VuZHMvY29udGludW91cy1jb2xvci1sZWdlbmQnO1xuXG4vLyBNYXliZSB3ZSBzaG91bGQgdGhpbmsgYWJvdXQgZXhwb3J0aW5nIHRoaXMgb3IgY3JlYXRpbmcgYSB2YXJpYWJsZVxuLy8gYXMgcGFydCBvZiB0aGUgYmFzZS5qcyB0aGVtZVxuY29uc3QgR2xvYmFsU3R5bGUgPSBzdHlsZWQuZGl2YFxuICBmb250LWZhbWlseTogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5mb250RmFtaWx5fTtcbiAgZm9udC13ZWlnaHQ6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZm9udFdlaWdodH07XG4gIGZvbnQtc2l6ZTogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5mb250U2l6ZX07XG4gIGxpbmUtaGVpZ2h0OiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmxpbmVIZWlnaHR9O1xuICBtYXJnaW4tbGVmdDogJHtwcm9wcyA9PiAocHJvcHMuc2lkZVBhbmVsID09PSBudWxsID8gJzBweCcgOiAnMzgxcHgnKX07XG4gIG1hcmdpbi1yaWdodDogMHB4O1xuICAqLFxuICAqOmJlZm9yZSxcbiAgKjphZnRlciB7XG4gICAgLXdlYmtpdC1ib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC1tb3otYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB9XG5cbiAgdWwge1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAwO1xuICB9XG5cbiAgbGkge1xuICAgIG1hcmdpbjogMDtcbiAgfVxuXG4gIGEge1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICBjb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5sYWJlbENvbG9yfTtcbiAgfVxuYDtcblxuS2VwbGVyR2xGYWN0b3J5LmRlcHMgPSBbXG4gIEJvdHRvbVdpZGdldEZhY3RvcnksXG4gIE1hcENvbnRhaW5lckZhY3RvcnksXG4gIE1vZGFsQ29udGFpbmVyRmFjdG9yeSxcbiAgU2lkZVBhbmVsRmFjdG9yeSxcbiAgUGxvdENvbnRhaW5lckZhY3RvcnksXG4gIE5vdGlmaWNhdGlvblBhbmVsRmFjdG9yeVxuXTtcblxuZnVuY3Rpb24gS2VwbGVyR2xGYWN0b3J5KFxuICBCb3R0b21XaWRnZXQsXG4gIE1hcENvbnRhaW5lcixcbiAgTW9kYWxXcmFwcGVyLFxuICBTaWRlUGFuZWwsXG4gIFBsb3RDb250YWluZXIsXG4gIE5vdGlmaWNhdGlvblBhbmVsXG4pIHtcbiAgY2xhc3MgS2VwbGVyR0wgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgICBtYXBTdHlsZXM6IFtdLFxuICAgICAgbWFwU3R5bGVzUmVwbGFjZURlZmF1bHQ6IGZhbHNlLFxuICAgICAgbWFwYm94QXBpVXJsOiBERUZBVUxUX01BUEJPWF9BUElfVVJMLFxuICAgICAgd2lkdGg6IDgwMCxcbiAgICAgIGhlaWdodDogODAwLFxuICAgICAgYXBwTmFtZTogS0VQTEVSX0dMX05BTUUsXG4gICAgICB2ZXJzaW9uOiBLRVBMRVJfR0xfVkVSU0lPTixcbiAgICAgIHNpZGVQYW5lbFdpZHRoOiBESU1FTlNJT05TLnNpZGVQYW5lbC53aWR0aCxcbiAgICAgIHRoZW1lOiB7fVxuICAgIH07XG5cbiAgICBjb21wb25lbnRXaWxsTW91bnQoKSB7XG4gICAgICB0aGlzLl92YWxpZGF0ZU1hcGJveFRva2VuKCk7XG4gICAgICB0aGlzLl9sb2FkTWFwU3R5bGUodGhpcy5wcm9wcy5tYXBTdHlsZXMpO1xuICAgICAgdGhpcy5faGFuZGxlUmVzaXplKHRoaXMucHJvcHMpO1xuICAgIH1cblxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIC8vIGlmIGRpbWVuc2lvbiBwcm9wcyBoYXMgY2hhbmdlZFxuICAgICAgICB0aGlzLnByb3BzLmhlaWdodCAhPT0gbmV4dFByb3BzLmhlaWdodCB8fFxuICAgICAgICB0aGlzLnByb3BzLndpZHRoICE9PSBuZXh0UHJvcHMud2lkdGggfHxcbiAgICAgICAgLy8gcmVhY3QtbWFwLWdsIHdpbGwgZGlzcGF0Y2ggdXBkYXRlVmlld3BvcnQgYWZ0ZXIgdGhpcy5faGFuZGxlUmVzaXplIGlzIGNhbGxlZFxuICAgICAgICAvLyBoZXJlIHdlIGNoZWNrIGlmIHRoaXMucHJvcHMubWFwU3RhdGUuaGVpZ2h0IGlzIHN5bmMgd2l0aCBwcm9wcy5oZWlnaHRcbiAgICAgICAgbmV4dFByb3BzLmhlaWdodCAhPT0gdGhpcy5wcm9wcy5tYXBTdGF0ZS5oZWlnaHQgfHxcbiAgICAgICAgbmV4dFByb3BzLnVpU3RhdGUuYWN0aXZlU2lkZVBhbmVsICE9PSB0aGlzLnByb3BzLnVpU3RhdGUuYWN0aXZlU2lkZVBhbmVsXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5faGFuZGxlUmVzaXplKG5leHRQcm9wcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcm9vdCA9IGNyZWF0ZVJlZigpO1xuXG4gICAgLyogc2VsZWN0b3IgKi9cbiAgICB0aGVtZVNlbGVjdG9yID0gcHJvcHMgPT4gcHJvcHMudGhlbWU7XG4gICAgYXZhaWxhYmxlVGhlbWVTZWxlY3RvciA9IGNyZWF0ZVNlbGVjdG9yKHRoaXMudGhlbWVTZWxlY3RvciwgdGhlbWUgPT5cbiAgICAgIHR5cGVvZiB0aGVtZSA9PT0gJ29iamVjdCdcbiAgICAgICAgPyB7XG4gICAgICAgICAgICAuLi5iYXNpY1RoZW1lLFxuICAgICAgICAgICAgLi4udGhlbWVcbiAgICAgICAgICB9XG4gICAgICAgIDogdGhlbWUgPT09IFRIRU1FLmxpZ2h0XG4gICAgICAgID8gdGhlbWVMVFxuICAgICAgICA6IHRoZW1lXG4gICAgKTtcblxuICAgIF92YWxpZGF0ZU1hcGJveFRva2VuKCkge1xuICAgICAgY29uc3Qge21hcGJveEFwaUFjY2Vzc1Rva2VufSA9IHRoaXMucHJvcHM7XG4gICAgICBpZiAoIXZhbGlkYXRlVG9rZW4obWFwYm94QXBpQWNjZXNzVG9rZW4pKSB7XG4gICAgICAgIENvbnNvbGUud2FybihNSVNTSU5HX01BUEJPWF9UT0tFTik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2hhbmRsZVJlc2l6ZSh7d2lkdGgsIGhlaWdodCwgdWlTdGF0ZX0pIHtcbiAgICAgIHdpZHRoID0gdWlTdGF0ZS5hY3RpdmVTaWRlUGFuZWwgPT09IG51bGwgPyB3aWR0aCA6IHdpZHRoIC0gMzgxO1xuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUod2lkdGgpIHx8ICFOdW1iZXIuaXNGaW5pdGUoaGVpZ2h0KSkge1xuICAgICAgICBDb25zb2xlLndhcm4oJ3dpZHRoIGFuZCBoZWlnaHQgaXMgcmVxdWlyZWQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wcm9wcy5tYXBTdGF0ZUFjdGlvbnMudXBkYXRlTWFwKHtcbiAgICAgICAgd2lkdGg6IHdpZHRoIC8gKDEgKyBOdW1iZXIodGhpcy5wcm9wcy5tYXBTdGF0ZS5pc1NwbGl0KSksXG4gICAgICAgIGhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2xvYWRNYXBTdHlsZSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRTdHlsZXMgPSBPYmplY3QudmFsdWVzKHRoaXMucHJvcHMubWFwU3R5bGUubWFwU3R5bGVzKTtcbiAgICAgIC8vIGFkZCBpZCB0byBjdXN0b20gbWFwIHN0eWxlcyBpZiBub3QgZ2l2ZW5cbiAgICAgIGNvbnN0IGN1c3RvbVN0eWxlcyA9ICh0aGlzLnByb3BzLm1hcFN0eWxlcyB8fCBbXSkubWFwKG1zID0+ICh7XG4gICAgICAgIC4uLm1zLFxuICAgICAgICBpZDogbXMuaWQgfHwgZ2VuZXJhdGVIYXNoSWQoKVxuICAgICAgfSkpO1xuXG4gICAgICBjb25zdCBhbGxTdHlsZXMgPSBbLi4uY3VzdG9tU3R5bGVzLCAuLi5kZWZhdWx0U3R5bGVzXS5yZWR1Y2UoXG4gICAgICAgIChhY2N1LCBzdHlsZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhc1N0eWxlT2JqZWN0ID0gc3R5bGUuc3R5bGUgJiYgdHlwZW9mIHN0eWxlLnN0eWxlID09PSAnb2JqZWN0JztcbiAgICAgICAgICBhY2N1W2hhc1N0eWxlT2JqZWN0ID8gJ3RvTG9hZCcgOiAndG9SZXF1ZXN0J11bc3R5bGUuaWRdID0gc3R5bGU7XG5cbiAgICAgICAgICByZXR1cm4gYWNjdTtcbiAgICAgICAgfSxcbiAgICAgICAge3RvTG9hZDoge30sIHRvUmVxdWVzdDoge319XG4gICAgICApO1xuXG4gICAgICB0aGlzLnByb3BzLm1hcFN0eWxlQWN0aW9ucy5sb2FkTWFwU3R5bGVzKGFsbFN0eWxlcy50b0xvYWQpO1xuICAgICAgdGhpcy5wcm9wcy5tYXBTdHlsZUFjdGlvbnMucmVxdWVzdE1hcFN0eWxlcyhhbGxTdHlsZXMudG9SZXF1ZXN0KTtcbiAgICB9O1xuXG4gICAgcmVuZGVyKCkge1xuICAgICAgdmFyIHtcbiAgICAgICAgLy8gYXV0aFxuICAgICAgICBhdXRoLFxuXG4gICAgICAgIC8vXG4gICAgICAgIHByb2plY3QsXG5cbiAgICAgICAgLy8gcHJvcHNcbiAgICAgICAgaWQsXG4gICAgICAgIGFwcE5hbWUsXG4gICAgICAgIHZlcnNpb24sXG4gICAgICAgIG9uU2F2ZU1hcCxcbiAgICAgICAgb25WaWV3U3RhdGVDaGFuZ2UsXG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIG1hcGJveEFwaUFjY2Vzc1Rva2VuLFxuICAgICAgICBtYXBib3hBcGlVcmwsXG4gICAgICAgIGdldE1hcGJveFJlZixcblxuICAgICAgICAvLyByZWR1eCBzdGF0ZVxuICAgICAgICBtYXBTdHlsZSxcbiAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgIHVpU3RhdGUsXG4gICAgICAgIHZpc1N0YXRlLFxuXG4gICAgICAgIC8vIGFjdGlvbnMsXG4gICAgICAgIHZpc1N0YXRlQWN0aW9ucyxcbiAgICAgICAgbWFwU3RhdGVBY3Rpb25zLFxuICAgICAgICBtYXBTdHlsZUFjdGlvbnMsXG4gICAgICAgIHVpU3RhdGVBY3Rpb25zXG4gICAgICB9ID0gdGhpcy5wcm9wcztcblxuICAgICAgY29uc3Qge1xuICAgICAgICBmaWx0ZXJzLFxuICAgICAgICBsYXllcnMsXG4gICAgICAgIHdpZGdldHMsXG4gICAgICAgIHNwbGl0TWFwcywgLy8gdGhpcyB3aWxsIHN0b3JlIHN1cHBvcnQgZm9yIHNwbGl0IG1hcCB2aWV3IGlzIG5lY2Vzc2FyeVxuICAgICAgICBsYXllck9yZGVyLFxuICAgICAgICBsYXllckJsZW5kaW5nLFxuICAgICAgICBsYXllckNsYXNzZXMsXG4gICAgICAgIHdpZGdldE9yZGVyLFxuICAgICAgICB3aWRnZXRDbGFzc2VzLFxuICAgICAgICBpbnRlcmFjdGlvbkNvbmZpZyxcbiAgICAgICAgZGF0YXNldHMsXG4gICAgICAgIGxheWVyRGF0YSxcbiAgICAgICAgaG92ZXJJbmZvLFxuICAgICAgICBjbGlja2VkLFxuICAgICAgICBtb3VzZVBvcyxcbiAgICAgICAgYW5pbWF0aW9uQ29uZmlnXG4gICAgICB9ID0gdmlzU3RhdGU7XG5cbiAgICAgIGNvbnN0IG5vdGlmaWNhdGlvblBhbmVsRmllbGRzID0ge1xuICAgICAgICByZW1vdmVOb3RpZmljYXRpb246IHVpU3RhdGVBY3Rpb25zLnJlbW92ZU5vdGlmaWNhdGlvbixcbiAgICAgICAgbm90aWZpY2F0aW9uczogdWlTdGF0ZS5ub3RpZmljYXRpb25zXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzaWRlRmllbGRzID0ge1xuICAgICAgICBhcHBOYW1lLFxuICAgICAgICB2ZXJzaW9uLFxuICAgICAgICBhdXRoLFxuICAgICAgICBwcm9qZWN0LFxuICAgICAgICBkYXRhc2V0cyxcbiAgICAgICAgZmlsdGVycyxcbiAgICAgICAgbGF5ZXJzLFxuICAgICAgICBsYXllck9yZGVyLFxuICAgICAgICBsYXllckNsYXNzZXMsXG4gICAgICAgIHdpZGdldHMsXG4gICAgICAgIHdpZGdldE9yZGVyLFxuICAgICAgICB3aWRnZXRDbGFzc2VzLFxuICAgICAgICBpbnRlcmFjdGlvbkNvbmZpZyxcbiAgICAgICAgbWFwU3R5bGUsXG4gICAgICAgIGxheWVyQmxlbmRpbmcsXG4gICAgICAgIG9uU2F2ZU1hcCxcbiAgICAgICAgdWlTdGF0ZSxcbiAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgIG1hcFN0eWxlQWN0aW9ucyxcbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zLFxuICAgICAgICB1aVN0YXRlQWN0aW9ucyxcbiAgICAgICAgd2lkdGg6IHRoaXMucHJvcHMuc2lkZVBhbmVsV2lkdGhcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hcEZpZWxkcyA9IHtcbiAgICAgICAgYXV0aCxcbiAgICAgICAgcHJvamVjdCxcbiAgICAgICAgZGF0YXNldHMsXG4gICAgICAgIGdldE1hcGJveFJlZixcbiAgICAgICAgbWFwYm94QXBpQWNjZXNzVG9rZW4sXG4gICAgICAgIG1hcGJveEFwaVVybCxcbiAgICAgICAgbWFwU3RhdGUsXG4gICAgICAgIHVpU3RhdGUsXG4gICAgICAgIGVkaXRvcjogdmlzU3RhdGUuZWRpdG9yLFxuICAgICAgICBtYXBTdHlsZSxcbiAgICAgICAgbGF5ZXJzLFxuICAgICAgICBsYXllck9yZGVyLFxuICAgICAgICBsYXllckRhdGEsXG4gICAgICAgIGxheWVyQmxlbmRpbmcsXG4gICAgICAgIGZpbHRlcnMsXG4gICAgICAgIHdpZGdldHMsXG4gICAgICAgIGludGVyYWN0aW9uQ29uZmlnLFxuICAgICAgICBob3ZlckluZm8sXG4gICAgICAgIGNsaWNrZWQsXG4gICAgICAgIG1vdXNlUG9zLFxuICAgICAgICByZWFkT25seTogdWlTdGF0ZS5yZWFkT25seSxcbiAgICAgICAgb25WaWV3U3RhdGVDaGFuZ2UsXG4gICAgICAgIHVpU3RhdGVBY3Rpb25zLFxuICAgICAgICB2aXNTdGF0ZUFjdGlvbnMsXG4gICAgICAgIG1hcFN0YXRlQWN0aW9ucyxcbiAgICAgICAgYW5pbWF0aW9uQ29uZmlnXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpc1NwbGl0ID0gc3BsaXRNYXBzICYmIHNwbGl0TWFwcy5sZW5ndGggPiAxO1xuICAgICAgY29uc3QgY29udGFpbmVyVyA9IG1hcFN0YXRlLndpZHRoICogKE51bWJlcihpc1NwbGl0KSArIDEpO1xuXG4gICAgICBjb25zdCBtYXBDb250YWluZXJzID0gIWlzU3BsaXRcbiAgICAgICAgPyBbXG4gICAgICAgICAgICA8TWFwQ29udGFpbmVyXG4gICAgICAgICAgICAgIGlkPVwic2F2ZVwiXG4gICAgICAgICAgICAgIGtleT17MH1cbiAgICAgICAgICAgICAgaW5kZXg9ezB9XG4gICAgICAgICAgICAgIHsuLi5tYXBGaWVsZHN9XG4gICAgICAgICAgICAgIG1hcExheWVycz17aXNTcGxpdCA/IHNwbGl0TWFwc1swXS5sYXllcnMgOiBudWxsfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICBdXG4gICAgICAgIDogc3BsaXRNYXBzLm1hcCgoc2V0dGluZ3MsIGluZGV4KSA9PiAoXG4gICAgICAgICAgICA8TWFwQ29udGFpbmVyXG4gICAgICAgICAgICAgIGlkPVwic2F2ZVwiXG4gICAgICAgICAgICAgIGtleT17aW5kZXh9XG4gICAgICAgICAgICAgIGluZGV4PXtpbmRleH1cbiAgICAgICAgICAgICAgey4uLm1hcEZpZWx