UNPKG

kepler.gl

Version:

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

390 lines (342 loc) 41.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.aggregateRequiredColumns = exports.getFilterDataFunc = exports.getValueAggrFunc = exports.pointPosResolver = exports.pointPosAccessor = 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 _baseLayer = _interopRequireDefault(require("./base-layer")); var _colorUtils = require("../utils/color-utils"); var _aggregateUtils = require("../utils/aggregate-utils"); 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 pointPosAccessor = function pointPosAccessor(_ref) { var lat = _ref.lat, lng = _ref.lng; return function (d) { return [d.data[lng.fieldIdx], d.data[lat.fieldIdx]]; }; }; exports.pointPosAccessor = pointPosAccessor; var pointPosResolver = function pointPosResolver(_ref2) { var lat = _ref2.lat, lng = _ref2.lng; return "".concat(lat.fieldIdx, "-").concat(lng.fieldIdx); }; exports.pointPosResolver = pointPosResolver; var getValueAggrFunc = function getValueAggrFunc(field, aggregation) { return function (points) { return field ? (0, _aggregateUtils.aggregate)(points.map(function (p) { return p.data[field.tableFieldIndex - 1]; }), aggregation) : points.length; }; }; exports.getValueAggrFunc = getValueAggrFunc; var getFilterDataFunc = function getFilterDataFunc(filterRange, getFilterValue) { return function (pt) { return getFilterValue(pt).every(function (val, i) { return val >= filterRange[i][0] && val <= filterRange[i][1]; }); }; }; exports.getFilterDataFunc = getFilterDataFunc; var getLayerColorRange = function getLayerColorRange(colorRange) { return colorRange.colors.map(_colorUtils.hexToRgb); }; var aggregateRequiredColumns = ['lat', 'lng']; exports.aggregateRequiredColumns = aggregateRequiredColumns; var AggregationLayer = /*#__PURE__*/ function (_Layer) { (0, _inherits2["default"])(AggregationLayer, _Layer); function AggregationLayer(props) { var _this; (0, _classCallCheck2["default"])(this, AggregationLayer); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(AggregationLayer).call(this, props)); _this.getPositionAccessor = function () { return pointPosAccessor(_this.config.columns); }; _this.getColorRange = (0, _lodash["default"])(getLayerColorRange); return _this; } (0, _createClass2["default"])(AggregationLayer, [{ key: "getVisualChannelDescription", /** * Get the description of a visualChannel config * @param key * @returns {{label: string, measure: (string|string)}} */ value: function getVisualChannelDescription(key) { // e.g. label: Color, measure: Average of ETA var _this$visualChannels$ = this.visualChannels[key], range = _this$visualChannels$.range, field = _this$visualChannels$.field, defaultMeasure = _this$visualChannels$.defaultMeasure, aggregation = _this$visualChannels$.aggregation; return { label: this.visConfigSettings[range].label, measure: this.config[field] ? "".concat(this.config.visConfig[aggregation], " of ").concat(this.config[field].name) : defaultMeasure }; } }, { key: "getHoverData", value: function getHoverData(object) { // return aggregated object return object; } /** * Aggregation layer handles visual channel aggregation inside deck.gl layer */ }, { key: "updateLayerVisualChannel", value: function updateLayerVisualChannel(_ref3, channel) { var data = _ref3.data, allData = _ref3.allData; this.validateVisualChannel(channel); } /** * Validate aggregation type on top of basic layer visual channel validation * @param channel */ }, { key: "validateVisualChannel", value: function validateVisualChannel(channel) { // field type decides aggregation type decides scale type this.validateFieldType(channel); this.validateAggregationType(channel); this.validateScale(channel); } /** * Validate aggregation type based on selected field */ }, { key: "validateAggregationType", value: function validateAggregationType(channel) { var visualChannel = this.visualChannels[channel]; var field = visualChannel.field, aggregation = visualChannel.aggregation; var aggregationOptions = this.getAggregationOptions(channel); if (!aggregation) { return; } if (!aggregationOptions.length) { // if field cannot be aggregated, set field to null this.updateLayerConfig((0, _defineProperty2["default"])({}, field, null)); } else if (!aggregationOptions.includes(this.config.visConfig[aggregation])) { // current aggregation type is not supported by this field // set aggregation to the first supported option this.updateLayerVisConfig((0, _defineProperty2["default"])({}, aggregation, aggregationOptions[0])); } } }, { key: "getAggregationOptions", value: function getAggregationOptions(channel) { var visualChannel = this.visualChannels[channel]; var field = visualChannel.field, channelScaleType = visualChannel.channelScaleType; return Object.keys(this.config[field] ? _defaultSettings.FIELD_OPTS[this.config[field].type].scale[channelScaleType] : _defaultSettings.DEFAULT_AGGREGATION[channelScaleType]); } /** * Get scale options based on current field and aggregation type * @param {string} channel * @returns {string[]} */ }, { key: "getScaleOptions", value: function getScaleOptions(channel) { var visualChannel = this.visualChannels[channel]; var field = visualChannel.field, aggregation = visualChannel.aggregation, channelScaleType = visualChannel.channelScaleType; var aggregationType = this.config.visConfig[aggregation]; return this.config[field] ? // scale options based on aggregation _defaultSettings.FIELD_OPTS[this.config[field].type].scale[channelScaleType][aggregationType] : // default scale options for point count _defaultSettings.DEFAULT_AGGREGATION[channelScaleType][aggregationType]; } /** * Aggregation layer handles visual channel aggregation inside deck.gl layer */ }, { key: "updateLayerDomain", value: function updateLayerDomain(datasets, newFilter) { return this; } }, { key: "updateLayerMeta", value: function updateLayerMeta(allData, getPosition) { // get bounds from points var bounds = this.getPointsBounds(allData, function (d) { return getPosition({ data: d }); }); this.updateMeta({ bounds: bounds }); } }, { key: "calculateDataAttribute", value: function calculateDataAttribute(_ref4, getPosition) { var allData = _ref4.allData, filteredIndex = _ref4.filteredIndex; var data = []; for (var i = 0; i < filteredIndex.length; i++) { var index = filteredIndex[i]; var pos = getPosition({ data: allData[index] }); // if doesn't have point lat or lng, do not add the point // deck.gl can't handle position = null if (pos.every(Number.isFinite)) { data.push({ index: index, data: allData[index] }); } } return data; } }, { key: "formatLayerData", value: function formatLayerData(datasets, oldLayerData) { var getPosition = this.getPositionAccessor(); // if ( var gpuFilter = datasets[this.config.dataId].gpuFilter; var getColorValue = getValueAggrFunc(this.config.colorField, this.config.visConfig.colorAggregation); var getElevationValue = getValueAggrFunc(this.config.sizeField, this.config.visConfig.sizeAggregation); var hasFilter = Object.values(gpuFilter.filterRange).some(function (arr) { return arr.some(function (v) { return v !== 0; }); }); var getFilterValue = gpuFilter.filterValueAccessor(); var filterData = hasFilter ? getFilterDataFunc(gpuFilter.filterRange, getFilterValue) : undefined; var _this$updateData = this.updateData(datasets, oldLayerData), data = _this$updateData.data; return _objectSpread({ data: data, getPosition: getPosition, _filterData: filterData }, getColorValue ? { getColorValue: getColorValue } : {}, {}, getElevationValue ? { getElevationValue: getElevationValue } : {}); } }, { key: "getDefaultDeckLayerProps", value: function getDefaultDeckLayerProps(opts) { var baseProp = (0, _get2["default"])((0, _getPrototypeOf2["default"])(AggregationLayer.prototype), "getDefaultDeckLayerProps", this).call(this, opts); return _objectSpread({}, baseProp, { highlightColor: _defaultSettings.HIGHLIGH_COLOR_3D, // gpu data filtering is not supported in aggregation layer extensions: [], autoHighlight: this.config.visConfig.enable3d }); } }, { key: "getDefaultAggregationLayerProp", value: function getDefaultAggregationLayerProp(opts) { var gpuFilter = opts.gpuFilter, mapState = opts.mapState, _opts$layerCallbacks = opts.layerCallbacks, layerCallbacks = _opts$layerCallbacks === void 0 ? {} : _opts$layerCallbacks; var visConfig = this.config.visConfig; var eleZoomFactor = this.getElevationZoomFactor(mapState); var updateTriggers = { getColorValue: { colorField: this.config.colorField, colorAggregation: this.config.visConfig.colorAggregation }, getElevationValue: { sizeField: this.config.sizeField, sizeAggregation: this.config.visConfig.sizeAggregation }, _filterData: _objectSpread({ filterRange: gpuFilter.filterRange }, gpuFilter.filterValueUpdateTriggers) }; return _objectSpread({}, this.getDefaultDeckLayerProps(opts), { coverage: visConfig.coverage, // color colorRange: this.getColorRange(visConfig.colorRange), colorScaleType: this.config.colorScale, upperPercentile: visConfig.percentile[1], lowerPercentile: visConfig.percentile[0], colorAggregation: visConfig.colorAggregation, // elevation extruded: visConfig.enable3d, elevationScale: visConfig.elevationScale * eleZoomFactor, elevationScaleType: this.config.sizeScale, elevationRange: visConfig.sizeRange, elevationLowerPercentile: visConfig.elevationPercentile[0], elevationUpperPercentile: visConfig.elevationPercentile[1], // updateTriggers updateTriggers: updateTriggers, // callbacks onSetColorDomain: layerCallbacks.onSetLayerDomain }); } }, { key: "isAggregated", get: function get() { return true; } }, { key: "requiredLayerColumns", get: function get() { return aggregateRequiredColumns; } }, { key: "columnPairs", get: function get() { return this.defaultPointColumnPairs; } }, { key: "noneLayerDataAffectingProps", get: function get() { return [].concat((0, _toConsumableArray2["default"])((0, _get2["default"])((0, _getPrototypeOf2["default"])(AggregationLayer.prototype), "noneLayerDataAffectingProps", this)), ['enable3d', 'colorRange', 'colorDomain', 'sizeRange', 'sizeScale', 'sizeDomain', 'percentile', 'coverage', 'elevationPercentile', 'elevationScale']); } }, { key: "visualChannels", get: function get() { return { color: { aggregation: 'colorAggregation', channelScaleType: _defaultSettings.CHANNEL_SCALES.colorAggr, defaultMeasure: 'property.pointCount', domain: 'colorDomain', field: 'colorField', key: 'color', property: 'color', range: 'colorRange', scale: 'colorScale' }, size: { aggregation: 'sizeAggregation', channelScaleType: _defaultSettings.CHANNEL_SCALES.sizeAggr, condition: function condition(config) { return config.visConfig.enable3d; }, defaultMeasure: 'property.pointCount', domain: 'sizeDomain', field: 'sizeField', key: 'size', property: 'height', range: 'sizeRange', scale: 'sizeScale' } }; } }]); return AggregationLayer; }(_baseLayer["default"]); exports["default"] = AggregationLayer; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYXllcnMvYWdncmVnYXRpb24tbGF5ZXIuanMiXSwibmFtZXMiOlsicG9pbnRQb3NBY2Nlc3NvciIsImxhdCIsImxuZyIsImQiLCJkYXRhIiwiZmllbGRJZHgiLCJwb2ludFBvc1Jlc29sdmVyIiwiZ2V0VmFsdWVBZ2dyRnVuYyIsImZpZWxkIiwiYWdncmVnYXRpb24iLCJwb2ludHMiLCJtYXAiLCJwIiwidGFibGVGaWVsZEluZGV4IiwibGVuZ3RoIiwiZ2V0RmlsdGVyRGF0YUZ1bmMiLCJmaWx0ZXJSYW5nZSIsImdldEZpbHRlclZhbHVlIiwicHQiLCJldmVyeSIsInZhbCIsImkiLCJnZXRMYXllckNvbG9yUmFuZ2UiLCJjb2xvclJhbmdlIiwiY29sb3JzIiwiaGV4VG9SZ2IiLCJhZ2dyZWdhdGVSZXF1aXJlZENvbHVtbnMiLCJBZ2dyZWdhdGlvbkxheWVyIiwicHJvcHMiLCJnZXRQb3NpdGlvbkFjY2Vzc29yIiwiY29uZmlnIiwiY29sdW1ucyIsImdldENvbG9yUmFuZ2UiLCJrZXkiLCJ2aXN1YWxDaGFubmVscyIsInJhbmdlIiwiZGVmYXVsdE1lYXN1cmUiLCJsYWJlbCIsInZpc0NvbmZpZ1NldHRpbmdzIiwibWVhc3VyZSIsInZpc0NvbmZpZyIsIm5hbWUiLCJvYmplY3QiLCJjaGFubmVsIiwiYWxsRGF0YSIsInZhbGlkYXRlVmlzdWFsQ2hhbm5lbCIsInZhbGlkYXRlRmllbGRUeXBlIiwidmFsaWRhdGVBZ2dyZWdhdGlvblR5cGUiLCJ2YWxpZGF0ZVNjYWxlIiwidmlzdWFsQ2hhbm5lbCIsImFnZ3JlZ2F0aW9uT3B0aW9ucyIsImdldEFnZ3JlZ2F0aW9uT3B0aW9ucyIsInVwZGF0ZUxheWVyQ29uZmlnIiwiaW5jbHVkZXMiLCJ1cGRhdGVMYXllclZpc0NvbmZpZyIsImNoYW5uZWxTY2FsZVR5cGUiLCJPYmplY3QiLCJrZXlzIiwiRklFTERfT1BUUyIsInR5cGUiLCJzY2FsZSIsIkRFRkFVTFRfQUdHUkVHQVRJT04iLCJhZ2dyZWdhdGlvblR5cGUiLCJkYXRhc2V0cyIsIm5ld0ZpbHRlciIsImdldFBvc2l0aW9uIiwiYm91bmRzIiwiZ2V0UG9pbnRzQm91bmRzIiwidXBkYXRlTWV0YSIsImZpbHRlcmVkSW5kZXgiLCJpbmRleCIsInBvcyIsIk51bWJlciIsImlzRmluaXRlIiwicHVzaCIsIm9sZExheWVyRGF0YSIsImdwdUZpbHRlciIsImRhdGFJZCIsImdldENvbG9yVmFsdWUiLCJjb2xvckZpZWxkIiwiY29sb3JBZ2dyZWdhdGlvbiIsImdldEVsZXZhdGlvblZhbHVlIiwic2l6ZUZpZWxkIiwic2l6ZUFnZ3JlZ2F0aW9uIiwiaGFzRmlsdGVyIiwidmFsdWVzIiwic29tZSIsImFyciIsInYiLCJmaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiZmlsdGVyRGF0YSIsInVuZGVmaW5lZCIsInVwZGF0ZURhdGEiLCJfZmlsdGVyRGF0YSIsIm9wdHMiLCJiYXNlUHJvcCIsImhpZ2hsaWdodENvbG9yIiwiSElHSExJR0hfQ09MT1JfM0QiLCJleHRlbnNpb25zIiwiYXV0b0hpZ2hsaWdodCIsImVuYWJsZTNkIiwibWFwU3RhdGUiLCJsYXllckNhbGxiYWNrcyIsImVsZVpvb21GYWN0b3IiLCJnZXRFbGV2YXRpb25ab29tRmFjdG9yIiwidXBkYXRlVHJpZ2dlcnMiLCJmaWx0ZXJWYWx1ZVVwZGF0ZVRyaWdnZXJzIiwiZ2V0RGVmYXVsdERlY2tMYXllclByb3BzIiwiY292ZXJhZ2UiLCJjb2xvclNjYWxlVHlwZSIsImNvbG9yU2NhbGUiLCJ1cHBlclBlcmNlbnRpbGUiLCJwZXJjZW50aWxlIiwibG93ZXJQZXJjZW50aWxlIiwiZXh0cnVkZWQiLCJlbGV2YXRpb25TY2FsZSIsImVsZXZhdGlvblNjYWxlVHlwZSIsInNpemVTY2FsZSIsImVsZXZhdGlvblJhbmdlIiwic2l6ZVJhbmdlIiwiZWxldmF0aW9uTG93ZXJQZXJjZW50aWxlIiwiZWxldmF0aW9uUGVyY2VudGlsZSIsImVsZXZhdGlvblVwcGVyUGVyY2VudGlsZSIsIm9uU2V0Q29sb3JEb21haW4iLCJvblNldExheWVyRG9tYWluIiwiZGVmYXVsdFBvaW50Q29sdW1uUGFpcnMiLCJjb2xvciIsIkNIQU5ORUxfU0NBTEVTIiwiY29sb3JBZ2dyIiwiZG9tYWluIiwicHJvcGVydHkiLCJzaXplIiwic2l6ZUFnZ3IiLCJjb25kaXRpb24iLCJMYXllciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7O0FBSU8sSUFBTUEsZ0JBQWdCLEdBQUcsU0FBbkJBLGdCQUFtQjtBQUFBLE1BQUVDLEdBQUYsUUFBRUEsR0FBRjtBQUFBLE1BQU9DLEdBQVAsUUFBT0EsR0FBUDtBQUFBLFNBQWdCLFVBQUFDLENBQUM7QUFBQSxXQUFJLENBQUNBLENBQUMsQ0FBQ0MsSUFBRixDQUFPRixHQUFHLENBQUNHLFFBQVgsQ0FBRCxFQUF1QkYsQ0FBQyxDQUFDQyxJQUFGLENBQU9ILEdBQUcsQ0FBQ0ksUUFBWCxDQUF2QixDQUFKO0FBQUEsR0FBakI7QUFBQSxDQUF6Qjs7OztBQUVBLElBQU1DLGdCQUFnQixHQUFHLFNBQW5CQSxnQkFBbUI7QUFBQSxNQUFFTCxHQUFGLFNBQUVBLEdBQUY7QUFBQSxNQUFPQyxHQUFQLFNBQU9BLEdBQVA7QUFBQSxtQkFBbUJELEdBQUcsQ0FBQ0ksUUFBdkIsY0FBbUNILEdBQUcsQ0FBQ0csUUFBdkM7QUFBQSxDQUF6Qjs7OztBQUVBLElBQU1FLGdCQUFnQixHQUFHLFNBQW5CQSxnQkFBbUIsQ0FBQ0MsS0FBRCxFQUFRQyxXQUFSLEVBQXdCO0FBQ3RELFNBQU8sVUFBQUMsTUFBTSxFQUFJO0FBQ2YsV0FBT0YsS0FBSyxHQUNSLCtCQUNFRSxNQUFNLENBQUNDLEdBQVAsQ0FBVyxVQUFBQyxDQUFDO0FBQUEsYUFBSUEsQ0FBQyxDQUFDUixJQUFGLENBQU9JLEtBQUssQ0FBQ0ssZUFBTixHQUF3QixDQUEvQixDQUFKO0FBQUEsS0FBWixDQURGLEVBRUVKLFdBRkYsQ0FEUSxHQUtSQyxNQUFNLENBQUNJLE1BTFg7QUFN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SnlCLFVBQUFBLEtBQUssRUFBRTtBQVZIO0FBWkQsT0FBUDtBQXlCRDs7O0VBOUQyQzBFLHFCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIwIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IG1lbW9pemUgZnJvbSAnbG9kYXNoLm1lbW9pemUnO1xuaW1wb3J0IExheWVyIGZyb20gJy4vYmFzZS1sYXllcic7XG5pbXBvcnQge2hleFRvUmdifSBmcm9tICd1dGlscy9jb2xvci11dGlscyc7XG5pbXBvcnQge2FnZ3JlZ2F0ZX0gZnJvbSAndXRpbHMvYWdncmVnYXRlLXV0aWxzJztcbmltcG9ydCB7SElHSExJR0hfQ09MT1JfM0R9IGZyb20gJ2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcblxuaW1wb3J0IHtDSEFOTkVMX1NDQUxFUywgRklFTERfT1BUUywgREVGQVVMVF9BR0dSRUdBVElPTn0gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuXG5leHBvcnQgY29uc3QgcG9pbnRQb3NBY2Nlc3NvciA9ICh7bGF0LCBsbmd9KSA9PiBkID0+IFtkLmRhdGFbbG5nLmZpZWxkSWR4XSwgZC5kYXRhW2xhdC5maWVsZElkeF1dO1xuXG5leHBvcnQgY29uc3QgcG9pbnRQb3NSZXNvbHZlciA9ICh7bGF0LCBsbmd9KSA9PiBgJHtsYXQuZmllbGRJZHh9LSR7bG5nLmZpZWxkSWR4fWA7XG5cbmV4cG9ydCBjb25zdCBnZXRWYWx1ZUFnZ3JGdW5jID0gKGZpZWxkLCBhZ2dyZWdhdGlvbikgPT4ge1xuICByZXR1cm4gcG9pbnRzID0+IHtcbiAgICByZXR1cm4gZmllbGRcbiAgICAgID8gYWdncmVnYXRlKFxuICAgICAgICAgIHBvaW50cy5tYXAocCA9PiBwLmRhdGFbZmllbGQudGFibGVGaWVsZEluZGV4IC0gMV0pLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uXG4gICAgICAgIClcbiAgICAgIDogcG9pbnRzLmxlbmd0aDtcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRGaWx0ZXJEYXRhRnVuYyA9IChmaWx0ZXJSYW5nZSwgZ2V0RmlsdGVyVmFsdWUpID0+IHB0ID0+XG4gIGdldEZpbHRlclZhbHVlKHB0KS5ldmVyeSgodmFsLCBpKSA9PiB2YWwgPj0gZmlsdGVyUmFuZ2VbaV1bMF0gJiYgdmFsIDw9IGZpbHRlclJhbmdlW2ldWzFdKTtcblxuY29uc3QgZ2V0TGF5ZXJDb2xvclJhbmdlID0gY29sb3JSYW5nZSA9PiBjb2xvclJhbmdlLmNvbG9ycy5tYXAoaGV4VG9SZ2IpO1xuXG5leHBvcnQgY29uc3QgYWdncmVnYXRlUmVxdWlyZWRDb2x1bW5zID0gWydsYXQnLCAnbG5nJ107XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFnZ3JlZ2F0aW9uTGF5ZXIgZXh0ZW5kcyBMYXllciB7XG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4gICAgdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yID0gKCkgPT4gcG9pbnRQb3NBY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW5zKTtcbiAgICB0aGlzLmdldENvbG9yUmFuZ2UgPSBtZW1vaXplKGdldExheWVyQ29sb3JSYW5nZSk7XG4gIH1cblxuICBnZXQgaXNBZ2dyZWdhdGVkKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZ2V0IHJlcXVpcmVkTGF5ZXJDb2x1bW5zKCkge1xuICAgIHJldHVybiBhZ2dyZWdhdGVSZXF1aXJlZENvbHVtbnM7XG4gIH1cblxuICBnZXQgY29sdW1uUGFpcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVmYXVsdFBvaW50Q29sdW1uUGFpcnM7XG4gIH1cblxuICBnZXQgbm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzKCkge1xuICAgIHJldHVybiBbXG4gICAgICAuLi5zdXBlci5ub25lTGF5ZXJEYXRhQWZmZWN0aW5nUHJvcHMsXG4gICAgICAnZW5hYmxlM2QnLFxuICAgICAgJ2NvbG9yUmFuZ2UnLFxuICAgICAgJ2NvbG9yRG9tYWluJyxcbiAgICAgICdzaXplUmFuZ2UnLFxuICAgICAgJ3NpemVTY2FsZScsXG4gICAgICAnc2l6ZURvbWFpbicsXG4gICAgICAncGVyY2VudGlsZScsXG4gICAgICAnY292ZXJhZ2UnLFxuICAgICAgJ2VsZXZhdGlvblBlcmNlbnRpbGUnLFxuICAgICAgJ2VsZXZhdGlvblNjYWxlJ1xuICAgIF07XG4gIH1cblxuICBnZXQgdmlzdWFsQ2hhbm5lbHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB7XG4gICAgICAgIGFnZ3JlZ2F0aW9uOiAnY29sb3JBZ2dyZWdhdGlvbicsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6IENIQU5ORUxfU0NBTEVTLmNvbG9yQWdncixcbiAgICAgICAgZGVmYXVsdE1lYXN1cmU6ICdwcm9wZXJ0eS5wb2ludENvdW50JyxcbiAgICAgICAgZG9tYWluOiAnY29sb3JEb21haW4nLFxuICAgICAgICBmaWVsZDogJ2NvbG9yRmllbGQnLFxuICAgICAgICBrZXk6ICdjb2xvcicsXG4gICAgICAgIHByb3BlcnR5OiAnY29sb3InLFxuICAgICAgICByYW5nZTogJ2NvbG9yUmFuZ2UnLFxuICAgICAgICBzY2FsZTogJ2NvbG9yU2NhbGUnXG4gICAgICB9LFxuICAgICAgc2l6ZToge1xuICAgICAgICBhZ2dyZWdhdGlvbjogJ3NpemVBZ2dyZWdhdGlvbicsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6IENIQU5ORUxfU0NBTEVTLnNpemVBZ2dyLFxuICAgICAgICBjb25kaXRpb246IGNvbmZpZyA9PiBjb25maWcudmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgICBkZWZhdWx0TWVhc3VyZTogJ3Byb3BlcnR5LnBvaW50Q291bnQnLFxuICAgICAgICBkb21haW46ICdzaXplRG9tYWluJyxcbiAgICAgICAgZmllbGQ6ICdzaXplRmllbGQnLFxuICAgICAgICBrZXk6ICdzaXplJyxcbiAgICAgICAgcHJvcGVydHk6ICdoZWlnaHQnLFxuICAgICAgICByYW5nZTogJ3NpemVSYW5nZScsXG4gICAgICAgIHNjYWxlOiAnc2l6ZVNjYWxlJ1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkZXNjcmlwdGlvbiBvZiBhIHZpc3VhbENoYW5uZWwgY29uZmlnXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHJldHVybnMge3tsYWJlbDogc3RyaW5nLCBtZWFzdXJlOiAoc3RyaW5nfHN0cmluZyl9fVxuICAgKi9cbiAgZ2V0VmlzdWFsQ2hhbm5lbERlc2NyaXB0aW9uKGtleSkge1xuICAgIC8vIGUuZy4gbGFiZWw6IENvbG9yLCBtZWFzdXJlOiBBdmVyYWdlIG9mIEVUQVxuICAgIGNvbnN0IHtyYW5nZSwgZmllbGQsIGRlZmF1bHRNZWFzdXJlLCBhZ2dyZWdhdGlvbn0gPSB0aGlzLnZpc3VhbENoYW5uZWxzW2tleV07XG4gICAgcmV0dXJuIHtcbiAgICAgIGxhYmVsOiB0aGlzLnZpc0NvbmZpZ1NldHRpbmdzW3JhbmdlXS5sYWJlbCxcbiAgICAgIG1lYXN1cmU6IHRoaXMuY29uZmlnW2ZpZWxkXVxuICAgICAgICA/IGAke3RoaXMuY29uZmlnLnZpc0NvbmZpZ1thZ2dyZWdhdGlvbl19IG9mICR7dGhpcy5jb25maWdbZmllbGRdLm5hbWV9YFxuICAgICAgICA6IGRlZmF1bHRNZWFzdXJlXG4gICAgfTtcbiAgfVxuXG4gIGdldEhvdmVyRGF0YShvYmplY3QpIHtcbiAgICAvLyByZXR1cm4gYWdncmVnYXRlZCBvYmplY3RcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFnZ3JlZ2F0aW9uIGxheWVyIGhhbmRsZXMgdmlzdWFsIGNoYW5uZWwgYWdncmVnYXRpb24gaW5zaWRlIGRlY2suZ2wgbGF5ZXJcbiAgICovXG4gIHVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbCh7ZGF0YSwgYWxsRGF0YX0sIGNoYW5uZWwpIHtcbiAgICB0aGlzLnZhbGlkYXRlVmlzdWFsQ2hhbm5lbChjaGFubmVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhZ2dyZWdhdGlvbiB0eXBlIG9uIHRvcCBvZiBiYXNpYyBsYXllciB2aXN1YWwgY2hhbm5lbCB2YWxpZGF0aW9uXG4gICAqIEBwYXJhbSBjaGFubmVsXG4gICAqL1xuICB2YWxpZGF0ZVZpc3VhbENoYW5uZWwoY2hhbm5lbCkge1xuICAgIC8vIGZpZWxkIHR5cGUgZGVjaWRlcyBhZ2dyZWdhdGlvbiB0eXBlIGRlY2lkZXMgc2NhbGUgdHlwZVxuICAgIHRoaXMudmFsaWRhdGVGaWVsZFR5cGUoY2hhbm5lbCk7XG4gICAgdGhpcy52YWxpZGF0ZUFnZ3JlZ2F0aW9uVHlwZShjaGFubmVsKTtcbiAgICB0aGlzLnZhbGlkYXRlU2NhbGUoY2hhbm5lbCk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYWdncmVnYXRpb24gdHlwZSBiYXNlZCBvbiBzZWxlY3RlZCBmaWVsZFxuICAgKi9cbiAgdmFsaWRhdGVBZ2dyZWdhdGlvblR5cGUoY2hhbm5lbCkge1xuICAgIGNvbnN0IHZpc3VhbENoYW5uZWwgPSB0aGlzLnZpc3VhbENoYW5uZWxzW2NoYW5uZWxdO1xuICAgIGNvbnN0IHtmaWVsZCwgYWdncmVnYXRpb259ID0gdmlzdWFsQ2hhbm5lbDtcbiAgICBjb25zdCBhZ2dyZWdhdGlvbk9wdGlvbnMgPSB0aGlzLmdldEFnZ3JlZ2F0aW9uT3B0aW9ucyhjaGFubmVsKTtcblxuICAgIGlmICghYWdncmVnYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWFnZ3JlZ2F0aW9uT3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgIC8vIGlmIGZpZWxkIGNhbm5vdCBiZSBhZ2dyZWdhdGVkLCBzZXQgZmllbGQgdG8gbnVsbFxuICAgICAgdGhpcy51cGRhdGVMYXllckNvbmZpZyh7W2ZpZWxkXTogbnVsbH0pO1xuICAgIH0gZWxzZSBpZiAoIWFnZ3JlZ2F0aW9uT3B0aW9ucy5pbmNsdWRlcyh0aGlzLmNvbmZpZy52aXNDb25maWdbYWdncmVnYXRpb25dKSkge1xuICAgICAgLy8gY3VycmVudCBhZ2dyZWdhdGlvbiB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBmaWVsZFxuICAgICAgLy8gc2V0IGFnZ3JlZ2F0aW9uIHRvIHRoZSBmaXJzdCBzdXBwb3J0ZWQgb3B0aW9uXG4gICAgICB0aGlzLnVwZGF0ZUxheWVyVmlzQ29uZmlnKHtbYWdncmVnYXRpb25dOiBhZ2dyZWdhdGlvbk9wdGlvbnNbMF19KTtcbiAgICB9XG4gIH1cblxuICBnZXRBZ2dyZWdhdGlvbk9wdGlvbnMoY2hhbm5lbCkge1xuICAgIGNvbnN0IHZpc3VhbENoYW5uZWwgPSB0aGlzLnZpc3VhbENoYW5uZWxzW2NoYW5uZWxdO1xuICAgIGNvbnN0IHtmaWVsZCwgY2hhbm5lbFNjYWxlVHlwZX0gPSB2aXN1YWxDaGFubmVsO1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKFxuICAgICAgdGhpcy5jb25maWdbZmllbGRdXG4gICAgICAgID8gRklFTERfT1BUU1t0aGlzLmNvbmZpZ1tmaWVsZF0udHlwZV0uc2NhbGVbY2hhbm5lbFNjYWxlVHlwZV1cbiAgICAgICAgOiBERUZBVUxUX0FHR1JFR0FUSU9OW2NoYW5uZWxTY2FsZVR5cGVdXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2NhbGUgb3B0aW9ucyBiYXNlZCBvbiBjdXJyZW50IGZpZWxkIGFuZCBhZ2dyZWdhdGlvbiB0eXBlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFubmVsXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX1cbiAgICovXG4gIGdldFNjYWxlT3B0aW9ucyhjaGFubmVsKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge2ZpZWxkLCBhZ2dyZWdhdGlvbiwgY2hhbm5lbFNjYWxlVHlwZX0gPSB2aXN1YWxDaGFubmVsO1xuICAgIGNvbnN0IGFnZ3JlZ2F0aW9uVHlwZSA9IHRoaXMuY29uZmlnLnZpc0NvbmZpZ1thZ2dyZWdhdGlvbl07XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnW2ZpZWxkXVxuICAgICAgPyAvLyBzY2FsZSBvcHRpb25zIGJhc2VkIG9uIGFnZ3JlZ2F0aW9uXG4gICAgICAgIEZJRUxEX09QVFNbdGhpcy5jb25maWdbZmllbGRdLnR5cGVdLnNjYWxlW2NoYW5uZWxTY2FsZVR5cGVdW2FnZ3JlZ2F0aW9uVHlwZV1cbiAgICAgIDogLy8gZGVmYXVsdCBzY2FsZSBvcHRpb25zIGZvciBwb2ludCBjb3VudFxuICAgICAgICBERUZBVUxUX0FHR1JFR0FUSU9OW2NoYW5uZWxTY2FsZVR5cGVdW2FnZ3JlZ2F0aW9uVHlwZV07XG4gIH1cblxuICAvKipcbiAgICogQWdncmVnYXRpb24gbGF5ZXIgaGFuZGxlcyB2aXN1YWwgY2hhbm5lbCBhZ2dyZWdhdGlvbiBpbnNpZGUgZGVjay5nbCBsYXllclxuICAgKi9cbiAgdXBkYXRlTGF5ZXJEb21haW4oZGF0YXNldHMsIG5ld0ZpbHRlcikge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJNZXRhKGFsbERhdGEsIGdldFBvc2l0aW9uKSB7XG4gICAgLy8gZ2V0IGJvdW5kcyBmcm9tIHBvaW50c1xuICAgIGNvbnN0IGJvdW5kcyA9IHRoaXMuZ2V0UG9pbnRzQm91bmRzKGFsbERhdGEsIGQgPT4gZ2V0UG9zaXRpb24oe2RhdGE6IGR9KSk7XG5cbiAgICB0aGlzLnVwZGF0ZU1ldGEoe2JvdW5kc30pO1xuICB9XG5cbiAgY2FsY3VsYXRlRGF0YUF0dHJpYnV0ZSh7YWxsRGF0YSwgZmlsdGVyZWRJbmRleH0sIGdldFBvc2l0aW9uKSB7XG4gICAgY29uc3QgZGF0YSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWx0ZXJlZEluZGV4Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGZpbHRlcmVkSW5kZXhbaV07XG4gICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbih7ZGF0YTogYWxsRGF0YVtpbmRleF19KTtcblxuICAgICAgLy8gaWYgZG9lc24ndCBoYXZlIHBvaW50IGxhdCBvciBsbmcsIGRvIG5vdCBhZGQgdGhlIHBvaW50XG4gICAgICAvLyBkZWNrLmdsIGNhbid0IGhhbmRsZSBwb3NpdGlvbiA9IG51bGxcbiAgICAgIGlmIChwb3MuZXZlcnkoTnVtYmVyLmlzRmluaXRlKSkge1xuICAgICAgICBkYXRhLnB1c2goe1xuICAgICAgICAgIGluZGV4LFxuICAgICAgICAgIGRhdGE6IGFsbERhdGFbaW5kZXhdXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZm9ybWF0TGF5ZXJEYXRhKGRhdGFzZXRzLCBvbGRMYXllckRhdGEpIHtcbiAgICBjb25zdCBnZXRQb3NpdGlvbiA9IHRoaXMuZ2V0UG9zaXRpb25BY2Nlc3NvcigpOyAvLyBpZiAoXG4gICAgY29uc3Qge2dwdUZpbHRlcn0gPSBkYXRhc2V0c1t0aGlzLmNvbmZpZy5kYXRhSWRdO1xuXG4gICAgY29uc3QgZ2V0Q29sb3JWYWx1ZSA9IGdldFZhbHVlQWdnckZ1bmMoXG4gICAgICB0aGlzLmNvbmZpZy5jb2xvckZpZWxkLFxuICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnLmNvbG9yQWdncmVnYXRpb25cbiAgICApO1xuXG4gICAgY29uc3QgZ2V0RWxldmF0aW9uVmFsdWUgPSBnZXRWYWx1ZUFnZ3JGdW5jKFxuICAgICAgdGhpcy5jb25maWcuc2l6ZUZpZWxkLFxuICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnLnNpemVBZ2dyZWdhdGlvblxuICAgICk7XG4gICAgY29uc3QgaGFzRmlsdGVyID0gT2JqZWN0LnZhbHVlcyhncHVGaWx0ZXIuZmlsdGVyUmFuZ2UpLnNvbWUoYXJyID0+IGFyci5zb21lKHYgPT4gdiAhPT0gMCkpO1xuICAgIGNvbnN0IGdldEZpbHRlclZhbHVlID0gZ3B1RmlsdGVyLmZpbHRlclZhbHVlQWNjZXNzb3IoKTtcbiAgICBjb25zdCBmaWx0ZXJEYXRhID0gaGFzRmlsdGVyXG4gICAgICA/IGdldEZpbHRlckRhdGFGdW5jKGdwdUZpbHRlci5maWx0ZXJSYW5nZSwgZ2V0RmlsdGVyVmFsdWUpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHtkYXRhfSA9IHRoaXMudXBkYXRlRGF0YShkYXRhc2V0cywgb2xkTGF5ZXJEYXRhKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgZ2V0UG9zaXRpb24sXG4gICAgICBfZmlsdGVyRGF0YTogZmlsdGVyRGF0YSxcbiAgICAgIC4uLihnZXRDb2xvclZhbHVlID8ge2dldENvbG9yVmFsdWV9IDoge30pLFxuICAgICAgLi4uKGdldEVsZXZhdGlvblZhbHVlID8ge2dldEVsZXZhdGlvblZhbHVlfSA6IHt9KVxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0RGVja0xheWVyUHJvcHMob3B0cykge1xuICAgIGNvbnN0IGJhc2VQcm9wID0gc3VwZXIuZ2V0RGVmYXVsdERlY2tMYXllclByb3BzKG9wdHMpO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5iYXNlUHJvcCxcbiAgICAgIGhpZ2hsaWdodENvbG9yOiBISUdITElHSF9DT0xPUl8zRCxcbiAgICAgIC8vIGdwdSBkYXRhIGZpbHRlcmluZyBpcyBub3Qgc3VwcG9ydGVkIGluIGFnZ3JlZ2F0aW9uIGxheWVyXG4gICAgICBleHRlbnNpb25zOiBbXSxcbiAgICAgIGF1dG9IaWdobGlnaHQ6IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5lbmFibGUzZFxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0QWdncmVnYXRpb25MYXllclByb3Aob3B0cykge1xuICAgIGNvbnN0IHtncHVGaWx0ZXIsIG1hcFN0YXRlLCBsYXllckNhbGxiYWNrcyA9IHt9fSA9IG9wdHM7XG4gICAgY29uc3Qge3Zpc0NvbmZpZ30gPSB0aGlzLmNvbmZpZztcbiAgICBjb25zdCBlbGVab29tRmFjdG9yID0gdGhpcy5nZXRFbGV2YXRpb25ab29tRmFjdG9yKG1hcFN0YXRlKTtcblxuICAgIGNvbnN0IHVwZGF0ZVRyaWdnZXJzID0ge1xuICAgICAgZ2V0Q29sb3JWYWx1ZToge1xuICAgICAgICBjb2xvckZpZWxkOiB0aGlzLmNvbmZpZy5jb2xvckZpZWxkLFxuICAgICAgICBjb2xvckFnZ3JlZ2F0aW9uOiB0aGlzLmNvbmZpZy52aXNDb25maWcuY29sb3JBZ2dyZWdhdGlvblxuICAgICAgfSxcbiAgICAgIGdldEVsZXZhdGlvblZhbHVlOiB7XG4gICAgICAgIHNpemVGaWVsZDogdGhpcy5jb25maWcuc2l6ZUZpZWxkLFxuICAgICAgICBzaXplQWdncmVnYXRpb246IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5zaXplQWdncmVnYXRpb25cbiAgICAgIH0sXG4gICAgICBfZmlsdGVyRGF0YToge1xuICAgICAgICBmaWx0ZXJSYW5nZTogZ3B1RmlsdGVyLmZpbHRlclJhbmdlLFxuICAgICAgICAuLi5ncHVGaWx0ZXIuZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2Vyc1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5nZXREZWZhdWx0RGVja0xheWVyUHJvcHMob3B0cyksXG4gICAgICBjb3ZlcmFnZTogdmlzQ29uZmlnLmNvdmVyYWdlLFxuXG4gICAgICAvLyBjb2xvclxuICAgICAgY29sb3JSYW5nZTogdGhpcy5nZXRDb2xvclJhbmdlKHZpc0NvbmZpZy5jb2xvclJhbmdlKSxcbiAgICAgIGNvbG9yU2NhbGVUeXBlOiB0aGlzLmNvbmZpZy5jb2xvclNjYWxlLFxuICAgICAgdXBwZXJQZXJjZW50aWxlOiB2aXNDb25maWcucGVyY2VudGlsZVsxXSxcbiAgICAgIGxvd2VyUGVyY2VudGlsZTogdmlzQ29uZmlnLnBlcmNlbnRpbGVbMF0sXG4gICAgICBjb2xvckFnZ3JlZ2F0aW9uOiB2aXNDb25maWcuY29sb3JBZ2dyZWdhdGlvbixcblxuICAgICAgLy8gZWxldmF0aW9uXG4gICAgICBleHRydWRlZDogdmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgZWxldmF0aW9uU2NhbGU6IHZpc0NvbmZpZy5lbGV2YXRpb25TY2FsZSAqIGVsZVpvb21GYWN0b3IsXG4gICAgICBlbGV2YXRpb25TY2FsZVR5cGU6IHRoaXMuY29uZmlnLnNpemVTY2FsZSxcbiAgICAgIGVsZXZhdGlvblJhbmdlOiB2aXNDb25maWcuc2l6ZVJhbmdlLFxuICAgICAgZWxldmF0aW9uTG93ZXJQZXJjZW50aWxlOiB2aXNDb25maWcuZWxldmF0aW9uUGVyY2VudGlsZVswXSxcbiAgICAgIGVsZXZhdGlvblVwcGVyUGVyY2VudGlsZTogdmlzQ29uZmlnLmVsZXZhdGlvblBlcmNlbnRpbGVbMV0sXG5cbiAgICAgIC8vIHVwZGF0ZVRyaWdnZXJzXG4gICAgICB1cGRhdGVUcmlnZ2VycyxcblxuICAgICAgLy8gY2FsbGJhY2tzXG4gICAgICBvblNldENvbG9yRG9tYWluOiBsYXllckNhbGxiYWNrcy5vblNldExheWVyRG9tYWluXG4gICAgfTtcbiAgfVxufVxuIl19