UNPKG

kepler.gl.geoiq

Version:

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

428 lines (374 loc) 49.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.featureResolver = exports.featureAccessor = exports.geoJsonRequiredColumns = exports.geojsonVisConfigs = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); 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 _lodash = _interopRequireDefault(require("lodash.memoize")); var _lodash2 = _interopRequireDefault(require("lodash.uniq")); var _baseLayer = _interopRequireDefault(require("../base-layer")); var _solidPolygonLayer = _interopRequireDefault(require("../../deckgl-layers/geojson-layer/solid-polygon-layer")); var _deck = require("deck.gl"); var _colorUtils = require("../../utils/color-utils"); var _geojsonUtils = require("./geojson-utils"); var _geojsonLayerIcon = _interopRequireDefault(require("./geojson-layer-icon")); var _defaultSettings = require("../../constants/default-settings"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var geojsonVisConfigs = { opacity: 'opacity', thickness: { type: 'number', defaultValue: 0.5, label: 'Stroke Width', isRanged: false, range: [0, 100], step: 0.1, group: 'stroke', property: 'thickness' }, colorRange: 'colorRange', radius: 'radius', sizeRange: 'strokeWidthRange', radiusRange: 'radiusRange', heightRange: 'elevationRange', elevationScale: 'elevationScale', 'hi-precision': 'hi-precision', stroked: 'stroked', filled: 'filled', enable3d: 'enable3d', wireframe: 'wireframe' }; exports.geojsonVisConfigs = geojsonVisConfigs; var geoJsonRequiredColumns = ['geojson']; exports.geoJsonRequiredColumns = geoJsonRequiredColumns; var featureAccessor = function featureAccessor(_ref) { var geojson = _ref.geojson; return function (d) { return d[geojson.fieldIdx]; }; }; exports.featureAccessor = featureAccessor; var featureResolver = function featureResolver(_ref2) { var geojson = _ref2.geojson; return geojson.fieldIdx; }; exports.featureResolver = featureResolver; var GeoJsonLayer = /*#__PURE__*/ function (_Layer) { (0, _inherits2["default"])(GeoJsonLayer, _Layer); function GeoJsonLayer(props) { var _this; (0, _classCallCheck2["default"])(this, GeoJsonLayer); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(GeoJsonLayer).call(this, props)); _this.dataToFeature = {}; _this.registerVisConfig(geojsonVisConfigs); _this.getFeature = (0, _lodash["default"])(featureAccessor, featureResolver); return _this; } (0, _createClass2["default"])(GeoJsonLayer, [{ key: "getDefaultLayerConfig", value: function getDefaultLayerConfig() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return _objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(GeoJsonLayer.prototype), "getDefaultLayerConfig", this).call(this, props), { // add height visual channel heightField: null, heightDomain: [0, 1], heightScale: 'linear', // add radius visual channel radiusField: null, radiusDomain: [0, 1], radiusScale: 'linear' }); } }, { key: "getHoverData", value: function getHoverData(object, allData) { // index of allData is saved to feature.properties return allData[object.properties.index]; } // TODO: fix complexity /* eslint-disable complexity */ }, { key: "formatLayerData", value: function formatLayerData(_, allData, filteredIndex, oldLayerData) { var _this2 = this; var opt = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; var _this$config = this.config, colorScale = _this$config.colorScale, colorField = _this$config.colorField, colorDomain = _this$config.colorDomain, color = _this$config.color, sizeScale = _this$config.sizeScale, sizeDomain = _this$config.sizeDomain, sizeField = _this$config.sizeField, heightField = _this$config.heightField, heightDomain = _this$config.heightDomain, heightScale = _this$config.heightScale, radiusField = _this$config.radiusField, radiusDomain = _this$config.radiusDomain, radiusScale = _this$config.radiusScale, visConfig = _this$config.visConfig, columns = _this$config.columns; var enable3d = visConfig.enable3d, stroked = visConfig.stroked, colorRange = visConfig.colorRange, heightRange = visConfig.heightRange, sizeRange = visConfig.sizeRange, radiusRange = visConfig.radiusRange; var getFeature = this.getFeature(columns); // geojson feature are object, if doesn't exists // create it and save to layer if (!oldLayerData || oldLayerData.getFeature !== getFeature) { this.updateLayerMeta(allData, getFeature); } var geojsonData; if (oldLayerData && oldLayerData.data && opt.sameData && oldLayerData.getFeature === getFeature) { // no need to create a new array of data // use updateTriggers to selectively re-calculate attributes geojsonData = oldLayerData.data; } else { // filteredIndex is a reference of index in allData which can map to feature geojsonData = filteredIndex.map(function (i) { return _this2.dataToFeature[i]; }).filter(function (d) { return d; }); } var cScale = colorField && this.getVisChannelScale(colorScale, colorDomain, colorRange.colors.map(_colorUtils.hexToRgb)); // calculate stroke scale - if stroked = true var sScale = sizeField && stroked && this.getVisChannelScale(sizeScale, sizeDomain, sizeRange); // calculate elevation scale - if extruded = true var eScale = heightField && enable3d && this.getVisChannelScale(heightScale, heightDomain, heightRange); // console.log('eScale inside formatLayerData', eScale); // point radius var rScale = radiusField && this.getVisChannelScale(radiusScale, radiusDomain, radiusRange); return { data: geojsonData, getFeature: getFeature, getFillColor: function getFillColor(d) { return cScale ? _this2.getEncodedChannelValue(cScale, allData[d.properties.index], colorField) : d.properties.fillColor || color; }, getLineColor: function getLineColor(d) { return cScale ? _this2.getEncodedChannelValue(cScale, allData[d.properties.index], colorField) : d.properties.lineColor || color; }, getLineWidth: function getLineWidth(d) { return sScale ? _this2.getEncodedChannelValue(sScale, allData[d.properties.index], sizeField, 0) : d.properties.lineWidth || 1; }, getElevation: function getElevation(d) { return eScale ? _this2.getEncodedChannelValue(eScale, allData[d.properties.index], heightField, 0) : d.properties.elevation || 500; }, getRadius: function getRadius(d) { return rScale ? _this2.getEncodedChannelValue(rScale, allData[d.properties.index], radiusField, 0) : d.properties.radius || 1; } }; } /* eslint-enable complexity */ }, { key: "updateLayerMeta", value: function updateLayerMeta(allData, getFeature) { this.dataToFeature = (0, _geojsonUtils.getGeojsonDataMaps)(allData, getFeature); // calculate layer meta var allFeatures = Object.values(this.dataToFeature); // get bounds from features var bounds = (0, _geojsonUtils.getGeojsonBounds)(allFeatures); // get lightSettings from points var lightSettings = this.getLightSettingsFromBounds(bounds); // if any of the feature has properties.hi-precision set to be true var fp64 = Boolean(allFeatures.find(function (d) { return d && d.properties && d.properties['hi-precision']; })); var fixedRadius = Boolean(allFeatures.find(function (d) { return d && d.properties && d.properties.radius; })); // keep a record of what type of geometry the collection has var featureTypes = allFeatures.reduce(function (accu, f) { var geoType = (0, _geojsonUtils.featureToDeckGlGeoType)(f && f.geometry && f.geometry.type); if (geoType) { accu[geoType] = true; } return accu; }, {}); this.updateMeta({ bounds: bounds, lightSettings: lightSettings, fp64: fp64, fixedRadius: fixedRadius, featureTypes: featureTypes }); } }, { key: "renderLayer", value: function renderLayer(_ref3) { var data = _ref3.data, idx = _ref3.idx, objectHovered = _ref3.objectHovered, mapState = _ref3.mapState, interactionConfig = _ref3.interactionConfig; var _this$meta = this.meta, fp64 = _this$meta.fp64, lightSettings = _this$meta.lightSettings, fixedRadius = _this$meta.fixedRadius; var radiusScale = this.getRadiusScaleByZoom(mapState, fixedRadius); var zoomFactor = this.getZoomFactor(mapState); var visConfig = this.config.visConfig; var layerProps = { // multiplier applied just so it being consistent with previously saved maps lineWidthScale: visConfig.thickness * zoomFactor * 8, lineWidthMinPixels: 1, elevationScale: visConfig.elevationScale, pointRadiusScale: radiusScale, fp64: fp64 || visConfig['hi-precision'], lineMiterLimit: 4 }; var updateTriggers = { getElevation: { heightField: this.config.heightField, heightScale: this.config.heightScale, heightRange: visConfig.heightRange }, getFillColor: { color: this.config.color, colorField: this.config.colorField, colorRange: visConfig.colorRange, colorScale: this.config.colorScale }, getLineColor: { color: this.config.color, colorField: this.config.colorField, colorRange: visConfig.colorRange, colorScale: this.config.colorScale }, getLineWidth: { sizeField: this.config.sizeField, sizeRange: visConfig.sizeRange }, getRadius: { radiusField: this.config.radiusField, radiusRange: visConfig.radiusRange } }; return [new _deck.GeoJsonLayer(_objectSpread({}, layerProps, { id: this.id, idx: idx, data: data.data, getFillColor: data.getFillColor, getLineColor: data.getLineColor, getLineWidth: data.getLineWidth, getRadius: data.getRadius, getElevation: data.getElevation, // highlight pickable: true, // highlightColor: this.config.highlightColor, autoHighlight: visConfig.enable3d, // parameters parameters: { depthTest: Boolean(visConfig.enable3d || mapState.dragRotate) }, opacity: visConfig.opacity, stroked: visConfig.stroked, filled: visConfig.filled, extruded: visConfig.enable3d, wireframe: visConfig.wireframe, lightSettings: lightSettings, updateTriggers: updateTriggers, subLayers: _objectSpread({}, _deck.GeoJsonLayer.defaultProps.subLayers, { PolygonLayer: _solidPolygonLayer["default"] }) }))].concat((0, _toConsumableArray2["default"])(this.isLayerHovered(objectHovered) && !visConfig.enable3d ? [new _deck.GeoJsonLayer(_objectSpread({}, layerProps, { id: "".concat(this.id, "-hovered"), data: [objectHovered.object], getLineWidth: data.getLineWidth, getRadius: data.getRadius, getElevation: data.getElevation, getLineColor: this.config.highlightColor, getFillColor: this.config.highlightColor, updateTriggers: updateTriggers, stroked: true, pickable: false, filled: false }))] : [])); } }, { key: "type", get: function get() { return 'geojson'; } }, { key: "name", get: function get() { return 'Polygon'; } }, { key: "layerIcon", get: function get() { return _geojsonLayerIcon["default"]; } }, { key: "requiredLayerColumns", get: function get() { return geoJsonRequiredColumns; } }, { key: "visualChannels", get: function get() { return _objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(GeoJsonLayer.prototype), "visualChannels", this), { size: _objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(GeoJsonLayer.prototype), "visualChannels", this).size, { property: 'stroke', condition: function condition(config) { return config.visConfig.stroked; } }), height: { property: 'height', field: 'heightField', scale: 'heightScale', domain: 'heightDomain', range: 'heightRange', key: 'height', channelScaleType: 'size', condition: function condition(config) { return config.visConfig.enable3d; } }, radius: { property: 'radius', field: 'radiusField', scale: 'radiusScale', domain: 'radiusDomain', range: 'radiusRange', key: 'radius', channelScaleType: 'radius' } }); } }], [{ key: "findDefaultLayerProps", value: function findDefaultLayerProps(_ref4) { var _this3 = this; var label = _ref4.label, fields = _ref4.fields; var geojsonColumns = fields.filter(function (f) { return f.type === 'geojson'; }).map(function (f) { return f.name; }); var defaultColumns = { geojson: (0, _lodash2["default"])([].concat((0, _toConsumableArray2["default"])(_defaultSettings.GEOJSON_FIELDS.geojson), (0, _toConsumableArray2["default"])(geojsonColumns))) }; var foundColumns = this.findDefaultColumnField(defaultColumns, fields); if (!foundColumns || !foundColumns.length) { return []; } return foundColumns.map(function (columns) { return { label: typeof label === 'string' && label.replace(/\.[^/.]+$/, '') || _this3.type, columns: columns, isVisible: true }; }); } }]); return GeoJsonLayer; }(_baseLayer["default"]); exports["default"] = GeoJsonLayer; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYXllcnMvZ2VvanNvbi1sYXllci9nZW9qc29uLWxheWVyLmpzIl0sIm5hbWVzIjpbImdlb2pzb25WaXNDb25maWdzIiwib3BhY2l0eSIsInRoaWNrbmVzcyIsInR5cGUiLCJkZWZhdWx0VmFsdWUiLCJsYWJlbCIsImlzUmFuZ2VkIiwicmFuZ2UiLCJzdGVwIiwiZ3JvdXAiLCJwcm9wZXJ0eSIsImNvbG9yUmFuZ2UiLCJyYWRpdXMiLCJzaXplUmFuZ2UiLCJyYWRpdXNSYW5nZSIsImhlaWdodFJhbmdlIiwiZWxldmF0aW9uU2NhbGUiLCJzdHJva2VkIiwiZmlsbGVkIiwiZW5hYmxlM2QiLCJ3aXJlZnJhbWUiLCJnZW9Kc29uUmVxdWlyZWRDb2x1bW5zIiwiZmVhdHVyZUFjY2Vzc29yIiwiZ2VvanNvbiIsImQiLCJmaWVsZElkeCIsImZlYXR1cmVSZXNvbHZlciIsIkdlb0pzb25MYXllciIsInByb3BzIiwiZGF0YVRvRmVhdHVyZSIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0RmVhdHVyZSIsImhlaWdodEZpZWxkIiwiaGVpZ2h0RG9tYWluIiwiaGVpZ2h0U2NhbGUiLCJyYWRpdXNGaWVsZCIsInJhZGl1c0RvbWFpbiIsInJhZGl1c1NjYWxlIiwib2JqZWN0IiwiYWxsRGF0YSIsInByb3BlcnRpZXMiLCJpbmRleCIsIl8iLCJmaWx0ZXJlZEluZGV4Iiwib2xkTGF5ZXJEYXRhIiwib3B0IiwiY29uZmlnIiwiY29sb3JTY2FsZSIsImNvbG9yRmllbGQiLCJjb2xvckRvbWFpbiIsImNvbG9yIiwic2l6ZVNjYWxlIiwic2l6ZURvbWFpbiIsInNpemVGaWVsZCIsInZpc0NvbmZpZyIsImNvbHVtbnMiLCJ1cGRhdGVMYXllck1ldGEiLCJnZW9qc29uRGF0YSIsImRhdGEiLCJzYW1lRGF0YSIsIm1hcCIsImkiLCJmaWx0ZXIiLCJjU2NhbGUiLCJnZXRWaXNDaGFubmVsU2NhbGUiLCJjb2xvcnMiLCJoZXhUb1JnYiIsInNTY2FsZSIsImVTY2FsZSIsInJTY2FsZSIsImdldEZpbGxDb2xvciIsImdldEVuY29kZWRDaGFubmVsVmFsdWUiLCJmaWxsQ29sb3IiLCJnZXRMaW5lQ29sb3IiLCJsaW5lQ29sb3IiLCJnZXRMaW5lV2lkdGgiLCJsaW5lV2lkdGgiLCJnZXRFbGV2YXRpb24iLCJlbGV2YXRpb24iLCJnZXRSYWRpdXMiLCJhbGxGZWF0dXJlcyIsIk9iamVjdCIsInZhbHVlcyIsImJvdW5kcyIsImxpZ2h0U2V0dGluZ3MiLCJnZXRMaWdodFNldHRpbmdzRnJvbUJvdW5kcyIsImZwNjQiLCJCb29sZWFuIiwiZmluZCIsImZpeGVkUmFkaXVzIiwiZmVhdHVyZVR5cGVzIiwicmVkdWNlIiwiYWNjdSIsImYiLCJnZW9UeXBlIiwiZ2VvbWV0cnkiLCJ1cGRhdGVNZXRhIiwiaWR4Iiwib2JqZWN0SG92ZXJlZCIsIm1hcFN0YXRlIiwiaW50ZXJhY3Rpb25Db25maWciLCJtZXRhIiwiZ2V0UmFkaXVzU2NhbGVCeVpvb20iLCJ6b29tRmFjdG9yIiwiZ2V0Wm9vbUZhY3RvciIsImxheWVyUHJvcHMiLCJsaW5lV2lkdGhTY2FsZSIsImxpbmVXaWR0aE1pblBpeGVscyIsInBvaW50UmFkaXVzU2NhbGUiLCJsaW5lTWl0ZXJMaW1pdCIsInVwZGF0ZVRyaWdnZXJzIiwiRGVja0dMR2VvSnNvbkxheWVyIiwiaWQiLCJwaWNrYWJsZSIsImF1dG9IaWdobGlnaHQiLCJwYXJhbWV0ZXJzIiwiZGVwdGhUZXN0IiwiZHJhZ1JvdGF0ZSIsImV4dHJ1ZGVkIiwic3ViTGF5ZXJzIiwiZGVmYXVsdFByb3BzIiwiUG9seWdvbkxheWVyIiwiSGlnaGxpZ2h0UG9seWdvbkxheWVyIiwiaXNMYXllckhvdmVyZWQiLCJoaWdobGlnaHRDb2xvciIsIkdlb2pzb25MYXllckljb24iLCJzaXplIiwiY29uZGl0aW9uIiwiaGVpZ2h0IiwiZmllbGQiLCJzY2FsZSIsImRvbWFpbiIsImtleSIsImNoYW5uZWxTY2FsZVR5cGUiLCJmaWVsZHMiLCJnZW9qc29uQ29sdW1ucyIsIm5hbWUiLCJkZWZhdWx0Q29sdW1ucyIsIkdFT0pTT05fRklFTERTIiwiZm91bmRDb2x1bW5zIiwiZmluZERlZmF1bHRDb2x1bW5GaWVsZCIsImxlbmd0aCIsInJlcGxhY2UiLCJpc1Zpc2libGUiLCJMYXllciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFLQTs7QUFDQTs7Ozs7O0FBRU8sSUFBTUEsaUJBQWlCLEdBQUc7QUFDL0JDLEVBQUFBLE9BQU8sRUFBRSxTQURzQjtBQUUvQkMsRUFBQUEsU0FBUyxFQUFFO0FBQ1RDLElBQUFBLElBQUksRUFBRSxRQURHO0FBRVRDLElBQUFBLFlBQVksRUFBRSxHQUZMO0FBR1RDLElBQUFBLEtBQUssRUFBRSxjQUhFO0FBSVRDLElBQUFBLFFBQVEsRUFBRSxLQUpEO0FBS1RDLElBQUFBLEtBQUssRUFBRSxDQUFDLENBQUQsRUFBSSxHQUFKLENBTEU7QUFNVEMsSUFBQUEsSUFBSSxFQUFFLEdBTkc7QUFPVEMsSUFBQUEsS0FBSyxFQUFFLFFBUEU7QUFRVEMsSUFBQUEsUUFBUSxFQUFFO0FBUkQsR0FGb0I7QUFZL0JDLEVBQUFBLFVBQVUsRUFBRSxZQVptQjtBQWEvQkMsRUFBQUEsTUFBTSxFQUFFLFFBYnVCO0FBZS9CQyxFQUFBQSxTQUFTLEVBQUUsa0JBZm9CO0FBZ0IvQkMsRUFBQUEsV0FBVyxFQUFFLGFBaEJrQjtBQWlCL0JDLEVBQUFBLFdBQVcsRUFBRSxnQkFqQmtCO0FBa0IvQkMsRUFBQUEsY0FBYyxFQUFFLGdCQWxCZTtBQW9CL0Isa0JBQWdCLGNBcEJlO0FBcUIvQkMsRUFBQUEsT0FBTyxFQUFFLFNBckJzQjtBQXNCL0JDLEVBQUFBLE1BQU0sRUFBRSxRQXRCdUI7QUF1Qi9CQyxFQUFBQSxRQUFRLEVBQUUsVUF2QnFCO0FBd0IvQkMsRUFBQUEsU0FBUyxFQUFFO0FBeEJvQixDQUExQjs7QUEyQkEsSUFBTUMsc0JBQXNCLEdBQUcsQ0FBQyxTQUFELENBQS9COzs7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LE1BQVMsU0FBVEEsTUFBUztBQUM1QyxVQUFNQyxjQUFjLEdBQUdELE1BQU0sQ0FDMUJ4RSxNQURvQixDQUNiLFVBQUErQixDQUFDO0FBQUEsZUFBSUEsQ0FBQyxDQUFDMUYsSUFBRixLQUFXLFNBQWY7QUFBQSxPQURZLEVBRXBCeUQsR0FGb0IsQ0FFaEIsVUFBQWlDLENBQUM7QUFBQSxlQUFJQSxDQUFDLENBQUMyQyxJQUFOO0FBQUEsT0FGZSxDQUF2QjtBQUlBLFVBQU1DLGNBQWMsR0FBRztBQUNyQmxILFFBQUFBLE9BQU8sRUFBRSx1RUFBU21ILGdDQUFlbkgsT0FBeEIsdUNBQW9DZ0gsY0FBcEM7QUFEWSxPQUF2QjtBQUlBLFVBQU1JLFlBQVksR0FBRyxLQUFLQyxzQkFBTCxDQUE0QkgsY0FBNUIsRUFBNENILE1BQTVDLENBQXJCOztBQUNBLFVBQUksQ0FBQ0ssWUFBRCxJQUFpQixDQUFDQSxZQUFZLENBQUNFLE1BQW5DLEVBQTJDO0FBQ3pDLGVBQU8sRUFBUDtBQUNEOztBQUVELGFBQU9GLFlBQVksQ0FBQy9FLEdBQWIsQ0FBaUIsVUFBQUwsT0FBTztBQUFBLGVBQUs7QUFDbENsRCxVQUFBQSxLQUFLLEVBQ0YsT0FBT0EsS0FBUCxLQUFpQixRQUFqQixJQUE2QkEsS0FBSyxDQUFDeUksT0FBTixDQUFjLFdBQWQsRUFBMkIsRUFBM0IsQ0FBOUIsSUFDQSxNQUFJLENBQUMzSSxJQUgyQjtBQUlsQ29ELFVBQUFBLE9BQU8sRUFBUEEsT0FKa0M7QUFLbEN3RixVQUFBQSxTQUFTLEVBQUU7QUFMdUIsU0FBTDtBQUFBLE9BQXhCLENBQVA7QUFPRDs7O0VBNUV1Q0MscUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMTkgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgbWVtb2l6ZSBmcm9tICdsb2Rhc2gubWVtb2l6ZSc7XG5pbXBvcnQgdW5pcSBmcm9tICdsb2Rhc2gudW5pcSc7XG5cbmltcG9ydCBMYXllciBmcm9tICcuLi9iYXNlLWxheWVyJztcbmltcG9ydCBIaWdobGlnaHRQb2x5Z29uTGF5ZXIgZnJvbSAnZGVja2dsLWxheWVycy9nZW9qc29uLWxheWVyL3NvbGlkLXBvbHlnb24tbGF5ZXInO1xuaW1wb3J0IHtHZW9Kc29uTGF5ZXIgYXMgRGVja0dMR2VvSnNvbkxheWVyfSBmcm9tICdkZWNrLmdsJztcblxuaW1wb3J0IHtoZXhUb1JnYn0gZnJvbSAndXRpbHMvY29sb3ItdXRpbHMnO1xuaW1wb3J0IHtcbiAgZ2V0R2VvanNvbkRhdGFNYXBzLFxuICBnZXRHZW9qc29uQm91bmRzLFxuICBmZWF0dXJlVG9EZWNrR2xHZW9UeXBlXG59IGZyb20gJy4vZ2VvanNvbi11dGlscyc7XG5pbXBvcnQgR2VvanNvbkxheWVySWNvbiBmcm9tICcuL2dlb2pzb24tbGF5ZXItaWNvbic7XG5pbXBvcnQge0dFT0pTT05fRklFTERTfSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbmV4cG9ydCBjb25zdCBnZW9qc29uVmlzQ29uZmlncyA9IHtcbiAgb3BhY2l0eTogJ29wYWNpdHknLFxuICB0aGlja25lc3M6IHtcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBkZWZhdWx0VmFsdWU6IDAuNSxcbiAgICBsYWJlbDogJ1N0cm9rZSBXaWR0aCcsXG4gICAgaXNSYW5nZWQ6IGZhbHNlLFxuICAgIHJhbmdlOiBbMCwgMTAwXSxcbiAgICBzdGVwOiAwLjEsXG4gICAgZ3JvdXA6ICdzdHJva2UnLFxuICAgIHByb3BlcnR5OiAndGhpY2tuZXNzJ1xuICB9LFxuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScsXG4gIHJhZGl1czogJ3JhZGl1cycsXG5cbiAgc2l6ZVJhbmdlOiAnc3Ryb2tlV2lkdGhSYW5nZScsXG4gIHJhZGl1c1JhbmdlOiAncmFkaXVzUmFuZ2UnLFxuICBoZWlnaHRSYW5nZTogJ2VsZXZhdGlvblJhbmdlJyxcbiAgZWxldmF0aW9uU2NhbGU6ICdlbGV2YXRpb25TY2FsZScsXG5cbiAgJ2hpLXByZWNpc2lvbic6ICdoaS1wcmVjaXNpb24nLFxuICBzdHJva2VkOiAnc3Ryb2tlZCcsXG4gIGZpbGxlZDogJ2ZpbGxlZCcsXG4gIGVuYWJsZTNkOiAnZW5hYmxlM2QnLFxuICB3aXJlZnJhbWU6ICd3aXJlZnJhbWUnXG59O1xuXG5leHBvcnQgY29uc3QgZ2VvSnNvblJlcXVpcmVkQ29sdW1ucyA9IFsnZ2VvanNvbiddO1xuZXhwb3J0IGNvbnN0IGZlYXR1cmVBY2Nlc3NvciA9ICh7Z2VvanNvbn0pID0+IGQgPT4gZFtnZW9qc29uLmZpZWxkSWR4XTtcbmV4cG9ydCBjb25zdCBmZWF0dXJlUmVzb2x2ZXIgPSAoe2dlb2pzb259KSA9PiBnZW9qc29uLmZpZWxkSWR4O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHZW9Kc29uTGF5ZXIgZXh0ZW5kcyBMYXllciB7XG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4gICAgdGhpcy5kYXRhVG9GZWF0dXJlID0ge307XG4gICAgdGhpcy5yZWdpc3RlclZpc0NvbmZpZyhnZW9qc29uVmlzQ29uZmlncyk7XG4gICAgdGhpcy5nZXRGZWF0dXJlID0gbWVtb2l6ZShmZWF0dXJlQWNjZXNzb3IsIGZlYXR1cmVSZXNvbHZlcik7XG4gIH1cblxuICBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2dlb2pzb24nO1xuICB9XG5cbiAgZ2V0IG5hbWUoKSB7XG4gICAgcmV0dXJuICdQb2x5Z29uJztcbiAgfVxuXG4gIGdldCBsYXllckljb24oKSB7XG4gICAgcmV0dXJuIEdlb2pzb25MYXllckljb247XG4gIH1cblxuICBnZXQgcmVxdWlyZWRMYXllckNvbHVtbnMoKSB7XG4gICAgcmV0dXJuIGdlb0pzb25SZXF1aXJlZENvbHVtbnM7XG4gIH1cblxuICBnZXQgdmlzdWFsQ2hhbm5lbHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN1cGVyLnZpc3VhbENoYW5uZWxzLFxuICAgICAgc2l6ZToge1xuICAgICAgICAuLi5zdXBlci52aXN1YWxDaGFubmVscy5zaXplLFxuICAgICAgICBwcm9wZXJ0eTogJ3N0cm9rZScsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcuc3Ryb2tlZFxuICAgICAgfSxcbiAgICAgIGhlaWdodDoge1xuICAgICAgICBwcm9wZXJ0eTogJ2hlaWdodCcsXG4gICAgICAgIGZpZWxkOiAnaGVpZ2h0RmllbGQnLFxuICAgICAgICBzY2FsZTogJ2hlaWdodFNjYWxlJyxcbiAgICAgICAgZG9tYWluOiAnaGVpZ2h0RG9tYWluJyxcbiAgICAgICAgcmFuZ2U6ICdoZWlnaHRSYW5nZScsXG4gICAgICAgIGtleTogJ2hlaWdodCcsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6ICdzaXplJyxcbiAgICAgICAgY29uZGl0aW9uOiBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZy5lbmFibGUzZFxuICAgICAgfSxcbiAgICAgIHJhZGl1czoge1xuICAgICAgICBwcm9wZXJ0eTogJ3JhZGl1cycsXG4gICAgICAgIGZpZWxkOiAncmFkaXVzRmllbGQnLFxuICAgICAgICBzY2FsZTogJ3JhZGl1c1NjYWxlJyxcbiAgICAgICAgZG9tYWluOiAncmFkaXVzRG9tYWluJyxcbiAgICAgICAgcmFuZ2U6ICdyYWRpdXNSYW5nZScsXG4gICAgICAgIGtleTogJ3JhZGl1cycsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6ICdyYWRpdXMnXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoe2xhYmVsLCBmaWVsZHN9KSB7XG4gICAgY29uc3QgZ2VvanNvbkNvbHVtbnMgPSBmaWVsZHNcbiAgICAgIC5maWx0ZXIoZiA9PiBmLnR5cGUgPT09ICdnZW9qc29uJylcbiAgICAgIC5tYXAoZiA9PiBmLm5hbWUpO1xuXG4gICAgY29uc3QgZGVmYXVsdENvbHVtbnMgPSB7XG4gICAgICBnZW9qc29uOiB1bmlxKFsuLi5HRU9KU09OX0ZJRUxEUy5nZW9qc29uLCAuLi5nZW9qc29uQ29sdW1uc10pXG4gICAgfTtcblxuICAgIGNvbnN0IGZvdW5kQ29sdW1ucyA9IHRoaXMuZmluZERlZmF1bHRDb2x1bW5GaWVsZChkZWZhdWx0Q29sdW1ucywgZmllbGRzKTtcbiAgICBpZiAoIWZvdW5kQ29sdW1ucyB8fCAhZm91bmRDb2x1bW5zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBmb3VuZENvbHVtbnMubWFwKGNvbHVtbnMgPT4gKHtcbiAgICAgIGxhYmVsOlxuICAgICAgICAodHlwZW9mIGxhYmVsID09PSAnc3RyaW5nJyAmJiBsYWJlbC5yZXBsYWNlKC9cXC5bXi8uXSskLywgJycpKSB8fFxuICAgICAgICB0aGlzLnR5cGUsXG4gICAgICBjb2x1bW5zLFxuICAgICAgaXNWaXNpYmxlOiB0cnVlXG4gICAgfSkpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzID0ge30pIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3VwZXIuZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzKSxcblxuICAgICAgLy8gYWRkIGhlaWdodCB2aXN1YWwgY2hhbm5lbFxuICAgICAgaGVpZ2h0RmllbGQ6IG51bGwsXG4gICAgICBoZWlnaHREb21haW46IFswLCAxXSxcbiAgICAgIGhlaWdodFNjYWxlOiAnbGluZWFyJyxcblxuICAgICAgLy8gYWRkIHJhZGl1cyB2aXN1YWwgY2hhbm5lbFxuICAgICAgcmFkaXVzRmllbGQ6IG51bGwsXG4gICAgICByYWRpdXNEb21haW46IFswLCAxXSxcbiAgICAgIHJhZGl1c1NjYWxlOiAnbGluZWFyJ1xuICAgIH07XG4gIH1cblxuICBnZXRIb3ZlckRhdGEob2JqZWN0LCBhbGxEYXRhKSB7XG4gICAgLy8gaW5kZXggb2YgYWxsRGF0YSBpcyBzYXZlZCB0byBmZWF0dXJlLnByb3BlcnRpZXNcbiAgICByZXR1cm4gYWxsRGF0YVtvYmplY3QucHJvcGVydGllcy5pbmRleF07XG4gIH1cblxuICAvLyBUT0RPOiBmaXggY29tcGxleGl0eVxuICAvKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG4gIGZvcm1hdExheWVyRGF0YShfLCBhbGxEYXRhLCBmaWx0ZXJlZEluZGV4LCBvbGRMYXllckRhdGEsIG9wdCA9IHt9KSB7XG4gICAgY29uc3Qge1xuICAgICAgY29sb3JTY2FsZSxcbiAgICAgIGNvbG9yRmllbGQsXG4gICAgICBjb2xvckRvbWFpbixcbiAgICAgIGNvbG9yLFxuICAgICAgc2l6ZVNjYWxlLFxuICAgICAgc2l6ZURvbWFpbixcbiAgICAgIHNpemVGaWVsZCxcbiAgICAgIGhlaWdodEZpZWxkLFxuICAgICAgaGVpZ2h0RG9tYWluLFxuICAgICAgaGVpZ2h0U2NhbGUsXG4gICAgICByYWRpdXNGaWVsZCxcbiAgICAgIHJhZGl1c0RvbWFpbixcbiAgICAgIHJhZGl1c1NjYWxlLFxuICAgICAgdmlzQ29uZmlnLFxuICAgICAgY29sdW1uc1xuICAgIH0gPSB0aGlzLmNvbmZpZztcblxuICAgIGNvbnN0IHtcbiAgICAgIGVuYWJsZTNkLFxuICAgICAgc3Ryb2tlZCxcbiAgICAgIGNvbG9yUmFuZ2UsXG4gICAgICBoZWlnaHRSYW5nZSxcbiAgICAgIHNpemVSYW5nZSxcbiAgICAgIHJhZGl1c1JhbmdlXG4gICAgfSA9IHZpc0NvbmZpZztcblxuICAgIGNvbnN0IGdldEZlYXR1cmUgPSB0aGlzLmdldEZlYXR1cmUoY29sdW1ucyk7XG4gICAgLy8gZ2VvanNvbiBmZWF0dXJlIGFyZSBvYmplY3QsIGlmIGRvZXNuJ3QgZXhpc3RzXG4gICAgLy8gY3JlYXRlIGl0IGFuZCBzYXZlIHRvIGxheWVyXG4gICAgaWYgKCFvbGRMYXllckRhdGEgfHwgb2xkTGF5ZXJEYXRhLmdldEZlYXR1cmUgIT09IGdldEZlYXR1cmUpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJNZXRhKGFsbERhdGEsIGdldEZlYXR1cmUpO1xuICAgIH1cblxuICAgIGxldCBnZW9qc29uRGF0YTtcblxuICAgIGlmIChcbiAgICAgIG9sZExheWVyRGF0YSAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmRhdGEgJiZcbiAgICAgIG9wdC5zYW1lRGF0YSAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmdldEZlYXR1cmUgPT09IGdldEZlYXR1cmVcbiAgICApIHtcbiAgICAgIC8vIG5vIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGFycmF5IG9mIGRhdGFcbiAgICAgIC8vIHVzZSB1cGRhdGVUcmlnZ2VycyB0byBzZWxlY3RpdmVseSByZS1jYWxjdWxhdGUgYXR0cmlidXRlc1xuICAgICAgZ2VvanNvbkRhdGEgPSBvbGRMYXllckRhdGEuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZmlsdGVyZWRJbmRleCBpcyBhIHJlZmVyZW5jZSBvZiBpbmRleCBpbiBhbGxEYXRhIHdoaWNoIGNhbiBtYXAgdG8gZmVhdHVyZVxuICAgICAgZ2VvanNvbkRhdGEgPSBmaWx0ZXJlZEluZGV4XG4gICAgICAgIC5tYXAoaSA9PiB0aGlzLmRhdGFUb0ZlYXR1cmVbaV0pXG4gICAgICAgIC5maWx0ZXIoZCA9PiBkKTtcbiAgICB9XG5cbiAgICBcblxuICAgIGNvbnN0IGNTY2FsZSA9XG4gICAgICBjb2xvckZpZWxkICYmXG4gICAgICB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShcbiAgICAgICAgY29sb3JTY2FsZSxcbiAgICAgICAgY29sb3JEb21haW4sXG4gICAgICAgIGNvbG9yUmFuZ2UuY29sb3JzLm1hcChoZXhUb1JnYilcbiAgICAgICk7XG5cbiAgICAvLyBjYWxjdWxhdGUgc3Ryb2tlIHNjYWxlIC0gaWYgc3Ryb2tlZCA9IHRydWVcbiAgICBjb25zdCBzU2NhbGUgPVxuICAgICAgc2l6ZUZpZWxkICYmXG4gICAgICBzdHJva2VkICYmXG4gICAgICB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShzaXplU2NhbGUsIHNpemVEb21haW4sIHNpemVSYW5nZSk7XG5cbiAgICAvLyBjYWxjdWxhdGUgZWxldmF0aW9uIHNjYWxlIC0gaWYgZXh0cnVkZWQgPSB0cnVlXG4gICAgY29uc3QgZVNjYWxlID1cbiAgICAgIGhlaWdodEZpZWxkICYmXG4gICAgICBlbmFibGUzZCAmJlxuICAgICAgdGhpcy5nZXRWaXNDaGFubmVsU2NhbGUoaGVpZ2h0U2NhbGUsIGhlaWdodERvbWFpbiwgaGVpZ2h0UmFuZ2UpO1xuICAgIC8vIGNvbnNvbGUubG9nKCdlU2NhbGUgaW5zaWRlIGZvcm1hdExheWVyRGF0YScsIGVTY2FsZSk7XG4gICAgLy8gcG9pbnQgcmFkaXVzXG4gICAgY29uc3QgclNjYWxlID1cbiAgICAgIHJhZGl1c0ZpZWxkICYmXG4gICAgICB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShyYWRpdXNTY2FsZSwgcmFkaXVzRG9tYWluLCByYWRpdXNSYW5nZSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogZ2VvanNvbkRhdGEsXG4gICAgICBnZXRGZWF0dXJlLFxuICAgICAgZ2V0RmlsbENvbG9yOiBkID0+XG4gICAgICAgIGNTY2FsZVxuICAgICAgICAgID8gdGhpcy5nZXRFbmNvZGVkQ2hhbm5lbFZhbHVlKFxuICAgICAgICAgICAgICBjU2NhbGUsXG4gICAgICAgICAgICAgIGFsbERhdGFbZC5wcm9wZXJ0aWVzLmluZGV4XSxcbiAgICAgICAgICAgICAgY29sb3JGaWVsZFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogZC5wcm9wZXJ0aWVzLmZpbGxDb2xvciB8fCBjb2xvcixcbiAgICAgIGdldExpbmVDb2xvcjogZCA9PlxuICAgICAgICBjU2NhbGVcbiAgICAgICAgICA/IHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShcbiAgICAgICAgICAgICAgY1NjYWxlLFxuICAgICAgICAgICAgICBhbGxEYXRhW2QucHJvcGVydGllcy5pbmRleF0sXG4gICAgICAgICAgICAgIGNvbG9yRmllbGRcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGQucHJvcGVydGllcy5saW5lQ29sb3IgfHwgY29sb3IsXG4gICAgICBnZXRMaW5lV2lkdGg6IGQgPT5cbiAgICAgICAgc1NjYWxlXG4gICAgICAgICAgPyB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoXG4gICAgICAgICAgICAgIHNTY2FsZSxcbiAgICAgICAgICAgICAgYWxsRGF0YVtkLnByb3BlcnRpZXMuaW5kZXhdLFxuICAgICAgICAgICAgICBzaXplRmllbGQsXG4gICAgICAgICAgICAgIDBcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGQucHJvcGVydGllcy5saW5lV2lkdGggfHwgMSxcbiAgICAgIGdldEVsZXZhdGlvbjogZCA9PlxuICAgICAgICBlU2NhbGVcbiAgICAgICAgICA/IHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShcbiAgICAgICAgICAgICAgZVNjYWxlLFxuICAgICAgICAgICAgICBhbGxEYXRhW2QucHJvcGVydGllcy5pbmRleF0sXG4gICAgICAgICAgICAgIGhlaWdodEZpZWxkLFxuICAgICAgICAgICAgICAwXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBkLnByb3BlcnRpZXMuZWxldmF0aW9uIHx8IDUwMCxcbiAgICAgIGdldFJhZGl1czogZCA9PlxuICAgICAgICByU2NhbGVcbiAgICAgICAgICA/IHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShcbiAgICAgICAgICAgICAgclNjYWxlLFxuICAgICAgICAgICAgICBhbGxEYXRhW2QucHJvcGVydGllcy5pbmRleF0sXG4gICAgICAgICAgICAgIHJhZGl1c0ZpZWxkLFxuICAgICAgICAgICAgICAwXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBkLnByb3BlcnRpZXMucmFkaXVzIHx8IDFcbiAgICB9O1xuICB9XG4gIC8qIGVzbGludC1lbmFibGUgY29tcGxleGl0eSAqL1xuXG4gIHVwZGF0ZUxheWVyTWV0YShhbGxEYXRhLCBnZXRGZWF0dXJlKSB7XG4gICAgdGhpcy5kYXRhVG9GZWF0dXJlID0gZ2V0R2VvanNvbkRhdGFNYXBzKGFsbERhdGEsIGdldEZlYXR1cmUpO1xuXG4gICAgLy8gY2FsY3VsYXRlIGxheWVyIG1ldGFcbiAgICBjb25zdCBhbGxGZWF0dXJlcyA9IE9iamVjdC52YWx1ZXModGhpcy5kYXRhVG9GZWF0dXJlKTtcblxuICAgIC8vIGdldCBib3VuZHMgZnJvbSBmZWF0dXJlc1xuICAgIGNvbnN0IGJvdW5kcyA9IGdldEdlb2pzb25Cb3VuZHMoYWxsRmVhdHVyZXMpO1xuXG4gICAgLy8gZ2V0IGxpZ2h0U2V0dGluZ3MgZnJvbSBwb2ludHNcbiAgICBjb25zdCBsaWdodFNldHRpbmdzID0gdGhpcy5nZXRMaWdodFNldHRpbmdzRnJvbUJvdW5kcyhib3VuZHMpO1xuXG4gICAgLy8gaWYgYW55IG9mIHRoZSBmZWF0dXJlIGhhcyBwcm9wZXJ0aWVzLmhpLXByZWNpc2lvbiBzZXQgdG8gYmUgdHJ1ZVxuICAgIGNvbnN0IGZwNjQgPSBCb29sZWFuKFxuICAgICAgYWxsRmVhdHVyZXMuZmluZChkID0+IGQgJiYgZC5wcm9wZXJ0aWVzICYmIGQucHJvcGVydGllc1snaGktcHJlY2lzaW9uJ10pXG4gICAgKTtcbiAgICBjb25zdCBmaXhlZFJhZGl1cyA9IEJvb2xlYW4oXG4gICAgICBhbGxGZWF0dXJlcy5maW5kKGQgPT4gZCAmJiBkLnByb3BlcnRpZXMgJiYgZC5wcm9wZXJ0aWVzLnJhZGl1cylcbiAgICApO1xuXG4gICAgLy8ga2VlcCBhIHJlY29yZCBvZiB3aGF0IHR5cGUgb2YgZ2VvbWV0cnkgdGhlIGNvbGxlY3Rpb24gaGFzXG4gICAgY29uc3QgZmVhdHVyZVR5cGVzID0gYWxsRmVhdHVyZXMucmVkdWNlKChhY2N1LCBmKSA9PiB7XG4gICAgICBjb25zdCBnZW9UeXBlID0gZmVhdHVyZVRvRGVja0dsR2VvVHlwZShcbiAgICAgICAgZiAmJiBmLmdlb21ldHJ5ICYmIGYuZ2VvbWV0cnkudHlwZVxuICAgICAgKTtcblxuICAgICAgaWYgKGdlb1R5cGUpIHtcbiAgICAgICAgYWNjdVtnZW9UeXBlXSA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdTtcbiAgICB9LCB7fSk7XG5cbiAgICB0aGlzLnVwZGF0ZU1ldGEoe2JvdW5kcywgbGlnaHRTZXR0aW5ncywgZnA2NCwgZml4ZWRSYWRpdXMsIGZlYXR1cmVUeXBlc30pO1xuICB9XG5cbiAgcmVuZGVyTGF5ZXIoe2RhdGEsIGlkeCwgb2JqZWN0SG92ZXJlZCwgbWFwU3RhdGUsIGludGVyYWN0aW9uQ29uZmlnfSkge1xuICAgIGNvbnN0IHtmcDY0LCBsaWdodFNldHRpbmdzLCBmaXhlZFJhZGl1c30gPSB0aGlzLm1ldGE7XG4gICAgY29uc3QgcmFkaXVzU2NhbGUgPSB0aGlzLmdldFJhZGl1c1NjYWxlQnlab29tKG1hcFN0YXRlLCBmaXhlZFJhZGl1cyk7XG4gICAgY29uc3Qgem9vbUZhY3RvciA9IHRoaXMuZ2V0Wm9vbUZhY3RvcihtYXBTdGF0ZSk7XG4gICAgY29uc3Qge3Zpc0NvbmZpZ30gPSB0aGlzLmNvbmZpZztcblxuICAgIGNvbnN0IGxheWVyUHJvcHMgPSB7XG4gICAgICAvLyBtdWx0aXBsaWVyIGFwcGxpZWQganVzdCBzbyBpdCBiZWluZyBjb25zaXN0ZW50IHdpdGggcHJldmlvdXNseSBzYXZlZCBtYXBzXG4gICAgICBsaW5lV2lkdGhTY2FsZTogdmlzQ29uZmlnLnRoaWNrbmVzcyAqIHpvb21GYWN0b3IgKiA4LFxuICAgICAgbGluZVdpZHRoTWluUGl4ZWxzOiAxLFxuICAgICAgZWxldmF0aW9uU2NhbGU6IHZpc0NvbmZpZy5lbGV2YXRpb25TY2FsZSxcbiAgICAgIHBvaW50UmFkaXVzU2NhbGU6IHJhZGl1c1NjYWxlLFxuICAgICAgZnA2NDogZnA2NCB8fCB2aXNDb25maWdbJ2hpLXByZWNpc2lvbiddLFxuICAgICAgbGluZU1pdGVyTGltaXQ6IDRcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlVHJpZ2dlcnMgPSB7XG4gICAgICBnZXRFbGV2YXRpb246IHtcbiAgICAgICAgaGVpZ2h0RmllbGQ6IHRoaXMuY29uZmlnLmhlaWdodEZpZWxkLFxuICAgICAgICBoZWlnaHRTY2FsZTogdGhpcy5jb25maWcuaGVpZ2h0U2NhbGUsXG4gICAgICAgIGhlaWdodFJhbmdlOiB2aXNDb25maWcuaGVpZ2h0UmFuZ2VcbiAgICAgIH0sXG4gICAgICBnZXRGaWxsQ29sb3I6IHtcbiAgICAgICAgY29sb3I6IHRoaXMuY29uZmlnLmNvbG9yLFxuICAgICAgICBjb2xvckZpZWxkOiB0aGlzLmNvbmZpZy5jb2xvckZpZWxkLFxuICAgICAgICBjb2xvclJhbmdlOiB2aXNDb25maWcuY29sb3JSYW5nZSxcbiAgICAgICAgY29sb3JTY2FsZTogdGhpcy5jb25maWcuY29sb3JTY2FsZVxuICAgICAgfSxcbiAgICAgIGdldExpbmVDb2xvcjoge1xuICAgICAgICBjb2xvcjogdGhpcy5jb25maWcuY29sb3IsXG4gICAgICAgIGNvbG9yRmllbGQ6IHRoaXMuY29uZmlnLmNvbG9yRmllbGQsXG4gICAgICAgIGNvbG9yUmFuZ2U6IHZpc0NvbmZpZy5jb2xvclJhbmdlLFxuICAgICAgICBjb2xvclNjYWxlOiB0aGlzLmNvbmZpZy5jb2xvclNjYWxlXG4gICAgICB9LFxuICAgICAgZ2V0TGluZVdpZHRoOiB7XG4gICAgICAgIHNpemVGaWVsZDogdGhpcy5jb25maWcuc2l6ZUZpZWxkLFxuICAgICAgICBzaXplUmFuZ2U6IHZpc0NvbmZpZy5zaXplUmFuZ2VcbiAgICAgIH0sXG4gICAgICBnZXRSYWRpdXM6IHtcbiAgICAgICAgcmFkaXVzRmllbGQ6IHRoaXMuY29uZmlnLnJhZGl1c0ZpZWxkLFxuICAgICAgICByYWRpdXNSYW5nZTogdmlzQ29uZmlnLnJhZGl1c1JhbmdlXG4gICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IERlY2tHTEdlb0pzb25MYXllcih7XG4gICAgICAgIC4uLmxheWVyUHJvcHMsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICBpZHgsXG4gICAgICAgIGRhdGE6IGRhdGEuZGF0YSxcbiAgICAgICAgZ2V0RmlsbENvbG9yOiBkYXRhLmdldEZpbGxDb2xvcixcbiAgICAgICAgZ2V0TGluZUNvbG9yOiBkYXRhLmdldExpbmVDb2xvcixcbiAgICAgICAgZ2V0TGluZVdpZHRoOiBkYXRhLmdldExpbmVXaWR0aCxcbiAgICAgICAgZ2V0UmFkaXVzOiBkYXRhLmdldFJhZGl1cyxcbiAgICAgICAgZ2V0RWxldmF0aW9uOiBkYXRhLmdldEVsZXZhdGlvbixcbiAgICAgICAgLy8gaGlnaGxpZ2h0XG4gICAgICAgIHBpY2thYmxlOiB0cnVlLFxuICAgICAgICAvLyBoaWdobGlnaHRDb2xvcjogdGhpcy5jb25maWcuaGlnaGxpZ2h0Q29sb3IsXG4gICAgICAgIGF1dG9IaWdobGlnaHQ6IHZpc0NvbmZpZy5lbmFibGUzZCxcbiAgICAgICAgLy8gcGFyYW1ldGVyc1xuICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgZGVwdGhUZXN0OiBCb29sZWFuKHZpc0NvbmZpZy5lbmFibGUzZCB8fCBtYXBTdGF0ZS5kcmFnUm90YXRlKVxuICAgICAgICB9LFxuICAgICAgICBvcGFjaXR5OiB2aXNDb25maWcub3BhY2l0eSxcbiAgICAgICAgc3Ryb2tlZDogdmlzQ29uZmlnLnN0cm9rZWQsXG4gICAgICAgIGZpbGxlZDogdmlzQ29uZmlnLmZpbGxlZCxcbiAgICAgICAgZXh0cnVkZWQ6IHZpc0NvbmZpZy5lbmFibGUzZCxcbiAgICAgICAgd2lyZWZyYW1lOiB2aXNDb25maWcud2lyZWZyYW1lLFxuICAgICAgICBsaWdodFNldHRpbmdzLFxuICAgICAgICB1cGRhdGVUcmlnZ2VycyxcblxuICAgICAgICBzdWJMYXllcnM6IHtcbiAgICAgICAgICAuLi5EZWNrR0xHZW9Kc29uTGF5ZXIuZGVmYXVsdFByb3BzLnN1YkxheWVycyxcbiAgICAgICAgICBQb2x5Z29uTGF5ZXI6IEhpZ2hsaWdodFBvbHlnb25MYXllclxuICAgICAgICB9XG4gICAgICB9KSxcbiAgICAgIC4uLih0aGlzLmlzTGF5ZXJIb3ZlcmVkKG9iamVjdEhvdmVyZWQpICYmICF2aXNDb25maWcuZW5hYmxlM2RcbiAgICAgICAgPyBbXG4gICAgICAgICAgICBuZXcgRGVja0dMR2VvSnNvbkxheWVyKHtcbiAgICAgICAgICAgICAgLi4ubGF5ZXJQcm9wcyxcbiAgICAgICAgICAgICAgaWQ6IGAke3RoaXMuaWR9LWhvdmVyZWRgLFxuICAgICAgICAgICAgICBkYXRhOiBbb2JqZWN0SG92ZXJlZC5vYmplY3RdLFxuICAgICAgICAgICAgICBnZXRMaW5lV2lkdGg6IGRhdGEuZ2V0TGluZVdpZHRoLFxuICAgICAgICAgICAgICBnZXRSYWRpdXM6IGRhdGEuZ2V0UmFkaXVzLFxuICAgICAgICAgICAgICBnZXRFbGV2YXRpb246IGRhdGEuZ2V0RWxldmF0aW9uLFxuICAgICAgICAgICAgICBnZXRMaW5lQ29sb3I6IHRoaXMuY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgICAgICAgICBnZXRGaWxsQ29sb3I6IHRoaXMuY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgICAgICAgICB1cGRhdGVUcmlnZ2VycyxcbiAgICAgICAgICAgICAgc3Ryb2tlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgcGlja2FibGU6IGZhbHNlLFxuICAgICAgICAgICAgICBmaWxsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIF1cbiAgICAgICAgOiBbXSlcbiAgICBdO1xuICB9XG59XG4iXX0=