UNPKG

kepler.gl

Version:

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

386 lines (383 loc) 53.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.commonTileVisConfigs = exports.DEFAULT_RADIUS = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); 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 _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _throttle = _interopRequireDefault(require("lodash/throttle")); var _commonUtils = require("@kepler.gl/common-utils"); var _constants = require("@kepler.gl/constants"); var _table = require("@kepler.gl/table"); var _utils = require("@kepler.gl/utils"); var _baseLayer = _interopRequireDefault(require("../base-layer")); var _tileUtils = require("./common-tile/tile-utils"); 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; })(); } function _superPropGet(t, e, r, o) { var p = (0, _get2["default"])((0, _getPrototypeOf2["default"])(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; } 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; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project var DEFAULT_ELEVATION = 500; var DEFAULT_RADIUS = exports.DEFAULT_RADIUS = 1; var commonTileVisConfigs = exports.commonTileVisConfigs = { strokeColor: 'strokeColor', strokeOpacity: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.opacity), {}, { property: 'strokeOpacity' }), radius: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.radius), {}, { range: [0.1, 100], step: 0.1, defaultValue: DEFAULT_RADIUS, allowCustomValue: false }), radiusUnits: { type: 'boolean', defaultValue: true, label: 'Radius in pixels', group: '', property: 'radiusUnits', description: 'Radius in pixels or in meters' }, enable3d: 'enable3d', stroked: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.stroked), {}, { defaultValue: false }), transition: { type: 'boolean', defaultValue: false, label: 'Transition', group: '', property: 'transition', description: 'Smoother transition during animation (enable transition will decrease performance)' }, heightRange: 'elevationRange', elevationScale: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.elevationScale), {}, { allowCustomValue: false }), opacity: 'opacity', colorRange: 'colorRange', // TODO: figure out type for radiusByZoom vis config radiusByZoom: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.radius), {}, { defaultValue: { enabled: false, stops: null } }), dynamicColor: { type: 'boolean', defaultValue: false, label: 'Dynamic Color', group: '', property: 'dynamicColor', description: 'Use a dynamic color scale based on data visible in the viewport' } }; /** * Abstract tile layer, including common functionality for viewport-based datasets, * dynamic scales, and tile-based animation */ var AbstractTileLayer = exports["default"] = /*#__PURE__*/function (_KeplerLayer) { function AbstractTileLayer(props) { var _this; (0, _classCallCheck2["default"])(this, AbstractTileLayer); _this = _callSuper(this, AbstractTileLayer, [props]); (0, _defineProperty2["default"])(_this, "tileDataset", void 0); (0, _defineProperty2["default"])(_this, "setLayerDomain", undefined); /** * Callback to invoke when the viewport changes */ (0, _defineProperty2["default"])(_this, "onViewportLoad", function (tiles) { _this.tileDataset.updateTiles(tiles); // Update dynamic color domain if required if (_this.config.visConfig.dynamicColor) { _this.setDynamicColorDomain(); } }); (0, _defineProperty2["default"])(_this, "setDynamicColorDomain", (0, _throttle["default"])(function () { var _this2 = _this, config = _this2.config, tileDataset = _this2.tileDataset, setLayerDomain = _this2.setLayerDomain; var field = config.colorField; var colorDomain = config.colorDomain, colorScale = config.colorScale; if (!tileDataset || !setLayerDomain || !field) return; if (colorScale === _constants.SCALE_TYPES.quantize) { var _tileDataset$getExten = tileDataset.getExtent(field), _tileDataset$getExten2 = (0, _slicedToArray2["default"])(_tileDataset$getExten, 2), min = _tileDataset$getExten2[0], max = _tileDataset$getExten2[1]; if (!Array.isArray(colorDomain) || min !== colorDomain[0] || max !== colorDomain[1]) { setLayerDomain({ domain: [min, max] }); } } else if (colorScale === _constants.SCALE_TYPES.quantile) { var domain = tileDataset.getQuantileSample(field); setLayerDomain({ domain: domain }); } else if (colorScale === _constants.SCALE_TYPES.ordinal) { var _domain = tileDataset.getUniqueValues(field); setLayerDomain({ domain: _domain }); } }, 500)); _this.registerVisConfig(commonTileVisConfigs); _this.tileDataset = _this.initTileDataset(); return _this; } (0, _inherits2["default"])(AbstractTileLayer, _KeplerLayer); return (0, _createClass2["default"])(AbstractTileLayer, [{ key: "requireData", get: function get() { return true; } }, { key: "requiredLayerColumns", get: function get() { return []; } }, { key: "visualChannels", get: function get() { return { color: _objectSpread(_objectSpread({}, _superPropGet(AbstractTileLayer, "visualChannels", this, 1).color), {}, { accessor: 'getFillColor', defaultValue: function defaultValue(config) { return config.color; } }), height: { property: 'height', field: 'heightField', scale: 'heightScale', domain: 'heightDomain', range: 'heightRange', key: 'height', channelScaleType: 'size', accessor: 'getElevation', condition: function condition(config) { return config.visConfig.enable3d; }, nullValue: 0, defaultValue: DEFAULT_ELEVATION } }; } }, { key: "accessVSFieldValue", value: function accessVSFieldValue(inputField, indexKey) { return this.accessRowValue(inputField, indexKey); } }, { key: "getScaleOptions", value: function getScaleOptions(channelKey) { if (channelKey === 'color') { var _field$filterProps; var channel = this.visualChannels.color; var _field = this.config[channel.field]; if ((0, _tileUtils.isDomainQuantiles)(_field === null || _field === void 0 || (_field$filterProps = _field.filterProps) === null || _field$filterProps === void 0 ? void 0 : _field$filterProps.domainQuantiles) || this.config.visConfig.dynamicColor || // If we've set the scale to quantile, we need to include it - there's a loading // period in which the visConfig isn't set yet, but if we don't return the right // scale type we lose it this.config.colorScale === _constants.SCALE_TYPES.quantile) { return [_constants.SCALE_TYPES.quantize, _constants.SCALE_TYPES.quantile, _constants.SCALE_TYPES.custom]; } return [_constants.SCALE_TYPES.quantize, _constants.SCALE_TYPES.custom]; } return [_constants.SCALE_TYPES.linear]; } }, { key: "resetColorDomain", value: function resetColorDomain() { var _this$setLayerDomain; var _this$meta = this.meta, datasetId = _this$meta.datasetId, datasets = _this$meta.datasets; this.updateLayerVisualChannel(datasets === null || datasets === void 0 ? void 0 : datasets[datasetId || ''], 'color'); (_this$setLayerDomain = this.setLayerDomain) === null || _this$setLayerDomain === void 0 || _this$setLayerDomain.call(this, { domain: this.config.colorDomain }); } }, { key: "updateLayerConfig", value: function updateLayerConfig(newConfig) { var _this$config$visConfi, _newConfig$visConfig$, _newConfig$visConfig, _this3 = this; // When the dynamic color setting changes, we need to recalculate the layer domain var old = (_this$config$visConfi = this.config.visConfig.dynamicColor) !== null && _this$config$visConfi !== void 0 ? _this$config$visConfi : false; var next = (_newConfig$visConfig$ = (_newConfig$visConfig = newConfig.visConfig) === null || _newConfig$visConfig === void 0 ? void 0 : _newConfig$visConfig.dynamicColor) !== null && _newConfig$visConfig$ !== void 0 ? _newConfig$visConfig$ : old; var scaleTypeChanged = newConfig.colorScale && this.config.colorScale !== newConfig.colorScale; _superPropGet(AbstractTileLayer, "updateLayerConfig", this, 3)([newConfig]); var colorField = this.config.colorField; if (colorField) { // When we switch from dynamic to non-dynamic or vice versa, we need to update // the color domain. This is downstream from a dispatch call, so we use // setTimeout to avoid "reducers may not dispatch actions" errors if (next && (!old || scaleTypeChanged)) { setTimeout(function () { return _this3.setDynamicColorDomain(); }, 0); } else if (old && !next) { setTimeout(function () { return _this3.resetColorDomain(); }, 0); } } return this; } }, { key: "animationDomain", get: function get() { return this.config.animation.domain; } }, { key: "setInitialLayerConfig", value: function setInitialLayerConfig(dataset) { var defaultColorField = (0, _utils.findDefaultColorField)(dataset); if (defaultColorField) { this.updateLayerConfig({ colorField: defaultColorField }); this.updateLayerVisualChannel(dataset, 'color'); } return this; } }, { key: "getDefaultLayerConfig", value: function getDefaultLayerConfig(props) { return _objectSpread(_objectSpread({}, _superPropGet(AbstractTileLayer, "getDefaultLayerConfig", this, 3)([props])), {}, { colorScale: _constants.SCALE_TYPES.quantize, // add height visual channel heightField: null, heightDomain: [0, 1], heightScale: 'linear' }); } // We can render without columns, so we redefine this method }, { key: "shouldRenderLayer", value: function shouldRenderLayer() { return Boolean(this.type && this.config.isVisible); } }, { key: "updateAnimationDomainByField", value: function updateAnimationDomainByField(channel) { var field = this.config[this.visualChannels[channel].field]; if ((0, _tileUtils.isIndexedField)(field) && field.indexBy.type === _constants.ALL_FIELD_TYPES.timestamp) { var timeDomain = field.indexBy.timeDomain; this.updateLayerConfig({ animation: _objectSpread(_objectSpread({}, timeDomain), {}, { enabled: true, startTime: timeDomain.domain[0] }) }); } } }, { key: "updateAnimationDomain", value: function updateAnimationDomain(domain) { this.updateLayerConfig({ animation: _objectSpread(_objectSpread({}, this.config.animation), {}, { domain: domain }) }); } }, { key: "updateLayerDomain", value: function updateLayerDomain(datasets, newFilter) { var _this4 = this; _superPropGet(AbstractTileLayer, "updateLayerDomain", this, 3)([datasets, newFilter]); if (newFilter) { // invalidate cachedVisibleDataset when e.g. changing filters this.tileDataset.invalidateCache(); } Object.keys(this.visualChannels).forEach(function (channel) { _this4.updateAnimationDomainByField(channel); }); return this; } }, { key: "updateLayerVisualChannel", value: function updateLayerVisualChannel(dataset, channel) { _superPropGet(AbstractTileLayer, "updateLayerVisualChannel", this, 3)([dataset, channel]); // create animation if field is indexed by time this.updateAnimationDomainByField(channel); } }, { key: "formatLayerData", value: function formatLayerData(datasets, oldLayerData, animationConfig) { var dataId = this.config.dataId; if (!(0, _commonUtils.notNullorUndefined)(dataId)) { return {}; } var dataset = datasets[dataId]; var dataUpdateTriggers = this.getDataUpdateTriggers(dataset); var triggerChanged = this.getChangedTriggers(dataUpdateTriggers); if (triggerChanged && triggerChanged.getMeta) { this.updateLayerMeta(dataset, datasets); } var indexKey = this.config.animation.enabled ? animationConfig.currentTime : null; var accessors = this.getAttributeAccessors({ dataAccessor: function dataAccessor() { return function (d) { return d; }; }, dataContainer: dataset.dataContainer, indexKey: indexKey }); var metadata = dataset === null || dataset === void 0 ? void 0 : dataset.metadata; var metadataToData = metadata ? { minZoom: metadata.minZoom, maxZoom: metadata.maxZoom, bounds: metadata.bounds } : {}; return _objectSpread(_objectSpread({}, metadataToData), accessors); } }, { key: "getGpuFilterValueAccessor", value: function getGpuFilterValueAccessor(_ref) { var _this5 = this; var gpuFilter = _ref.gpuFilter, animationConfig = _ref.animationConfig; var indexKey = this.config.animation.enabled ? animationConfig.currentTime : null; var valueAccessor = function valueAccessor(dataContainer, d) { return function (field) { return _this5.accessVSFieldValue(field, indexKey)(field, d); }; }; return gpuFilter.filterValueAccessor(null)(undefined, valueAccessor); } }], [{ key: "findDefaultLayerProps", value: function findDefaultLayerProps(dataset) { if (!(0, _table.isTileDataset)(dataset)) { return { props: [] }; } var newLayerProp = { dataId: dataset.id, label: dataset.label, isVisible: true }; return { props: [newLayerProp] }; } }]); }(_baseLayer["default"]); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdGhyb3R0bGUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jb21tb25VdGlscyIsIl9jb25zdGFudHMiLCJfdGFibGUiLCJfdXRpbHMiLCJfYmFzZUxheWVyIiwiX3RpbGVVdGlscyIsIl9jYWxsU3VwZXIiLCJ0IiwibyIsImUiLCJfZ2V0UHJvdG90eXBlT2YyIiwiX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yIiwiX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCIsIlJlZmxlY3QiLCJjb25zdHJ1Y3QiLCJjb25zdHJ1Y3RvciIsImFwcGx5IiwiQm9vbGVhbiIsInByb3RvdHlwZSIsInZhbHVlT2YiLCJjYWxsIiwiX3N1cGVyUHJvcEdldCIsInIiLCJwIiwiX2dldDIiLCJvd25LZXlzIiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIkRFRkFVTFRfRUxFVkFUSU9OIiwiREVGQVVMVF9SQURJVVMiLCJleHBvcnRzIiwiY29tbW9uVGlsZVZpc0NvbmZpZ3MiLCJzdHJva2VDb2xvciIsInN0cm9rZU9wYWNpdHkiLCJMQVlFUl9WSVNfQ09ORklHUyIsIm9wYWNpdHkiLCJwcm9wZXJ0eSIsInJhZGl1cyIsInJhbmdlIiwic3RlcCIsImRlZmF1bHRWYWx1ZSIsImFsbG93Q3VzdG9tVmFsdWUiLCJyYWRpdXNVbml0cyIsInR5cGUiLCJsYWJlbCIsImdyb3VwIiwiZGVzY3JpcHRpb24iLCJlbmFibGUzZCIsInN0cm9rZWQiLCJ0cmFuc2l0aW9uIiwiaGVpZ2h0UmFuZ2UiLCJlbGV2YXRpb25TY2FsZSIsImNvbG9yUmFuZ2UiLCJyYWRpdXNCeVpvb20iLCJlbmFibGVkIiwic3RvcHMiLCJkeW5hbWljQ29sb3IiLCJBYnN0cmFjdFRpbGVMYXllciIsIl9LZXBsZXJMYXllciIsInByb3BzIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2syIiwidW5kZWZpbmVkIiwidGlsZXMiLCJ0aWxlRGF0YXNldCIsInVwZGF0ZVRpbGVzIiwiY29uZmlnIiwidmlzQ29uZmlnIiwic2V0RHluYW1pY0NvbG9yRG9tYWluIiwidGhyb3R0bGUiLCJfdGhpczIiLCJzZXRMYXllckRvbWFpbiIsImZpZWxkIiwiY29sb3JGaWVsZCIsImNvbG9yRG9tYWluIiwiY29sb3JTY2FsZSIsIlNDQUxFX1RZUEVTIiwicXVhbnRpemUiLCJfdGlsZURhdGFzZXQkZ2V0RXh0ZW4iLCJnZXRFeHRlbnQiLCJfdGlsZURhdGFzZXQkZ2V0RXh0ZW4yIiwiX3NsaWNlZFRvQXJyYXkyIiwibWluIiwibWF4IiwiQXJyYXkiLCJpc0FycmF5IiwiZG9tYWluIiwicXVhbnRpbGUiLCJnZXRRdWFudGlsZVNhbXBsZSIsIm9yZGluYWwiLCJnZXRVbmlxdWVWYWx1ZXMiLCJyZWdpc3RlclZpc0NvbmZpZyIsImluaXRUaWxlRGF0YXNldCIsIl9pbmhlcml0czIiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwiZ2V0IiwiY29sb3IiLCJhY2Nlc3NvciIsImhlaWdodCIsInNjYWxlIiwiY2hhbm5lbFNjYWxlVHlwZSIsImNvbmRpdGlvbiIsIm51bGxWYWx1ZSIsInZhbHVlIiwiYWNjZXNzVlNGaWVsZFZhbHVlIiwiaW5wdXRGaWVsZCIsImluZGV4S2V5IiwiYWNjZXNzUm93VmFsdWUiLCJnZXRTY2FsZU9wdGlvbnMiLCJjaGFubmVsS2V5IiwiX2ZpZWxkJGZpbHRlclByb3BzIiwiY2hhbm5lbCIsInZpc3VhbENoYW5uZWxzIiwiaXNEb21haW5RdWFudGlsZXMiLCJmaWx0ZXJQcm9wcyIsImRvbWFpblF1YW50aWxlcyIsImN1c3RvbSIsImxpbmVhciIsInJlc2V0Q29sb3JEb21haW4iLCJfdGhpcyRzZXRMYXllckRvbWFpbiIsIl90aGlzJG1ldGEiLCJtZXRhIiwiZGF0YXNldElkIiwiZGF0YXNldHMiLCJ1cGRhdGVMYXllclZpc3VhbENoYW5uZWwiLCJ1cGRhdGVMYXllckNvbmZpZyIsIm5ld0NvbmZpZyIsIl90aGlzJGNvbmZpZyR2aXNDb25maSIsIl9uZXdDb25maWckdmlzQ29uZmlnJCIsIl9uZXdDb25maWckdmlzQ29uZmlnIiwiX3RoaXMzIiwib2xkIiwibmV4dCIsInNjYWxlVHlwZUNoYW5nZWQiLCJzZXRUaW1lb3V0IiwiYW5pbWF0aW9uIiwic2V0SW5pdGlhbExheWVyQ29uZmlnIiwiZGF0YXNldCIsImRlZmF1bHRDb2xvckZpZWxkIiwiZmluZERlZmF1bHRDb2xvckZpZWxkIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiaGVpZ2h0RmllbGQiLCJoZWlnaHREb21haW4iLCJoZWlnaHRTY2FsZSIsInNob3VsZFJlbmRlckxheWVyIiwiaXNWaXNpYmxlIiwidXBkYXRlQW5pbWF0aW9uRG9tYWluQnlGaWVsZCIsImlzSW5kZXhlZEZpZWxkIiwiaW5kZXhCeSIsIkFMTF9GSUVMRF9UWVBFUyIsInRpbWVzdGFtcCIsInRpbWVEb21haW4iLCJzdGFydFRpbWUiLCJ1cGRhdGVBbmltYXRpb25Eb21haW4iLCJ1cGRhdGVMYXllckRvbWFpbiIsIm5ld0ZpbHRlciIsIl90aGlzNCIsImludmFsaWRhdGVDYWNoZSIsImZvcm1hdExheWVyRGF0YSIsIm9sZExheWVyRGF0YSIsImFuaW1hdGlvbkNvbmZpZyIsImRhdGFJZCIsIm5vdE51bGxvclVuZGVmaW5lZCIsImRhdGFVcGRhdGVUcmlnZ2VycyIsImdldERhdGFVcGRhdGVUcmlnZ2VycyIsInRyaWdnZXJDaGFuZ2VkIiwiZ2V0Q2hhbmdlZFRyaWdnZXJzIiwiZ2V0TWV0YSIsInVwZGF0ZUxheWVyTWV0YSIsImN1cnJlbnRUaW1lIiwiYWNjZXNzb3JzIiwiZ2V0QXR0cmlidXRlQWNjZXNzb3JzIiwiZGF0YUFjY2Vzc29yIiwiZCIsImRhdGFDb250YWluZXIiLCJtZXRhZGF0YSIsIm1ldGFkYXRhVG9EYXRhIiwibWluWm9vbSIsIm1heFpvb20iLCJib3VuZHMiLCJnZXRHcHVGaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiX3JlZiIsIl90aGlzNSIsImdwdUZpbHRlciIsInZhbHVlQWNjZXNzb3IiLCJmaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiZmluZERlZmF1bHRMYXllclByb3BzIiwiaXNUaWxlRGF0YXNldCIsIm5ld0xheWVyUHJvcCIsImlkIiwiS2VwbGVyTGF5ZXIiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdmVjdG9yLXRpbGUvYWJzdHJhY3QtdGlsZS1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgdGhyb3R0bGUgZnJvbSAnbG9kYXNoL3Rocm90dGxlJztcblxuaW1wb3J0IHtub3ROdWxsb3JVbmRlZmluZWR9IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7U0NBTEVfVFlQRVMsIEFMTF9GSUVMRF9UWVBFUywgTEFZRVJfVklTX0NPTkZJR1N9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIGlzVGlsZURhdGFzZXQsXG4gIEtlcGxlclRhYmxlIGFzIEtlcGxlckRhdGFzZXQsXG4gIERhdGFzZXRzIGFzIEtlcGxlckRhdGFzZXRzLFxuICBHcHVGaWx0ZXJcbn0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge1xuICBBbmltYXRpb25Db25maWcsXG4gIEZpZWxkLFxuICBCaW5kZWRMYXllckNhbGxiYWNrcyxcbiAgVmlzQ29uZmlnQm9vbGVhbixcbiAgVmlzQ29uZmlnUmFuZ2UsXG4gIFZpc0NvbmZpZ0NvbG9yUmFuZ2UsXG4gIFZpc0NvbmZpZ051bWJlcixcbiAgVmlzQ29uZmlnQ29sb3JTZWxlY3QsXG4gIExheWVyQ29sb3JDb25maWcsXG4gIExheWVySGVpZ2h0Q29uZmlnLFxuICBGaWx0ZXIsXG4gIEZpZWxkIGFzIEtlcGxlckZpZWxkLFxuICBNYXBTdGF0ZSxcbiAgTWVyZ2UsXG4gIFpvb21TdG9wc0NvbmZpZ1xufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7ZmluZERlZmF1bHRDb2xvckZpZWxkLCBEYXRhQ29udGFpbmVySW50ZXJmYWNlfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IHtcbiAgZGVmYXVsdCBhcyBLZXBsZXJMYXllcixcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICBMYXllckJhc2VDb25maWdQYXJ0aWFsLFxuICBWaXN1YWxDaGFubmVsLFxuICBWaXN1YWxDaGFubmVsRG9tYWluLFxuICBWaXN1YWxDaGFubmVsRmllbGRcbn0gZnJvbSAnLi4vYmFzZS1sYXllcic7XG5pbXBvcnQgVGlsZURhdGFzZXQgZnJvbSAnLi9jb21tb24tdGlsZS90aWxlLWRhdGFzZXQnO1xuaW1wb3J0IHtpc0luZGV4ZWRGaWVsZCwgaXNEb21haW5RdWFudGlsZXN9IGZyb20gJy4vY29tbW9uLXRpbGUvdGlsZS11dGlscyc7XG5pbXBvcnQge0ZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlfSBmcm9tICcuLi9sYXllci11dGlscyc7XG5cbmNvbnN0IERFRkFVTFRfRUxFVkFUSU9OID0gNTAwO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkFESVVTID0gMTtcblxuZXhwb3J0IHR5cGUgQWJzdHJhY3RUaWxlTGF5ZXJWaXNDb25maWdTZXR0aW5ncyA9IHtcbiAgc3Ryb2tlQ29sb3I6IFZpc0NvbmZpZ0NvbG9yU2VsZWN0O1xuICBzdHJva2VPcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIHJhZGl1czogVmlzQ29uZmlnTnVtYmVyO1xuICByYWRpdXNVbml0czogVmlzQ29uZmlnQm9vbGVhbjtcbiAgZW5hYmxlM2Q6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIHN0cm9rZWQ6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIHRyYW5zaXRpb246IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIGhlaWdodFJhbmdlOiBWaXNDb25maWdSYW5nZTtcbiAgZWxldmF0aW9uU2NhbGU6IFZpc0NvbmZpZ051bWJlcjtcbiAgb3BhY2l0eTogVmlzQ29uZmlnTnVtYmVyO1xuICBjb2xvclJhbmdlOiBWaXNDb25maWdDb2xvclJhbmdlO1xuICAvLyBUT0RPOiBmaWd1cmUgb3V0IHR5cGUgZm9yIHJhZGl1c0J5Wm9vbSB2aXMgY29uZmlnXG4gIHJhZGl1c0J5Wm9vbTogYW55O1xuICBkeW5hbWljQ29sb3I6IFZpc0NvbmZpZ0Jvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBMYXllckRhdGEgPSB7XG4gIG1pblpvb20/OiBudW1iZXI7XG4gIG1heFpvb20/OiBudW1iZXI7XG4gIGJvdW5kcz86IG51bWJlcltdO1xuICBnZXRQb2ludFJhZGl1cz86ICgpID0+IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIExheWVyT3B0cyA9IHtcbiAgaWR4OiBudW1iZXI7XG4gIG1hcFN0YXRlOiBNYXBTdGF0ZTtcbiAgZGF0YTogTGF5ZXJEYXRhO1xuICBncHVGaWx0ZXI6IEdwdUZpbHRlcjtcbiAgYW5pbWF0aW9uQ29uZmlnOiBBbmltYXRpb25Db25maWc7XG4gIHRpbGVzZXREYXRhVXJsPzogc3RyaW5nIHwgbnVsbDtcbiAgbGF5ZXJDYWxsYmFja3M6IEJpbmRlZExheWVyQ2FsbGJhY2tzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbW1vblRpbGVWaXNDb25maWdzID0ge1xuICBzdHJva2VDb2xvcjogJ3N0cm9rZUNvbG9yJyBhcyBjb25zdCxcbiAgc3Ryb2tlT3BhY2l0eToge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLm9wYWNpdHksXG4gICAgcHJvcGVydHk6ICdzdHJva2VPcGFjaXR5J1xuICB9LFxuICByYWRpdXM6IHtcbiAgICAuLi5MQVlFUl9WSVNfQ09ORklHUy5yYWRpdXMsXG4gICAgcmFuZ2U6IFswLjEsIDEwMF0sXG4gICAgc3RlcDogMC4xLFxuICAgIGRlZmF1bHRWYWx1ZTogREVGQVVMVF9SQURJVVMsXG4gICAgYWxsb3dDdXN0b21WYWx1ZTogZmFsc2VcbiAgfSBhcyBWaXNDb25maWdOdW1iZXIsXG4gIHJhZGl1c1VuaXRzOiB7XG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHRWYWx1ZTogdHJ1ZSxcbiAgICBsYWJlbDogJ1JhZGl1cyBpbiBwaXhlbHMnLFxuICAgIGdyb3VwOiAnJyxcbiAgICBwcm9wZXJ0eTogJ3JhZGl1c1VuaXRzJyxcbiAgICBkZXNjcmlwdGlvbjogJ1JhZGl1cyBpbiBwaXhlbHMgb3IgaW4gbWV0ZXJzJ1xuICB9IGFzIFZpc0NvbmZpZ0Jvb2xlYW4sXG4gIGVuYWJsZTNkOiAnZW5hYmxlM2QnIGFzIGNvbnN0LFxuICBzdHJva2VkOiB7XG4gICAgLi4uTEFZRVJfVklTX0NPTkZJR1Muc3Ryb2tlZCxcbiAgICBkZWZhdWx0VmFsdWU6IGZhbHNlXG4gIH0sXG4gIHRyYW5zaXRpb246IHtcbiAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICBsYWJlbDogJ1RyYW5zaXRpb24nLFxuICAgIGdyb3VwOiAnJyxcbiAgICBwcm9wZXJ0eTogJ3RyYW5zaXRpb24nLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1Ntb290aGVyIHRyYW5zaXRpb24gZHVyaW5nIGFuaW1hdGlvbiAoZW5hYmxlIHRyYW5zaXRpb24gd2lsbCBkZWNyZWFzZSBwZXJmb3JtYW5jZSknXG4gIH0gYXMgVmlzQ29uZmlnQm9vbGVhbixcbiAgaGVpZ2h0UmFuZ2U6ICdlbGV2YXRpb25SYW5nZScgYXMgY29uc3QsXG4gIGVsZXZhdGlvblNjYWxlOiB7Li4uTEFZRVJfVklTX0NPTkZJR1MuZWxldmF0aW9uU2NhbGUsIGFsbG93Q3VzdG9tVmFsdWU6IGZhbHNlfSxcbiAgb3BhY2l0eTogJ29wYWNpdHknIGFzIGNvbnN0LFxuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScgYXMgY29uc3QsXG4gIC8vIFRPRE86IGZpZ3VyZSBvdXQgdHlwZSBmb3IgcmFkaXVzQnlab29tIHZpcyBjb25maWdcbiAgcmFkaXVzQnlab29tOiB7XG4gICAgLi4uTEFZRVJfVklTX0NPTkZJR1MucmFkaXVzLFxuICAgIGRlZmF1bHRWYWx1ZToge1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICBzdG9wczogbnVsbFxuICAgIH0gYXMgWm9vbVN0b3BzQ29uZmlnXG4gIH0gYXMgYW55LFxuICBkeW5hbWljQ29sb3I6IHtcbiAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICBsYWJlbDogJ0R5bmFtaWMgQ29sb3InLFxuICAgIGdyb3VwOiAnJyxcbiAgICBwcm9wZXJ0eTogJ2R5bmFtaWNDb2xvcicsXG4gICAgZGVzY3JpcHRpb246ICdVc2UgYSBkeW5hbWljIGNvbG9yIHNjYWxlIGJhc2VkIG9uIGRhdGEgdmlzaWJsZSBpbiB0aGUgdmlld3BvcnQnXG4gIH0gYXMgVmlzQ29uZmlnQm9vbGVhblxufTtcblxuZXhwb3J0IHR5cGUgQWJzdHJhY3RUaWxlTGF5ZXJDb25maWcgPSBNZXJnZTxcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICB7Y29sb3JGaWVsZD86IFZpc3VhbENoYW5uZWxGaWVsZDsgY29sb3JTY2FsZT86IHN0cmluZzsgY29sb3JEb21haW4/OiBWaXN1YWxDaGFubmVsRG9tYWlufVxuPjtcblxuLyoqXG4gKiBBYnN0cmFjdCB0aWxlIGxheWVyLCBpbmNsdWRpbmcgY29tbW9uIGZ1bmN0aW9uYWxpdHkgZm9yIHZpZXdwb3J0LWJhc2VkIGRhdGFzZXRzLFxuICogZHluYW1pYyBzY2FsZXMsIGFuZCB0aWxlLWJhc2VkIGFuaW1hdGlvblxuICovXG5leHBvcnQgZGVmYXVsdCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFRpbGVMYXllcjxcbiAgLy8gVHlwZSBvZiB0aGUgdGlsZSBpdHNlbGZcbiAgVCxcbiAgLy8gVHlwZSBvZiB0aGUgaXRlcmFibGUgZGF0YSBvYmplY3RcbiAgSSBleHRlbmRzIEl0ZXJhYmxlPGFueT4gPSBUIGV4dGVuZHMgSXRlcmFibGU8YW55PiA/IFQgOiBuZXZlclxuPiBleHRlbmRzIEtlcGxlckxheWVyIHtcbiAgZGVjbGFyZSBjb25maWc6IEFic3RyYWN0VGlsZUxheWVyQ29uZmlnO1xuICBkZWNsYXJlIHZpc0NvbmZpZ1NldHRpbmdzOiBBYnN0cmFjdFRpbGVMYXllclZpc0NvbmZpZ1NldHRpbmdzO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIEtlcGxlckxheWVyPlswXSkge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKGNvbW1vblRpbGVWaXNDb25maWdzKTtcbiAgICB0aGlzLnRpbGVEYXRhc2V0ID0gdGhpcy5pbml0VGlsZURhdGFzZXQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0aWxlRGF0YXNldDogVGlsZURhdGFzZXQ8VCwgST47XG4gIHByb3RlY3RlZCBzZXRMYXllckRvbWFpbjogQmluZGVkTGF5ZXJDYWxsYmFja3NbJ29uU2V0TGF5ZXJEb21haW4nXSA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW5pdFRpbGVEYXRhc2V0KCk6IFRpbGVEYXRhc2V0PFQsIEk+O1xuXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoZGF0YXNldDogS2VwbGVyRGF0YXNldCk6IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlIHtcbiAgICBpZiAoIWlzVGlsZURhdGFzZXQoZGF0YXNldCkpIHtcbiAgICAgIHJldHVybiB7cHJvcHM6IFtdfTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdMYXllclByb3AgPSB7XG4gICAgICBkYXRhSWQ6IGRhdGFzZXQuaWQsXG4gICAgICBsYWJlbDogZGF0YXNldC5sYWJlbCxcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZVxuICAgIH07XG5cbiAgICByZXR1cm4ge3Byb3BzOiBbbmV3TGF5ZXJQcm9wXX07XG4gIH1cblxuICBnZXQgcmVxdWlyZURhdGEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBnZXQgcmVxdWlyZWRMYXllckNvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpOiBSZWNvcmQ8c3RyaW5nLCBWaXN1YWxDaGFubmVsPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB7XG4gICAgICAgIC4uLnN1cGVyLnZpc3VhbENoYW5uZWxzLmNvbG9yLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldEZpbGxDb2xvcicsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogY29uZmlnID0+IGNvbmZpZy5jb2xvclxuICAgICAgfSxcbiAgICAgIGhlaWdodDoge1xuICAgICAgICBwcm9wZXJ0eTogJ2hlaWdodCcsXG4gICAgICAgIGZpZWxkOiAnaGVpZ2h0RmllbGQnLFxuICAgICAgICBzY2FsZTogJ2hlaWdodFNjYWxlJyxcbiAgICAgICAgZG9tYWluOiAnaGVpZ2h0RG9tYWluJyxcbiAgICAgICAgcmFuZ2U6ICdoZWlnaHRSYW5nZScsXG4gICAgICAgIGtleTogJ2hlaWdodCcsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6ICdzaXplJyxcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRFbGV2YXRpb24nLFxuICAgICAgICBjb25kaXRpb246IGNvbmZpZyA9PiBjb25maWcudmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgICBudWxsVmFsdWU6IDAsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogREVGQVVMVF9FTEVWQVRJT05cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB2aWV3cG9ydCBjaGFuZ2VzXG4gICAqL1xuICBvblZpZXdwb3J0TG9hZCA9ICh0aWxlczogVFtdKTogdm9pZCA9PiB7XG4gICAgdGhpcy50aWxlRGF0YXNldC51cGRhdGVUaWxlcyh0aWxlcyk7XG4gICAgLy8gVXBkYXRlIGR5bmFtaWMgY29sb3IgZG9tYWluIGlmIHJlcXVpcmVkXG4gICAgaWYgKHRoaXMuY29uZmlnLnZpc0NvbmZpZy5keW5hbWljQ29sb3IpIHtcbiAgICAgIHRoaXMuc2V0RHluYW1pY0NvbG9yRG9tYWluKCk7XG4gICAgfVxuICB9O1xuXG4gIGFic3RyYWN0IGFjY2Vzc1Jvd1ZhbHVlKFxuICAgIGZpZWxkPzogS2VwbGVyRmllbGQsXG4gICAgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsXG4gICk6IChmaWVsZDogS2VwbGVyRmllbGQsIGRhdHVtOiBUIGV4dGVuZHMgSXRlcmFibGU8aW5mZXIgVj4gPyBWIDogbmV2ZXIpID0+IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG5cbiAgYWNjZXNzVlNGaWVsZFZhbHVlKGlucHV0RmllbGQ/OiBGaWVsZCwgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5hY2Nlc3NSb3dWYWx1ZShpbnB1dEZpZWxkLCBpbmRleEtleSk7XG4gIH1cblxuICBnZXRTY2FsZU9wdGlvbnMoY2hhbm5lbEtleTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGlmIChjaGFubmVsS2V5ID09PSAnY29sb3InKSB7XG4gICAgICBjb25zdCBjaGFubmVsID0gdGhpcy52aXN1YWxDaGFubmVscy5jb2xvcjtcbiAgICAgIGNvbnN0IGZpZWxkID0gdGhpcy5jb25maWdbY2hhbm5lbC5maWVsZF07XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNEb21haW5RdWFudGlsZXMoZmllbGQ/LmZpbHRlclByb3BzPy5kb21haW5RdWFudGlsZXMpIHx8XG4gICAgICAgIHRoaXMuY29uZmlnLnZpc0NvbmZpZy5keW5hbWljQ29sb3IgfHxcbiAgICAgICAgLy8gSWYgd2UndmUgc2V0IHRoZSBzY2FsZSB0byBxdWFudGlsZSwgd2UgbmVlZCB0byBpbmNsdWRlIGl0IC0gdGhlcmUncyBhIGxvYWRpbmdcbiAgICAgICAgLy8gcGVyaW9kIGluIHdoaWNoIHRoZSB2aXNDb25maWcgaXNuJ3Qgc2V0IHlldCwgYnV0IGlmIHdlIGRvbid0IHJldHVybiB0aGUgcmlnaHRcbiAgICAgICAgLy8gc2NhbGUgdHlwZSB3ZSBsb3NlIGl0XG4gICAgICAgIHRoaXMuY29uZmlnLmNvbG9yU2NhbGUgPT09IFNDQUxFX1RZUEVTLnF1YW50aWxlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIFtTQ0FMRV9UWVBFUy5xdWFudGl6ZSwgU0NBTEVfVFlQRVMucXVhbnRpbGUsIFNDQUxFX1RZUEVTLmN1c3RvbV07XG4gICAgICB9XG4gICAgICByZXR1cm4gW1NDQUxFX1RZUEVTLnF1YW50aXplLCBTQ0FMRV9UWVBFUy5jdXN0b21dO1xuICAgIH1cblxuICAgIHJldHVybiBbU0NBTEVfVFlQRVMubGluZWFyXTtcbiAgfVxuXG4gIHNldER5bmFtaWNDb2xvckRvbWFpbiA9IHRocm90dGxlKCgpOiB2b2lkID0+IHtcbiAgICBjb25zdCB7Y29uZmlnLCB0aWxlRGF0YXNldCwgc2V0TGF5ZXJEb21haW59ID0gdGhpcztcbiAgICBjb25zdCBmaWVsZCA9IGNvbmZpZy5jb2xvckZpZWxkO1xuICAgIGNvbnN0IHtjb2xvckRvbWFpbiwgY29sb3JTY2FsZX0gPSBjb25maWc7XG4gICAgaWYgKCF0aWxlRGF0YXNldCB8fCAhc2V0TGF5ZXJEb21haW4gfHwgIWZpZWxkKSByZXR1cm47XG5cbiAgICBpZiAoY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMucXVhbnRpemUpIHtcbiAgICAgIGNvbnN0IFttaW4sIG1heF0gPSB0aWxlRGF0YXNldC5nZXRFeHRlbnQoZmllbGQpO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbG9yRG9tYWluKSB8fCBtaW4gIT09IGNvbG9yRG9tYWluWzBdIHx8IG1heCAhPT0gY29sb3JEb21haW5bMV0pIHtcbiAgICAgICAgc2V0TGF5ZXJEb21haW4oe2RvbWFpbjogW21pbiwgbWF4XX0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMucXVhbnRpbGUpIHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IHRpbGVEYXRhc2V0LmdldFF1YW50aWxlU2FtcGxlKGZpZWxkKTtcbiAgICAgIHNldExheWVyRG9tYWluKHtkb21haW59KTtcbiAgICB9IGVsc2UgaWYgKGNvbG9yU2NhbGUgPT09IFNDQUxFX1RZUEVTLm9yZGluYWwpIHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IHRpbGVEYXRhc2V0LmdldFVuaXF1ZVZhbHVlcyhmaWVsZCk7XG4gICAgICBzZXRMYXllckRvbWFpbih7ZG9tYWlufSk7XG4gICAgfVxuICB9LCA1MDApO1xuXG4gIHJlc2V0Q29sb3JEb21haW4oKTogdm9pZCB7XG4gICAgY29uc3Qge2RhdGFzZXRJZCwgZGF0YXNldHN9ID0gdGhpcy5tZXRhO1xuICAgIHRoaXMudXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXRzPy5bZGF0YXNldElkIHx8ICcnXSwgJ2NvbG9yJyk7XG4gICAgdGhpcy5zZXRMYXllckRvbWFpbj8uKHtkb21haW46IHRoaXMuY29uZmlnLmNvbG9yRG9tYWlufSk7XG4gIH1cblxuICB1cGRhdGVMYXllckNvbmZpZyhcbiAgICBuZXdDb25maWc6IFBhcnRpYWw8TGF5ZXJCYXNlQ29uZmlnPiAmIFBhcnRpYWw8TGF5ZXJDb2xvckNvbmZpZz5cbiAgKTogQWJzdHJhY3RUaWxlTGF5ZXI8VCwgST4ge1xuICAgIC8vIFdoZW4gdGhlIGR5bmFtaWMgY29sb3Igc2V0dGluZyBjaGFuZ2VzLCB3ZSBuZWVkIHRvIHJlY2FsY3VsYXRlIHRoZSBsYXllciBkb21haW5cbiAgICBjb25zdCBvbGQgPSB0aGlzLmNvbmZpZy52aXNDb25maWcuZHluYW1pY0NvbG9yID8/IGZhbHNlO1xuICAgIGNvbnN0IG5leHQgPSBuZXdDb25maWcudmlzQ29uZmlnPy5keW5hbWljQ29sb3IgPz8gb2xkO1xuICAgIGNvbnN0IHNjYWxlVHlwZUNoYW5nZWQgPVxuICAgICAgbmV3Q29uZmlnLmNvbG9yU2NhbGUgJiYgdGhpcy5jb25maWcuY29sb3JTY2FsZSAhPT0gbmV3Q29uZmlnLmNvbG9yU2NhbGU7XG5cbiAgICBzdXBlci51cGRhdGVMYXllckNvbmZpZyhuZXdDb25maWcpO1xuICAgIGNvbnN0IHtjb2xvckZpZWxkfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgaWYgKGNvbG9yRmllbGQpIHtcbiAgICAgIC8vIFdoZW4gd2Ugc3dpdGNoIGZyb20gZHluYW1pYyB0byBub24tZHluYW1pYyBvciB2aWNlIHZlcnNhLCB3ZSBuZWVkIHRvIHVwZGF0ZVxuICAgICAgLy8gdGhlIGNvbG9yIGRvbWFpbi4gVGhpcyBpcyBkb3duc3RyZWFtIGZyb20gYSBkaXNwYXRjaCBjYWxsLCBzbyB3ZSB1c2VcbiAgICAgIC8vIHNldFRpbWVvdXQgdG8gYXZvaWQgXCJyZWR1Y2VycyBtYXkgbm90IGRpc3BhdGNoIGFjdGlvbnNcIiBlcnJvcnNcbiAgICAgIGlmIChuZXh0ICYmICghb2xkIHx8IHNjYWxlVHlwZUNoYW5nZWQpKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXREeW5hbWljQ29sb3JEb21haW4oKSwgMCk7XG4gICAgICB9IGVsc2UgaWYgKG9sZCAmJiAhbmV4dCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVzZXRDb2xvckRvbWFpbigpLCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldCBhbmltYXRpb25Eb21haW4oKTogW251bWJlciwgbnVtYmVyXSB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5hbmltYXRpb24uZG9tYWluO1xuICB9XG5cbiAgc2V0SW5pdGlhbExheWVyQ29uZmlnKGRhdGFzZXQ6IEtlcGxlckRhdGFzZXQpOiBBYnN0cmFjdFRpbGVMYXllcjxULCBJPiB7XG4gICAgY29uc3QgZGVmYXVsdENvbG9yRmllbGQgPSBmaW5kRGVmYXVsdENvbG9yRmllbGQoZGF0YXNldCk7XG5cbiAgICBpZiAoZGVmYXVsdENvbG9yRmllbGQpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgICBjb2xvckZpZWxkOiBkZWZhdWx0Q29sb3JGaWVsZFxuICAgICAgfSk7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbChkYXRhc2V0LCAnY29sb3InKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldERlZmF1bHRMYXllckNvbmZpZyhcbiAgICBwcm9wczogTGF5ZXJCYXNlQ29uZmlnUGFydGlhbFxuICApOiBMYXllckJhc2VDb25maWcgJiBQYXJ0aWFsPExheWVyQ29sb3JDb25maWcgJiBMYXllckhlaWdodENvbmZpZz4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci5nZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMpLFxuICAgICAgY29sb3JTY2FsZTogU0NBTEVfVFlQRVMucXVhbnRpemUsXG5cbiAgICAgIC8vIGFkZCBoZWlnaHQgdmlzdWFsIGNoYW5uZWxcbiAgICAgIGhlaWdodEZpZWxkOiBudWxsLFxuICAgICAgaGVpZ2h0RG9tYWluOiBbMCwgMV0sXG4gICAgICBoZWlnaHRTY2FsZTogJ2xpbmVhcidcbiAgICB9O1xuICB9XG5cbiAgLy8gV2UgY2FuIHJlbmRlciB3aXRob3V0IGNvbHVtbnMsIHNvIHdlIHJlZGVmaW5lIHRoaXMgbWV0aG9kXG4gIHNob3VsZFJlbmRlckxheWVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMudHlwZSAmJiB0aGlzLmNvbmZpZy5pc1Zpc2libGUpO1xuICB9XG5cbiAgdXBkYXRlQW5pbWF0aW9uRG9tYWluQnlGaWVsZChjaGFubmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBmaWVsZCA9IHRoaXMuY29uZmlnW3RoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF0uZmllbGRdO1xuXG4gICAgaWYgKGlzSW5kZXhlZEZpZWxkKGZpZWxkKSAmJiBmaWVsZC5pbmRleEJ5LnR5cGUgPT09IEFMTF9GSUVMRF9UWVBFUy50aW1lc3RhbXApIHtcbiAgICAgIGNvbnN0IHt0aW1lRG9tYWlufSA9IGZpZWxkLmluZGV4Qnk7XG5cbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgICBhbmltYXRpb246IHtcbiAgICAgICAgICAuLi50aW1lRG9tYWluLFxuICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgc3RhcnRUaW1lOiB0aW1lRG9tYWluLmRvbWFpblswXVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVBbmltYXRpb25Eb21haW4oZG9tYWluOiBbbnVtYmVyLCBudW1iZXJdIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgIC4uLnRoaXMuY29uZmlnLmFuaW1hdGlvbixcbiAgICAgICAgZG9tYWluXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVMYXllckRvbWFpbihkYXRhc2V0czogS2VwbGVyRGF0YXNldHMsIG5ld0ZpbHRlcj86IEZpbHRlcik6IEFic3RyYWN0VGlsZUxheWVyPFQsIEk+IHtcbiAgICBzdXBlci51cGRhdGVMYXllckRvbWFpbihkYXRhc2V0cywgbmV3RmlsdGVyKTtcbiAgICBpZiAobmV3RmlsdGVyKSB7XG4gICAgICAvLyBpbnZhbGlkYXRlIGNhY2hlZFZpc2libGVEYXRhc2V0IHdoZW4gZS5nLiBjaGFuZ2luZyBmaWx0ZXJzXG4gICAgICB0aGlzLnRpbGVEYXRhc2V0LmludmFsaWRhdGVDYWNoZSgpO1xuICAgIH1cbiAgICBPYmplY3Qua2V5cyh0aGlzLnZpc3VhbENoYW5uZWxzKS5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgdGhpcy51cGRhdGVBbmltYXRpb25Eb21haW5CeUZpZWxkKGNoYW5uZWwpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXQ6IEtlcGxlckRhdGFzZXQsIGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHN1cGVyLnVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbChkYXRhc2V0LCBjaGFubmVsKTtcblxuICAgIC8vIGNyZWF0ZSBhbmltYXRpb24gaWYgZmllbGQgaXMgaW5kZXhlZCBieSB0aW1lXG4gICAgdGhpcy51cGRhdGVBbmltYXRpb25Eb21haW5CeUZpZWxkKGNoYW5uZWwpO1xuICB9XG5cbiAgZm9ybWF0TGF5ZXJEYXRhKFxuICAgIGRhdGFzZXRzOiBLZXBsZXJEYXRhc2V0cyxcbiAgICBvbGRMYXllckRhdGE6IHVua25vd24sXG4gICAgYW5pbWF0aW9uQ29uZmlnOiBBbmltYXRpb25Db25maWdcbiAgKTogTGF5ZXJEYXRhIHtcbiAgICBjb25zdCB7ZGF0YUlkfSA9IHRoaXMuY29uZmlnO1xuICAgIGlmICghbm90TnVsbG9yVW5kZWZpbmVkKGRhdGFJZCkpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2RhdGFJZF07XG5cbiAgICBjb25zdCBkYXRhVXBkYXRlVHJpZ2dlcnMgPSB0aGlzLmdldERhdGFVcGRhdGVUcmlnZ2VycyhkYXRhc2V0KTtcbiAgICBjb25zdCB0cmlnZ2VyQ2hhbmdlZCA9IHRoaXMuZ2V0Q2hhbmdlZFRyaWdnZXJzKGRhdGFVcGRhdGVUcmlnZ2Vycyk7XG5cbiAgICBpZiAodHJpZ2dlckNoYW5nZWQgJiYgdHJpZ2dlckNoYW5nZWQuZ2V0TWV0YSkge1xuICAgICAgdGhpcy51cGRhdGVMYXllck1ldGEoZGF0YXNldCwgZGF0YXNldHMpO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4S2V5ID0gdGhpcy5jb25maWcuYW5pbWF0aW9uLmVuYWJsZWQgPyBhbmltYXRpb25Db25maWcuY3VycmVudFRpbWUgOiBudWxsO1xuICAgIGNvbnN0IGFjY2Vzc29ycyA9IHRoaXMuZ2V0QXR0cmlidXRlQWNjZXNzb3JzKHtcbiAgICAgIGRhdGFBY2Nlc3NvcjogKCkgPT4gZCA9PiBkLFxuICAgICAgZGF0YUNvbnRhaW5lcjogZGF0YXNldC5kYXRhQ29udGFpbmVyLFxuICAgICAgaW5kZXhLZXlcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gZGF0YXNldD8ubWV0YWRhdGEgYXMgTGF5ZXJEYXRhIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1ldGFkYXRhVG9EYXRhID0gbWV0YWRhdGFcbiAgICAgID8ge1xuICAgICAgICAgIG1pblpvb206IG1ldGFkYXRhLm1pblpvb20sXG4gICAgICAgICAgbWF4Wm9vbTogbWV0YWRhdGEubWF4Wm9vbSxcbiAgICAgICAgICBib3VuZHM6IG1ldGFkYXRhLmJvdW5kc1xuICAgICAgICB9XG4gICAgICA6IHt9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1ldGFkYXRhVG9EYXRhLFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfTtcbiAgfVxuXG4gIGdldEdwdUZpbHRlclZhbHVlQWNjZXNzb3Ioe2dwdUZpbHRlciwgYW5pbWF0aW9uQ29uZmlnfTogTGF5ZXJPcHRzKTogYW55IHtcbiAgICBjb25zdCBpbmRleEtleSA9IHRoaXMuY29uZmlnLmFuaW1hdGlvbi5lbmFibGVkID8gYW5pbWF0aW9uQ29uZmlnLmN1cnJlbnRUaW1lIDogbnVsbDtcbiAgICBjb25zdCB2YWx1ZUFjY2Vzc29yID0gKGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsIGQpID0+IGZpZWxkID0+XG4gICAgICB0aGlzLmFjY2Vzc1ZTRmllbGRWYWx1ZShmaWVsZCwgaW5kZXhLZXkpKGZpZWxkLCBkKTtcbiAgICByZXR1cm4gZ3B1RmlsdGVyLmZpbHRlclZhbHVlQWNjZXNzb3IobnVsbCBhcyBhbnkpKHVuZGVmaW5lZCwgdmFsdWVBY2Nlc3Nvcik7XG4gIH1cbn1cbiJd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