UNPKG

kepler.gl.geoiq

Version:

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

462 lines (406 loc) 54.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.geojsonVisConfigs = exports.geoJsonRequiredColumns = exports.featureResolver = exports.featureAccessor = exports["default"] = 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 _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); 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 _lodash = _interopRequireDefault(require("lodash.memoize")); var _lodash2 = _interopRequireDefault(require("lodash.uniq")); var _baseLayer = _interopRequireWildcard(require("../base-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 _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 || _typeof(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; } } var geojsonVisConfigs = exports.geojsonVisConfigs = { opacity: 'opacity', thickness: { type: 'number', defaultValue: 0.5, label: 'Stroke Width', isRanged: false, range: [0, 100], step: 0.1, group: 'stroke', property: 'thickness' }, strokeColor: 'strokeColor', colorRange: 'colorRange', strokeColorRange: 'strokeColorRange', radius: 'radius', sizeRange: 'strokeWidthRange', radiusRange: 'radiusRange', heightRange: 'elevationRange', elevationScale: 'elevationScale', stroked: 'stroked', filled: 'filled', enable3d: 'enable3d', wireframe: 'wireframe' }; var geoJsonRequiredColumns = exports.geoJsonRequiredColumns = ['geojson']; var featureAccessor = exports.featureAccessor = function featureAccessor(_ref) { var geojson = _ref.geojson; return function (d) { return d[geojson.fieldIdx]; }; }; var featureResolver = exports.featureResolver = function featureResolver(_ref2) { var geojson = _ref2.geojson; return geojson.fieldIdx; }; var GeoJsonLayer = exports["default"] = /*#__PURE__*/function (_Layer) { (0, _inherits2["default"])(GeoJsonLayer, _Layer); var _super = _createSuper(GeoJsonLayer); function GeoJsonLayer(props) { var _this; (0, _classCallCheck2["default"])(this, GeoJsonLayer); _this = _super.call(this, props); _this.dataToFeature = []; _this.registerVisConfig(geojsonVisConfigs); _this.getFeature = (0, _lodash["default"])(featureAccessor, featureResolver); return _this; } (0, _createClass2["default"])(GeoJsonLayer, [{ 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(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(GeoJsonLayer.prototype), "visualChannels", this)), {}, { strokeColor: { property: 'strokeColor', field: 'strokeColorField', scale: 'strokeColorScale', domain: 'strokeColorDomain', range: 'strokeColorRange', key: 'strokeColor', channelScaleType: _defaultSettings.CHANNEL_SCALES.color, condition: function condition(config) { return config.visConfig.stroked; } }, size: _objectSpread(_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: "getPositionAccessor", value: function getPositionAccessor() { return this.getFeature(this.config.columns); } }, { key: "getDefaultLayerConfig", value: function getDefaultLayerConfig() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return _objectSpread(_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', // add stroke color visual channel strokeColorField: null, strokeColorDomain: [0, 1], strokeColorScale: 'quantile' }); } }, { key: "getHoverData", value: function getHoverData(object) { // index of allData is saved to feature.properties return object; } // 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, strokeColorField = _this$config.strokeColorField, strokeColorScale = _this$config.strokeColorScale, strokeColorDomain = _this$config.strokeColorDomain, 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; var enable3d = visConfig.enable3d, stroked = visConfig.stroked, colorRange = visConfig.colorRange, heightRange = visConfig.heightRange, sizeRange = visConfig.sizeRange, radiusRange = visConfig.radiusRange, strokeColorRange = visConfig.strokeColorRange, strokeColor = visConfig.strokeColor; var getFeature = this.getPositionAccessor(this.config.column); // 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; }); } // fill color var cScale = colorField && this.getVisChannelScale(colorScale, colorDomain, colorRange.colors.map(_colorUtils.hexToRgb)); // stroke color var scScale = strokeColorField && this.getVisChannelScale(strokeColorScale, strokeColorDomain, strokeColorRange.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 scScale ? _this2.getEncodedChannelValue(scScale, allData[d.properties.index], strokeColorField) : d.properties.lineColor || strokeColor || 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) { var getFeature = this.getPositionAccessor(); this.dataToFeature = (0, _geojsonUtils.getGeojsonDataMaps)(allData, getFeature); // get bounds from features var bounds = (0, _geojsonUtils.getGeojsonBounds)(this.dataToFeature); // if any of the feature has properties.radius set to be true var fixedRadius = Boolean(this.dataToFeature.find(function (d) { return d && d.properties && d.properties.radius; })); // keep a record of what type of geometry the collection has var featureTypes = (0, _geojsonUtils.getGeojsonFeatureTypes)(this.dataToFeature); this.updateMeta({ bounds: bounds, fixedRadius: fixedRadius, featureTypes: featureTypes }); } }, { key: "setInitialLayerConfig", value: function setInitialLayerConfig(allData) { this.updateLayerMeta(allData); var featureTypes = this.meta.featureTypes; // default settings is stroke: true, filled: false if (featureTypes && featureTypes.polygon) { // set both fill and stroke to true return this.updateLayerVisConfig({ filled: true, stroked: true, strokeColor: _baseLayer.colorMaker.next().value }); } else if (featureTypes && featureTypes.point) { // set fill to true if detect point return this.updateLayerVisConfig({ filled: true, stroked: false }); } return this; } }, { key: "renderLayer", value: function renderLayer(_ref3) { var data = _ref3.data, idx = _ref3.idx, objectHovered = _ref3.objectHovered, mapState = _ref3.mapState, interactionConfig = _ref3.interactionConfig; var 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, elevationScale: visConfig.elevationScale, pointRadiusScale: radiusScale, 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: visConfig.strokeColor, colorField: this.config.strokeColorField, colorRange: visConfig.strokeColorRange, colorScale: this.config.strokeColorScale }, getLineWidth: { sizeField: this.config.sizeField, sizeRange: visConfig.sizeRange }, getRadius: { radiusField: this.config.radiusField, radiusRange: visConfig.radiusRange } }; return [new _deck.GeoJsonLayer(_objectSpread(_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: _defaultSettings.HIGHLIGH_COLOR_3D, 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, lineMiterLimit: 2, rounded: true, updateTriggers: updateTriggers }))].concat((0, _toConsumableArray2["default"])(this.isLayerHovered(objectHovered) && !visConfig.enable3d ? [new _deck.GeoJsonLayer(_objectSpread(_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: "findDefaultLayerProps", value: function findDefaultLayerProps(_ref4) { var _this3 = this; var label = _ref4.label, _ref4$fields = _ref4.fields, fields = _ref4$fields === void 0 ? [] : _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 { props: [] }; } return { props: foundColumns.map(function (columns) { return { label: typeof label === 'string' && label.replace(/\.[^/.]+$/, '') || _this3.type, columns: columns, isVisible: true }; }) }; } }]); return GeoJsonLayer; }(_baseLayer["default"]); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYXllcnMvZ2VvanNvbi1sYXllci9nZW9qc29uLWxheWVyLmpzIl0sIm5hbWVzIjpbImdlb2pzb25WaXNDb25maWdzIiwib3BhY2l0eSIsInRoaWNrbmVzcyIsInR5cGUiLCJkZWZhdWx0VmFsdWUiLCJsYWJlbCIsImlzUmFuZ2VkIiwicmFuZ2UiLCJzdGVwIiwiZ3JvdXAiLCJwcm9wZXJ0eSIsInN0cm9rZUNvbG9yIiwiY29sb3JSYW5nZSIsInN0cm9rZUNvbG9yUmFuZ2UiLCJyYWRpdXMiLCJzaXplUmFuZ2UiLCJyYWRpdXNSYW5nZSIsImhlaWdodFJhbmdlIiwiZWxldmF0aW9uU2NhbGUiLCJzdHJva2VkIiwiZmlsbGVkIiwiZW5hYmxlM2QiLCJ3aXJlZnJhbWUiLCJnZW9Kc29uUmVxdWlyZWRDb2x1bW5zIiwiZmVhdHVyZUFjY2Vzc29yIiwiZ2VvanNvbiIsImQiLCJmaWVsZElkeCIsImZlYXR1cmVSZXNvbHZlciIsIkdlb0pzb25MYXllciIsInByb3BzIiwiZGF0YVRvRmVhdHVyZSIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0RmVhdHVyZSIsIkdlb2pzb25MYXllckljb24iLCJmaWVsZCIsInNjYWxlIiwiZG9tYWluIiwia2V5IiwiY2hhbm5lbFNjYWxlVHlwZSIsIkNIQU5ORUxfU0NBTEVTIiwiY29sb3IiLCJjb25kaXRpb24iLCJjb25maWciLCJ2aXNDb25maWciLCJzaXplIiwiaGVpZ2h0IiwiY29sdW1ucyIsImhlaWdodEZpZWxkIiwiaGVpZ2h0RG9tYWluIiwiaGVpZ2h0U2NhbGUiLCJyYWRpdXNGaWVsZCIsInJhZGl1c0RvbWFpbiIsInJhZGl1c1NjYWxlIiwic3Ryb2tlQ29sb3JGaWVsZCIsInN0cm9rZUNvbG9yRG9tYWluIiwic3Ryb2tlQ29sb3JTY2FsZSIsIm9iamVjdCIsIl8iLCJhbGxEYXRhIiwiZmlsdGVyZWRJbmRleCIsIm9sZExheWVyRGF0YSIsIm9wdCIsImNvbG9yU2NhbGUiLCJjb2xvckZpZWxkIiwiY29sb3JEb21haW4iLCJzaXplU2NhbGUiLCJzaXplRG9tYWluIiwic2l6ZUZpZWxkIiwiZ2V0UG9zaXRpb25BY2Nlc3NvciIsImNvbHVtbiIsInVwZGF0ZUxheWVyTWV0YSIsImdlb2pzb25EYXRhIiwiZGF0YSIsInNhbWVEYXRhIiwibWFwIiwiaSIsImZpbHRlciIsImNTY2FsZSIsImdldFZpc0NoYW5uZWxTY2FsZSIsImNvbG9ycyIsImhleFRvUmdiIiwic2NTY2FsZSIsInNTY2FsZSIsImVTY2FsZSIsInJTY2FsZSIsImdldEZpbGxDb2xvciIsImdldEVuY29kZWRDaGFubmVsVmFsdWUiLCJwcm9wZXJ0aWVzIiwiaW5kZXgiLCJmaWxsQ29sb3IiLCJnZXRMaW5lQ29sb3IiLCJsaW5lQ29sb3IiLCJnZXRMaW5lV2lkdGgiLCJsaW5lV2lkdGgiLCJnZXRFbGV2YXRpb24iLCJlbGV2YXRpb24iLCJnZXRSYWRpdXMiLCJib3VuZHMiLCJmaXhlZFJhZGl1cyIsIkJvb2xlYW4iLCJmaW5kIiwiZmVhdHVyZVR5cGVzIiwidXBkYXRlTWV0YSIsIm1ldGEiLCJwb2x5Z29uIiwidXBkYXRlTGF5ZXJWaXNDb25maWciLCJjb2xvck1ha2VyIiwibmV4dCIsInZhbHVlIiwicG9pbnQiLCJpZHgiLCJvYmplY3RIb3ZlcmVkIiwibWFwU3RhdGUiLCJpbnRlcmFjdGlvbkNvbmZpZyIsImdldFJhZGl1c1NjYWxlQnlab29tIiwiem9vbUZhY3RvciIsImdldFpvb21GYWN0b3IiLCJsYXllclByb3BzIiwibGluZVdpZHRoU2NhbGUiLCJwb2ludFJhZGl1c1NjYWxlIiwibGluZU1pdGVyTGltaXQiLCJ1cGRhdGVUcmlnZ2VycyIsIkRlY2tHTEdlb0pzb25MYXllciIsImlkIiwicGlja2FibGUiLCJoaWdobGlnaHRDb2xvciIsIkhJR0hMSUdIX0NPTE9SXzNEIiwiYXV0b0hpZ2hsaWdodCIsInBhcmFtZXRlcnMiLCJkZXB0aFRlc3QiLCJkcmFnUm90YXRlIiwiZXh0cnVkZWQiLCJyb3VuZGVkIiwiaXNMYXllckhvdmVyZWQiLCJmaWVsZHMiLCJnZW9qc29uQ29sdW1ucyIsImYiLCJuYW1lIiwiZGVmYXVsdENvbHVtbnMiLCJHRU9KU09OX0ZJRUxEUyIsImZvdW5kQ29sdW1ucyIsImZpbmREZWZhdWx0Q29sdW1uRmllbGQiLCJsZW5ndGgiLCJyZXBsYWNlIiwiaXNWaXNpYmxlIiwiTGF5ZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFLQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFNTyxJQUFNQSxpQkFBaUIsK0JBQUc7QUFDL0JDLEVBQUFBLE9BQU8sRUFBRSxTQURzQjtBQUUvQkMsRUFBQUEsU0FBUyxFQUFFO0FBQ1RDLElBQUFBLElBQUksRUFBRSxRQURHO0FBRVRDLElBQUFBLFlBQVksRUFBRSxHQUZMO0FBR1RDLElBQUFBLEtBQUssRUFBRSxjQUhFO0FBSVRDLElBQUFBLFFBQVEsRUFBRSxLQUpEO0FBS1RDLElBQUFBLEtBQUssRUFBRSxDQUFDLENBQUQsRUFBSSxHQUFKLENBTEU7QUFNVEMsSUFBQUEsSUFBSSxFQUFFLEdBTkc7QUFPVEMsSUFBQUEsS0FBSyxFQUFFLFFBUEU7QUFRVEMsSUFBQUEsUUFBUSxFQUFFO0FBUkQsR0FGb0I7QUFZL0JDLEVBQUFBLFdBQVcsRUFBRSxhQVprQjtBQWEvQkMsRUFBQUEsVUFBVSxFQUFFLFlBYm1CO0FBYy9CQyxFQUFBQSxnQkFBZ0IsRUFBRSxrQkFkYTtBQWUvQkMsRUFBQUEsTUFBTSxFQUFFLFFBZnVCO0FBaUIvQkMsRUFBQUEsU0FBUyxFQUFFLGtCQWpCb0I7QUFrQi9CQyxFQUFBQSxXQUFXLEVBQUUsYUFsQmtCO0FBbUIvQkMsRUFBQUEsV0FBVyxFQUFFLGdCQW5Ca0I7QUFvQi9CQyxFQUFBQSxjQUFjLEVBQUUsZ0JBcEJlO0FBcUIvQkMsRUFBQUEsT0FBTyxFQUFFLFNBckJzQjtBQXNCL0JDLEVBQUFBLE1BQU0sRUFBRSxRQXRCdUI7QUF1Qi9CQyxFQUFBQSxRQUFRLEVBQUUs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QURZLE9BQXZCO0FBSUEsVUFBTUssWUFBWSxHQUFHLEtBQUtDLHNCQUFMLENBQTRCSCxjQUE1QixFQUE0Q0osTUFBNUMsQ0FBckI7O0FBQ0EsVUFBSSxDQUFDTSxZQUFELElBQWlCLENBQUNBLFlBQVksQ0FBQ0UsTUFBbkMsRUFBMkM7QUFDekMsZUFBTztBQUFDakgsVUFBQUEsS0FBSyxFQUFFO0FBQVIsU0FBUDtBQUNEOztBQUVELGFBQU87QUFDTEEsUUFBQUEsS0FBSyxFQUFFK0csWUFBWSxDQUFDbEUsR0FBYixDQUFpQixVQUFBNUIsT0FBTztBQUFBLGlCQUFLO0FBQ2xDMUMsWUFBQUEsS0FBSyxFQUNGLE9BQU9BLEtBQVAsS0FBaUIsUUFBakIsSUFBNkJBLEtBQUssQ0FBQzJJLE9BQU4sQ0FBYyxXQUFkLEVBQTJCLEVBQTNCLENBQTlCLElBQ0EsTUFBSSxDQUFDN0ksSUFIMkI7QUFJbEM0QyxZQUFBQSxPQUFPLEVBQVBBLE9BSmtDO0FBS2xDa0csWUFBQUEsU0FBUyxFQUFFO0FBTHVCLFdBQUw7QUFBQSxTQUF4QjtBQURGLE9BQVA7QUFTRDs7O0VBNUZ1Q0MscUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjMgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgbWVtb2l6ZSBmcm9tICdsb2Rhc2gubWVtb2l6ZSc7XG5pbXBvcnQgdW5pcSBmcm9tICdsb2Rhc2gudW5pcSc7XG5cbmltcG9ydCBMYXllciwge2NvbG9yTWFrZXJ9IGZyb20gJy4uL2Jhc2UtbGF5ZXInO1xuaW1wb3J0IHtHZW9Kc29uTGF5ZXIgYXMgRGVja0dMR2VvSnNvbkxheWVyfSBmcm9tICdkZWNrLmdsJztcblxuaW1wb3J0IHtoZXhUb1JnYn0gZnJvbSAndXRpbHMvY29sb3ItdXRpbHMnO1xuaW1wb3J0IHtcbiAgZ2V0R2VvanNvbkRhdGFNYXBzLFxuICBnZXRHZW9qc29uQm91bmRzLFxuICBnZXRHZW9qc29uRmVhdHVyZVR5cGVzXG59IGZyb20gJy4vZ2VvanNvbi11dGlscyc7XG5pbXBvcnQgR2VvanNvbkxheWVySWNvbiBmcm9tICcuL2dlb2pzb24tbGF5ZXItaWNvbic7XG5pbXBvcnQge1xuICBHRU9KU09OX0ZJRUxEUyxcbiAgSElHSExJR0hfQ09MT1JfM0QsXG4gIENIQU5ORUxfU0NBTEVTXG59IGZyb20gJ2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcblxuZXhwb3J0IGNvbnN0IGdlb2pzb25WaXNDb25maWdzID0ge1xuICBvcGFjaXR5OiAnb3BhY2l0eScsXG4gIHRoaWNrbmVzczoge1xuICAgIHR5cGU6ICdudW1iZXInLFxuICAgIGRlZmF1bHRWYWx1ZTogMC41LFxuICAgIGxhYmVsOiAnU3Ryb2tlIFdpZHRoJyxcbiAgICBpc1JhbmdlZDogZmFsc2UsXG4gICAgcmFuZ2U6IFswLCAxMDBdLFxuICAgIHN0ZXA6IDAuMSxcbiAgICBncm91cDogJ3N0cm9rZScsXG4gICAgcHJvcGVydHk6ICd0aGlja25lc3MnXG4gIH0sXG4gIHN0cm9rZUNvbG9yOiAnc3Ryb2tlQ29sb3InLFxuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScsXG4gIHN0cm9rZUNvbG9yUmFuZ2U6ICdzdHJva2VDb2xvclJhbmdlJyxcbiAgcmFkaXVzOiAncmFkaXVzJyxcblxuICBzaXplUmFuZ2U6ICdzdHJva2VXaWR0aFJhbmdlJyxcbiAgcmFkaXVzUmFuZ2U6ICdyYWRpdXNSYW5nZScsXG4gIGhlaWdodFJhbmdlOiAnZWxldmF0aW9uUmFuZ2UnLFxuICBlbGV2YXRpb25TY2FsZTogJ2VsZXZhdGlvblNjYWxlJyxcbiAgc3Ryb2tlZDogJ3N0cm9rZWQnLFxuICBmaWxsZWQ6ICdmaWxsZWQnLFxuICBlbmFibGUzZDogJ2VuYWJsZTNkJyxcbiAgd2lyZWZyYW1lOiAnd2lyZWZyYW1lJ1xufTtcblxuZXhwb3J0IGNvbnN0IGdlb0pzb25SZXF1aXJlZENvbHVtbnMgPSBbJ2dlb2pzb24nXTtcbmV4cG9ydCBjb25zdCBmZWF0dXJlQWNjZXNzb3IgPSAoe2dlb2pzb259KSA9PiBkID0+IGRbZ2VvanNvbi5maWVsZElkeF07XG5leHBvcnQgY29uc3QgZmVhdHVyZVJlc29sdmVyID0gKHtnZW9qc29ufSkgPT4gZ2VvanNvbi5maWVsZElkeDtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2VvSnNvbkxheWVyIGV4dGVuZHMgTGF5ZXIge1xuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcblxuICAgIHRoaXMuZGF0YVRvRmVhdHVyZSA9IFtdO1xuICAgIHRoaXMucmVnaXN0ZXJWaXNDb25maWcoZ2VvanNvblZpc0NvbmZpZ3MpO1xuICAgIHRoaXMuZ2V0RmVhdHVyZSA9IG1lbW9pemUoZmVhdHVyZUFjY2Vzc29yLCBmZWF0dXJlUmVzb2x2ZXIpO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdnZW9qc29uJztcbiAgfVxuXG4gIGdldCBuYW1lKCkge1xuICAgIHJldHVybiAnUG9seWdvbic7XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCkge1xuICAgIHJldHVybiBHZW9qc29uTGF5ZXJJY29uO1xuICB9XG5cbiAgZ2V0IHJlcXVpcmVkTGF5ZXJDb2x1bW5zKCkge1xuICAgIHJldHVybiBnZW9Kc29uUmVxdWlyZWRDb2x1bW5zO1xuICB9XG5cbiAgZ2V0IHZpc3VhbENoYW5uZWxzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci52aXN1YWxDaGFubmVscyxcbiAgICAgIHN0cm9rZUNvbG9yOiB7XG4gICAgICAgIHByb3BlcnR5OiAnc3Ryb2tlQ29sb3InLFxuICAgICAgICBmaWVsZDogJ3N0cm9rZUNvbG9yRmllbGQnLFxuICAgICAgICBzY2FsZTogJ3N0cm9rZUNvbG9yU2NhbGUnLFxuICAgICAgICBkb21haW46ICdzdHJva2VDb2xvckRvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnc3Ryb2tlQ29sb3JSYW5nZScsXG4gICAgICAgIGtleTogJ3N0cm9rZUNvbG9yJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMuY29sb3IsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcuc3Ryb2tlZFxuICAgICAgfSxcbiAgICAgIHNpemU6IHtcbiAgICAgICAgLi4uc3VwZXIudmlzdWFsQ2hhbm5lbHMuc2l6ZSxcbiAgICAgICAgcHJvcGVydHk6ICdzdHJva2UnLFxuICAgICAgICBjb25kaXRpb246IGNvbmZpZyA9PiBjb25maWcudmlzQ29uZmlnLnN0cm9rZWRcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgcHJvcGVydHk6ICdoZWlnaHQnLFxuICAgICAgICBmaWVsZDogJ2hlaWdodEZpZWxkJyxcbiAgICAgICAgc2NhbGU6ICdoZWlnaHRTY2FsZScsXG4gICAgICAgIGRvbWFpbjogJ2hlaWdodERvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnaGVpZ2h0UmFuZ2UnLFxuICAgICAgICBrZXk6ICdoZWlnaHQnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiAnc2l6ZScsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcuZW5hYmxlM2RcbiAgICAgIH0sXG4gICAgICByYWRpdXM6IHtcbiAgICAgICAgcHJvcGVydHk6ICdyYWRpdXMnLFxuICAgICAgICBmaWVsZDogJ3JhZGl1c0ZpZWxkJyxcbiAgICAgICAgc2NhbGU6ICdyYWRpdXNTY2FsZScsXG4gICAgICAgIGRvbWFpbjogJ3JhZGl1c0RvbWFpbicsXG4gICAgICAgIHJhbmdlOiAncmFkaXVzUmFuZ2UnLFxuICAgICAgICBrZXk6ICdyYWRpdXMnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiAncmFkaXVzJ1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXRQb3NpdGlvbkFjY2Vzc29yKCkge1xuICAgIHJldHVybiB0aGlzLmdldEZlYXR1cmUodGhpcy5jb25maWcuY29sdW1ucyk7XG4gIH1cblxuICBzdGF0aWMgZmluZERlZmF1bHRMYXllclByb3BzKHtsYWJlbCwgZmllbGRzID0gW119KSB7XG4gICAgY29uc3QgZ2VvanNvbkNvbHVtbnMgPSBmaWVsZHNcbiAgICAgIC5maWx0ZXIoZiA9PiBmLnR5cGUgPT09ICdnZW9qc29uJylcbiAgICAgIC5tYXAoZiA9PiBmLm5hbWUpO1xuXG4gICAgY29uc3QgZGVmYXVsdENvbHVtbnMgPSB7XG4gICAgICBnZW9qc29uOiB1bmlxKFsuLi5HRU9KU09OX0ZJRUxEUy5nZW9qc29uLCAuLi5nZW9qc29uQ29sdW1uc10pXG4gICAgfTtcblxuICAgIGNvbnN0IGZvdW5kQ29sdW1ucyA9IHRoaXMuZmluZERlZmF1bHRDb2x1bW5GaWVsZChkZWZhdWx0Q29sdW1ucywgZmllbGRzKTtcbiAgICBpZiAoIWZvdW5kQ29sdW1ucyB8fCAhZm91bmRDb2x1bW5zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHtwcm9wczogW119O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwcm9wczogZm91bmRDb2x1bW5zLm1hcChjb2x1bW5zID0+ICh7XG4gICAgICAgIGxhYmVsOlxuICAgICAgICAgICh0eXBlb2YgbGFiZWwgPT09ICdzdHJpbmcnICYmIGxhYmVsLnJlcGxhY2UoL1xcLlteLy5dKyQvLCAnJykpIHx8XG4gICAgICAgICAgdGhpcy50eXBlLFxuICAgICAgICBjb2x1bW5zLFxuICAgICAgICBpc1Zpc2libGU6IHRydWVcbiAgICAgIH0pKVxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMgPSB7fSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci5nZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMpLFxuXG4gICAgICAvLyBhZGQgaGVpZ2h0IHZpc3VhbCBjaGFubmVsXG4gICAgICBoZWlnaHRGaWVsZDogbnVsbCxcbiAgICAgIGhlaWdodERvbWFpbjogWzAsIDFdLFxuICAgICAgaGVpZ2h0U2NhbGU6ICdsaW5lYXInLFxuXG4gICAgICAvLyBhZGQgcmFkaXVzIHZpc3VhbCBjaGFubmVsXG4gICAgICByYWRpdXNGaWVsZDogbnVsbCxcbiAgICAgIHJhZGl1c0RvbWFpbjogWzAsIDFdLFxuICAgICAgcmFkaXVzU2NhbGU6ICdsaW5lYXInLFxuXG4gICAgICAvLyBhZGQgc3Ryb2tlIGNvbG9yIHZpc3VhbCBjaGFubmVsXG4gICAgICBzdHJva2VDb2xvckZpZWxkOiBudWxsLFxuICAgICAgc3Ryb2tlQ29sb3JEb21haW46IFswLCAxXSxcbiAgICAgIHN0cm9rZUNvbG9yU2NhbGU6ICdxdWFudGlsZSdcbiAgICB9O1xuICB9XG5cbiAgZ2V0SG92ZXJEYXRhKG9iamVjdCkge1xuICAgIC8vIGluZGV4IG9mIGFsbERhdGEgaXMgc2F2ZWQgdG8gZmVhdHVyZS5wcm9wZXJ0aWVzXG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIC8vIFRPRE86IGZpeCBjb21wbGV4aXR5XG4gIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbiAgZm9ybWF0TGF5ZXJEYXRhKF8sIGFsbERhdGEsIGZpbHRlcmVkSW5kZXgsIG9sZExheWVyRGF0YSwgb3B0ID0ge30pIHtcbiAgICBjb25zdCB7XG4gICAgICBjb2xvclNjYWxlLFxuICAgICAgY29sb3JGaWVsZCxcbiAgICAgIGNvbG9yRG9tYWluLFxuICAgICAgc3Ryb2tlQ29sb3JGaWVsZCxcbiAgICAgIHN0cm9rZUNvbG9yU2NhbGUsXG4gICAgICBzdHJva2VDb2xvckRvbWFpbixcbiAgICAgIGNvbG9yLFxuICAgICAgc2l6ZVNjYWxlLFxuICAgICAgc2l6ZURvbWFpbixcbiAgICAgIHNpemVGaWVsZCxcbiAgICAgIGhlaWdodEZpZWxkLFxuICAgICAgaGVpZ2h0RG9tYWluLFxuICAgICAgaGVpZ2h0U2NhbGUsXG4gICAgICByYWRpdXNGaWVsZCxcbiAgICAgIHJhZGl1c0RvbWFpbixcbiAgICAgIHJhZGl1c1NjYWxlLFxuICAgICAgdmlzQ29uZmlnXG4gICAgfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgY29uc3Qge1xuICAgICAgZW5hYmxlM2QsXG4gICAgICBzdHJva2VkLFxuICAgICAgY29sb3JSYW5nZSxcbiAgICAgIGhlaWdodFJhbmdlLFxuICAgICAgc2l6ZVJhbmdlLFxuICAgICAgcmFkaXVzUmFuZ2UsXG4gICAgICBzdHJva2VDb2xvclJhbmdlLFxuICAgICAgc3Ryb2tlQ29sb3JcbiAgICB9ID0gdmlzQ29uZmlnO1xuXG4gICAgY29uc3QgZ2V0RmVhdHVyZSA9IHRoaXMuZ2V0UG9zaXRpb25BY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW4pO1xuXG4gICAgLy8gZ2VvanNvbiBmZWF0dXJlIGFyZSBvYmplY3QsIGlmIGRvZXNuJ3QgZXhpc3RzXG4gICAgLy8gY3JlYXRlIGl0IGFuZCBzYXZlIHRvIGxheWVyXG4gICAgaWYgKCFvbGRMYXllckRhdGEgfHwgb2xkTGF5ZXJEYXRhLmdldEZlYXR1cmUgIT09IGdldEZlYXR1cmUpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJNZXRhKGFsbERhdGEsIGdldEZlYXR1cmUpO1xuICAgIH1cblxuICAgIGxldCBnZW9qc29uRGF0YTtcblxuICAgIGlmIChcbiAgICAgIG9sZExheWVyRGF0YSAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmRhdGEgJiZcbiAgICAgIG9wdC5zYW1lRGF0YSAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmdldEZlYXR1cmUgPT09IGdldEZlYXR1cmVcbiAgICApIHtcbiAgICAgIC8vIG5vIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGFycmF5IG9mIGRhdGFcbiAgICAgIC8vIHVzZSB1cGRhdGVUcmlnZ2VycyB0byBzZWxlY3RpdmVseSByZS1jYWxjdWxhdGUgYXR0cmlidXRlc1xuICAgICAgZ2VvanNvbkRhdGEgPSBvbGRMYXllckRhdGEuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZmlsdGVyZWRJbmRleCBpcyBhIHJlZmVyZW5jZSBvZiBpbmRleCBpbiBhbGxEYXRhIHdoaWNoIGNhbiBtYXAgdG8gZmVhdHVyZVxuICAgICAgZ2VvanNvbkRhdGEgPSBmaWx0ZXJlZEluZGV4XG4gICAgICAgIC5tYXAoaSA9PiB0aGlzLmRhdGFUb0ZlYXR1cmVbaV0pXG4gICAgICAgIC5maWx0ZXIoZCA9PiBkKTtcbiAgICB9XG5cbiAgICAvLyBmaWxsIGNvbG9yXG4gICAgY29uc3QgY1NjYWxlID1cbiAgICAgIGNvbG9yRmllbGQgJiZcbiAgICAgIHRoaXMuZ2V0VmlzQ2hhbm5lbFNjYWxlKFxuICAgICAgICBjb2xvclNjYWxlLFxuICAgICAgICBjb2xvckRvbWFpbixcbiAgICAgICAgY29sb3JSYW5nZS5jb2xvcnMubWFwKGhleFRvUmdiKVxuICAgICAgKTtcblxuICAgIC8vIHN0cm9rZSBjb2xvclxuICAgIGNvbnN0IHNjU2NhbGUgPVxuICAgICAgc3Ryb2tlQ29sb3JGaWVsZCAmJlxuICAgICAgdGhpcy5nZXRWaXNDaGFubmVsU2NhbGUoXG4gICAgICAgIHN0cm9rZUNvbG9yU2NhbGUsXG4gICAgICAgIHN0cm9rZUNvbG9yRG9tYWluLFxuICAgICAgICBzdHJva2VDb2xvclJhbmdlLmNvbG9ycy5tYXAoaGV4VG9SZ2IpXG4gICAgICApO1xuICAgIC8vIGNhbGN1bGF0ZSBzdHJva2Ugc2NhbGUgLSBpZiBzdHJva2VkID0gdHJ1ZVxuICAgIGNvbnN0IHNTY2FsZSA9XG4gICAgICBzaXplRmllbGQgJiZcbiAgICAgIHN0cm9rZWQgJiZcbiAgICAgIHRoaXMuZ2V0VmlzQ2hhbm5lbFNjYWxlKHNpemVTY2FsZSwgc2l6ZURvbWFpbiwgc2l6ZVJhbmdlKTtcblxuICAgIC8vIGNhbGN1bGF0ZSBlbGV2YXRpb24gc2NhbGUgLSBpZiBleHRydWRlZCA9IHRydWVcbiAgICBjb25zdCBlU2NhbGUgPVxuICAgICAgaGVpZ2h0RmllbGQgJiZcbiAgICAgIGVuYWJsZTNkICYmXG4gICAgICB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShoZWlnaHRTY2FsZSwgaGVpZ2h0RG9tYWluLCBoZWlnaHRSYW5nZSk7XG4gICAgLy8gY29uc29sZS5sb2coJ2VTY2FsZSBpbnNpZGUgZm9ybWF0TGF5ZXJEYXRhJywgZVNjYWxlKTtcbiAgICAvLyBwb2ludCByYWRpdXNcbiAgICBjb25zdCByU2NhbGUgPVxuICAgICAgcmFkaXVzRmllbGQgJiZcbiAgICAgIHRoaXMuZ2V0VmlzQ2hhbm5lbFNjYWxlKHJhZGl1c1NjYWxlLCByYWRpdXNEb21haW4sIHJhZGl1c1JhbmdlKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBnZW9qc29uRGF0YSxcbiAgICAgIGdldEZlYXR1cmUsXG4gICAgICBnZXRGaWxsQ29sb3I6IGQgPT5cbiAgICAgICAgY1NjYWxlXG4gICAgICAgICAgPyB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoXG4gICAgICAgICAgICAgIGNTY2FsZSxcbiAgICAgICAgICAgICAgYWxsRGF0YVtkLnByb3BlcnRpZXMuaW5kZXhdLFxuICAgICAgICAgICAgICBjb2xvckZpZWxkXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBkLnByb3BlcnRpZXMuZmlsbENvbG9yIHx8IGNvbG9yLFxuICAgICAgZ2V0TGluZUNvbG9yOiBkID0+XG4gICAgICAgIHNjU2NhbGVcbiAgICAgICAgICA/IHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShcbiAgICAgICAgICAgICAgc2NTY2FsZSxcbiAgICAgICAgICAgICAgYWxsRGF0YVtkLnByb3BlcnRpZXMuaW5kZXhdLFxuICAgICAgICAgICAgICBzdHJva2VDb2xvckZpZWxkXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBkLnByb3BlcnRpZXMubGluZUNvbG9yIHx8IHN0cm9rZUNvbG9yIHx8IGNvbG9yLFxuICAgICAgZ2V0TGluZVdpZHRoOiBkID0+XG4gICAgICAgIHNTY2FsZVxuICAgICAgICAgID8gdGhpcy5nZXRFbmNvZGVkQ2hhbm5lbFZhbHVlKFxuICAgICAgICAgICAgICBzU2NhbGUsXG4gICAgICAgICAgICAgIGFsbERhdGFbZC5wcm9wZXJ0aWVzLmluZGV4XSxcbiAgICAgICAgICAgICAgc2l6ZUZpZWxkLFxuICAgICAgICAgICAgICAwXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBkLnByb3BlcnRpZXMubGluZVdpZHRoIHx8IDEsXG4gICAgICBnZXRFbGV2YXRpb246IGQgPT5cbiAgICAgICAgZVNjYWxlXG4gICAgICAgICAgPyB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoXG4gICAgICAgICAgICAgIGVTY2FsZSxcbiAgICAgICAgICAgICAgYWxsRGF0YVtkLnByb3BlcnRpZXMuaW5kZXhdLFxuICAgICAgICAgICAgICBoZWlnaHRGaWVsZCxcbiAgICAgICAgICAgICAgMFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogZC5wcm9wZXJ0aWVzLmVsZXZhdGlvbiB8fCA1MDAsXG4gICAgICBnZXRSYWRpdXM6IGQgPT5cbiAgICAgICAgclNjYWxlXG4gICAgICAgICAgPyB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoXG4gICAgICAgICAgICAgIHJTY2FsZSxcbiAgICAgICAgICAgICAgYWxsRGF0YVtkLnByb3BlcnRpZXMuaW5kZXhdLFxuICAgICAgICAgICAgICByYWRpdXNGaWVsZCxcbiAgICAgICAgICAgICAgMFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogZC5wcm9wZXJ0aWVzLnJhZGl1cyB8fCAxXG4gICAgfTtcbiAgfVxuICAvKiBlc2xpbnQtZW5hYmxlIGNvbXBsZXhpdHkgKi9cblxuICB1cGRhdGVMYXllck1ldGEoYWxsRGF0YSkge1xuICAgIGNvbnN0IGdldEZlYXR1cmUgPSB0aGlzLmdldFBvc2l0aW9uQWNjZXNzb3IoKTtcbiAgICB0aGlzLmRhdGFUb0ZlYXR1cmUgPSBnZXRHZW9qc29uRGF0YU1hcHMoYWxsRGF0YSwgZ2V0RmVhdHVyZSk7XG5cbiAgICAvLyBnZXQgYm91bmRzIGZyb20gZmVhdHVyZXNcbiAgICBjb25zdCBib3VuZHMgPSBnZXRHZW9qc29uQm91bmRzKHRoaXMuZGF0YVRvRmVhdHVyZSk7XG5cbiAgICAvLyBpZiBhbnkgb2YgdGhlIGZlYXR1cmUgaGFzIHByb3BlcnRpZXMucmFkaXVzIHNldCB0byBiZSB0cnVlXG4gICAgY29uc3QgZml4ZWRSYWRpdXMgPSBCb29sZWFuKFxuICAgICAgdGhpcy5kYXRhVG9GZWF0dXJlLmZpbmQoZCA9PiBkICYmIGQucHJvcGVydGllcyAmJiBkLnByb3BlcnRpZXMucmFkaXVzKVxuICAgICk7XG5cbiAgICAvLyBrZWVwIGEgcmVjb3JkIG9mIHdoYXQgdHlwZSBvZiBnZW9tZXRyeSB0aGUgY29sbGVjdGlvbiBoYXNcbiAgICBjb25zdCBmZWF0dXJlVHlwZXMgPSBnZXRHZW9qc29uRmVhdHVyZVR5cGVzKHRoaXMuZGF0YVRvRmVhdHVyZSk7XG5cbiAgICB0aGlzLnVwZGF0ZU1ldGEoe2JvdW5kcywgZml4ZWRSYWRpdXMsIGZlYXR1cmVUeXBlc30pO1xuICB9XG5cbiAgc2V0SW5pdGlhbExheWVyQ29uZmlnKGFsbERhdGEpIHtcbiAgICB0aGlzLnVwZGF0ZUxheWVyTWV0YShhbGxEYXRhKTtcblxuICAgIGNvbnN0IHtmZWF0dXJlVHlwZXN9ID0gdGhpcy5tZXRhO1xuIC