UNPKG

kepler.gl

Version:

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

393 lines (343 loc) 43.5 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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); 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 _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; } 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 pointPosAccessor = function pointPosAccessor(_ref) { var lat = _ref.lat, lng = _ref.lng; return function (dc) { return function (d) { return [dc.valueAt(d.index, lng.fieldIdx), dc.valueAt(d.index, 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 field.valueAccessor(p); }), 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); var _super = _createSuper(AggregationLayer); function AggregationLayer(props) { var _this; (0, _classCallCheck2["default"])(this, AggregationLayer); _this = _super.call(this, props); _this.getPositionAccessor = function (dataContainer) { return pointPosAccessor(_this.config.columns)(dataContainer); }; _this.getColorRange = (0, _lodash["default"])(getLayerColorRange); return _this; } (0, _createClass2["default"])(AggregationLayer, [{ 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', 'enableElevationZoomFactor']); } }, { 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' } }; } /** * Get the description of a visualChannel config * @param key * @returns {{label: string, measure: (string|string)}} */ }, { key: "getVisualChannelDescription", 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; var fieldConfig = this.config[field]; return { label: this.visConfigSettings[range].label, measure: fieldConfig ? "".concat(this.config.visConfig[aggregation], " of ").concat(fieldConfig.displayName || fieldConfig.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, dataContainer = _ref3.dataContainer; 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(dataContainer, getPosition) { // get bounds from points var bounds = this.getPointsBounds(dataContainer, getPosition); this.updateMeta({ bounds: bounds }); } }, { key: "calculateDataAttribute", value: function calculateDataAttribute(_ref4, getPosition) { var dataContainer = _ref4.dataContainer, filteredIndex = _ref4.filteredIndex; var data = []; for (var i = 0; i < filteredIndex.length; i++) { var index = filteredIndex[i]; var pos = getPosition({ index: 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 }); } } return data; } }, { key: "formatLayerData", value: function formatLayerData(datasets, oldLayerData) { var _datasets$this$config = datasets[this.config.dataId], gpuFilter = _datasets$this$config.gpuFilter, dataContainer = _datasets$this$config.dataContainer; var getPosition = this.getPositionAccessor(dataContainer); 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(dataContainer)(); var filterData = hasFilter ? getFilterDataFunc(gpuFilter.filterRange, getFilterValue) : undefined; var _this$updateData = this.updateData(datasets, oldLayerData), data = _this$updateData.data; return _objectSpread(_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(_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(_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 }); } }]); return AggregationLayer; }(_baseLayer["default"]); exports["default"] = AggregationLayer; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYXllcnMvYWdncmVnYXRpb24tbGF5ZXIuanMiXSwibmFtZXMiOlsicG9pbnRQb3NBY2Nlc3NvciIsImxhdCIsImxuZyIsImRjIiwiZCIsInZhbHVlQXQiLCJpbmRleCIsImZpZWxkSWR4IiwicG9pbnRQb3NSZXNvbHZlciIsImdldFZhbHVlQWdnckZ1bmMiLCJmaWVsZCIsImFnZ3JlZ2F0aW9uIiwicG9pbnRzIiwibWFwIiwicCIsInZhbHVlQWNjZXNzb3IiLCJsZW5ndGgiLCJnZXRGaWx0ZXJEYXRhRnVuYyIsImZpbHRlclJhbmdlIiwiZ2V0RmlsdGVyVmFsdWUiLCJwdCIsImV2ZXJ5IiwidmFsIiwiaSIsImdldExheWVyQ29sb3JSYW5nZSIsImNvbG9yUmFuZ2UiLCJjb2xvcnMiLCJoZXhUb1JnYiIsImFnZ3JlZ2F0ZVJlcXVpcmVkQ29sdW1ucyIsIkFnZ3JlZ2F0aW9uTGF5ZXIiLCJwcm9wcyIsImdldFBvc2l0aW9uQWNjZXNzb3IiLCJkYXRhQ29udGFpbmVyIiwiY29uZmlnIiwiY29sdW1ucyIsImdldENvbG9yUmFuZ2UiLCJkZWZhdWx0UG9pbnRDb2x1bW5QYWlycyIsImNvbG9yIiwiY2hhbm5lbFNjYWxlVHlwZSIsIkNIQU5ORUxfU0NBTEVTIiwiY29sb3JBZ2dyIiwiZGVmYXVsdE1lYXN1cmUiLCJkb21haW4iLCJrZXkiLCJwcm9wZXJ0eSIsInJhbmdlIiwic2NhbGUiLCJzaXplIiwic2l6ZUFnZ3IiLCJjb25kaXRpb24iLCJ2aXNDb25maWciLCJlbmFibGUzZCIsInZpc3VhbENoYW5uZWxzIiwiZmllbGRDb25maWciLCJsYWJlbCIsInZpc0NvbmZpZ1NldHRpbmdzIiwibWVhc3VyZSIsImRpc3BsYXlOYW1lIiwibmFtZSIsIm9iamVjdCIsImNoYW5uZWwiLCJkYXRhIiwidmFsaWRhdGVWaXN1YWxDaGFubmVsIiwidmFsaWRhdGVGaWVsZFR5cGUiLCJ2YWxpZGF0ZUFnZ3JlZ2F0aW9uVHlwZSIsInZhbGlkYXRlU2NhbGUiLCJ2aXN1YWxDaGFubmVsIiwiYWdncmVnYXRpb25PcHRpb25zIiwiZ2V0QWdncmVnYXRpb25PcHRpb25zIiwidXBkYXRlTGF5ZXJDb25maWciLCJpbmNsdWRlcyIsInVwZGF0ZUxheWVyVmlzQ29uZmlnIiwiT2JqZWN0Iiwia2V5cyIsIkZJRUxEX09QVFMiLCJ0eXBlIiwiREVGQVVMVF9BR0dSRUdBVElPTiIsImFnZ3JlZ2F0aW9uVHlwZSIsImRhdGFzZXRzIiwibmV3RmlsdGVyIiwiZ2V0UG9zaXRpb24iLCJib3VuZHMiLCJnZXRQb2ludHNCb3VuZHMiLCJ1cGRhdGVNZXRhIiwiZmlsdGVyZWRJbmRleCIsInBvcyIsIk51bWJlciIsImlzRmluaXRlIiwicHVzaCIsIm9sZExheWVyRGF0YSIsImRhdGFJZCIsImdwdUZpbHRlciIsImdldENvbG9yVmFsdWUiLCJjb2xvckZpZWxkIiwiY29sb3JBZ2dyZWdhdGlvbiIsImdldEVsZXZhdGlvblZhbHVlIiwic2l6ZUZpZWxkIiwic2l6ZUFnZ3JlZ2F0aW9uIiwiaGFzRmlsdGVyIiwidmFsdWVzIiwic29tZSIsImFyciIsInYiLCJmaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiZmlsdGVyRGF0YSIsInVuZGVmaW5lZCIsInVwZGF0ZURhdGEiLCJfZmlsdGVyRGF0YSIsIm9wdHMiLCJiYXNlUHJvcCIsImhpZ2hsaWdodENvbG9yIiwiSElHSExJR0hfQ09MT1JfM0QiLCJleHRlbnNpb25zIiwiYXV0b0hpZ2hsaWdodCIsIm1hcFN0YXRlIiwibGF5ZXJDYWxsYmFja3MiLCJlbGVab29tRmFjdG9yIiwiZ2V0RWxldmF0aW9uWm9vbUZhY3RvciIsInVwZGF0ZVRyaWdnZXJzIiwiZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2VycyIsImdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyIsImNvdmVyYWdlIiwiY29sb3JTY2FsZVR5cGUiLCJjb2xvclNjYWxlIiwidXBwZXJQZXJjZW50aWxlIiwicGVyY2VudGlsZSIsImxvd2VyUGVyY2VudGlsZSIsImV4dHJ1ZGVkIiwiZWxldmF0aW9uU2NhbGUiLCJlbGV2YXRpb25TY2FsZVR5cGUiLCJzaXplU2NhbGUiLCJlbGV2YXRpb25SYW5nZSIsInNpemVSYW5nZSIsImVsZXZhdGlvbkxvd2VyUGVyY2VudGlsZSIsImVsZXZhdGlvblBlcmNlbnRpbGUiLCJlbGV2YXRpb25VcHBlclBlcmNlbnRpbGUiLCJvblNldENvbG9yRG9tYWluIiwib25TZXRMYXllckRvbWFpbiIsIkxheWVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7O0FBT08sSUFBTUEsZ0JBQWdCLEdBQUcsU0FBbkJBLGdCQUFtQjtBQUFBLE1BQUVDLEdBQUYsUUFBRUEsR0FBRjtBQUFBLE1BQU9DLEdBQVAsUUFBT0EsR0FBUDtBQUFBLFNBQWdCLFVBQUFDLEVBQUU7QUFBQSxXQUFJLFVBQUFDLENBQUM7QUFBQSxhQUFJLENBQ3pERCxFQUFFLENBQUNFLE9BQUgsQ0FBV0QsQ0FBQyxDQUFDRSxLQUFiLEVBQW9CSixHQUFHLENBQUNLLFFBQXhCLENBRHlELEVBRXpESixFQUFFLENBQUNFLE9BQUgsQ0FBV0QsQ0FBQyxDQUFDRSxLQUFiLEVBQW9CTCxHQUFHLENBQUNNLFFBQXhCLENBRnlELENBQUo7QUFBQSxLQUFMO0FBQUEsR0FBbEI7QUFBQSxDQUF6Qjs7OztBQUtBLElBQU1DLGdCQUFnQixHQUFHLFNBQW5CQSxnQkFBbUI7QUFBQSxNQUFFUCxHQUFGLFNBQUVBLEdBQUY7QUFBQSxNQUFPQyxHQUFQLFNBQU9BLEdBQVA7QUFBQSxtQkFBbUJELEdBQUcsQ0FBQ00sUUFBdkIsY0FBbUNMLEdBQUcsQ0FBQ0ssUUFBdkM7QUFBQSxDQUF6Qjs7OztBQUVBLElBQU1FLGdCQUFnQixHQUFHLFNBQW5CQSxnQkFBbUIsQ0FBQ0MsS0FBRCxFQUFRQyxXQUFSLEVBQXdCO0FBQ3RELFNBQU8sVUFBQUMsTUFBTSxFQUFJO0FBQ2YsV0FBT0YsS0FBSyxHQUNSLCtCQUNFRSxNQUFNLENBQUNDLEdBQVAsQ0FBVyxVQUFBQyxDQUFDLEVBQUk7QUFDZCxhQUFPSixLQUFLLENBQUNLLGFBQU4sQ0FBb0JELENBQXBCLENBQVA7QUFDRCxLQUZELENBREYsRUFJRUgsV0FKRixDQURRLEdBT1JDLE1BQU0sQ0FBQ0ksTUFQWDtBQVFELEdBVEQ7QUFVRCxDQVhNOzs7O0FBYUEsSUFBTUMsaUJBQWlCLEdBQUcsU0FBcEJBLGlCQUFvQixDQUFDQyxXQUFELEVBQWNDLGNBQWQ7QUFBQSxTQUFpQyxVQUFBQyxFQUFFO0FBQUEsV0FDbEVELGNBQWMsQ0FBQ0MsRUFBRCxDQUFkLENBQW1CQyxLQUFuQixDQUF5QixVQUFDQyxHQUFELEVBQU1DLENBQU47QUFBQSxhQUFZRCxHQUFHLElBQUlKLFdBQVcsQ0FBQ0ssQ0FBRCxDQUFYLENBQWUsQ0FBZixDQUFQLElBQTRCRCxHQUFHLElBQUlKLFdBQVcsQ0FBQ0ssQ0FBRCxDQUFYLENBQWUsQ0FBZixDQUEvQztBQUFBLEtBQXpCLENBRGtFO0FBQUEsR0FBbkM7QUFBQSxDQUExQjs7OztBQUdQLElBQU1DLGtCQUFrQixHQUFHLFNBQXJCQSxrQkFBcUIsQ0FBQUMsVUFBVTtBQUFBLFNBQUlBLFVBQVUsQ0FBQ0MsTUFBWCxDQUFrQmIsR0FBbEIsQ0FBc0JjLG9CQUF0QixDQUFKO0FBQUEsQ0FBckM7O0FBRU8sSUFBTUMsd0JBQXdCLEdBQUcsQ0FBQyxLQUFELEVBQVEsS0FBUixDQUFqQzs7O0lBRWNDLGdCOzs7OztBQUNuQiw0QkFBWUMsS0FBWixFQUFtQjtBQUFBOztBQUFBO0FBQ2pCLDhCQUFNQSxLQUFOOztBQUVBLFVBQUtDLG1CQUFMLEdBQTJCLFVBQUFDLGFBQWE7QUFBQSxhQUN0Q2hDLGdCQUFnQixDQUFDLE1BQUtpQyxNQUFMLENBQVlDLE9BQWIsQ0FBaEIsQ0FBc0NGLGFBQXRDLENBRHNDO0FBQUEsS0FBeEM7O0FBRUEsVUFBS0csYUFBTCxHQUFxQix3QkFBUVgsa0JBQVIsQ0FBckI7QUFMaUI7QUFNbEI7Ozs7U0FFRCxlQUFtQjtBQUNqQixhQUFPLElBQVA7QUFDRDs7O1NBRUQsZUFBMkI7QUFDekIsYUFBT0ksd0JBQVA7QUFDRDs7O1NBRUQsZUFBa0I7QUFDaEIsYUFBTyxLQUFLUSx1QkFBWjtBQUNEOzs7U0FFRCxlQUFrQztBQUNoQyx1TEFFRSxVQUZGLEVBR0UsWUFIRixFQUlFLGFBSkYsRUFLRSxXQUxGLEVBTUUsV0FORixFQU9FLFlBUEYsRUFRRSxZQVJGLEVBU0UsVUFURixFQVVFLHFCQVZGLEVBV0UsZ0JBWEYsRUFZRSwyQkFaRjtBQWNEOzs7U0FFRCxlQUFxQjtBQUNuQixhQUFPO0FBQ0xDLFFBQUFBLEtBQUssRUFBRTtBQUNMMUIsVUFBQUEsV0FBVyxFQUFFLGtCQURSO0FBRUwyQixVQUFBQSxnQkFBZ0IsRUFBRUMsZ0NBQWVDLFNBRjVCO0FBR0xDLFVBQUFBLGNBQWMsRUFBRSxxQkFIWDtBQUlMQyxVQUFBQSxNQUFNLEVBQUUsYUFKSDtBQUtMaEMsVUFBQUEsS0FBSyxFQUFFLFlBTEY7QUFNTGlDLFVBQUFBLEdBQUcsRUFBRSxPQU5BO0FBT0xDLFVBQUFBLFFBQVEsRUFBRSxPQVBMO0FBUUxDLFVBQUFBLEtBQUssRUFBRSxZQVJGO0FBU0xDLFVBQUFBLEtBQUssRUFBRTtBQVRGLFNBREY7QUFZTEMsUUFBQUEsSUFBSSxFQUFFO0FBQ0pwQyxVQUFBQSxXQUFXLEVBQUUsaUJBRFQ7QUFFSjJCLFVBQUFBLGdCQUFnQixFQUFFQyxnQ0FBZVMsUUFGN0I7QUFHSkMsVUFBQUEsU0FBUyxFQUFFLG1CQUFBaEIsTUFBTTtBQUFBLG1CQUFJQSxNQUFNLENBQUNpQixTQUFQLENBQWlCQyxRQUFyQjtBQUFBLFdBSGI7QUFJSlYsVUFBQUEsY0FBYyxFQUFFLHFCQUpaO0FBS0pDLFVBQUFBLE1BQU0sRUFBRSxZQUxKO0FBTUpoQyxVQUFBQSxLQUFLLEVBQUUsV0FOSDtBQU9KaUMsVUFBQUEsR0FBRyxFQUFFLE1BUEQ7QUFRSkMsVUFBQUEsUUFBUSxFQUFFLFFBUk47QUFTSkMsVUFBQUEsS0FBSyxFQUFFLFdBVEg7QUFVSkMsVUFBQUEsS0FBSyxFQUFFO0FBVkg7QUFaRCxPQUFQO0FBeUJEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7OztXQUNFLHFDQUE0QkgsR0FBNUIsRUFBaUM7QUFDL0I7QUFEK0Isa0NBRXFCLEtBQUtTLGNBQUwsQ0FBb0JULEdBQXBCLENBRnJCO0FBQUEsVUFFeEJFLEtBRndCLHlCQUV4QkEsS0FGd0I7QUFBQSxVQUVqQm5DLEtBRmlCLHlCQUVqQkEsS0FGaUI7QUFBQSxVQUVWK0IsY0FGVSx5QkFFVkEsY0FGVTtBQUFBLFVBRU05QixXQUZOLHlCQUVNQSxXQUZOO0FBRy9CLFVBQU0wQyxXQUFXLEdBQUcsS0FBS3BCLE1BQUwsQ0FBWXZCLEtBQVosQ0FBcEI7QUFDQSxhQUFPO0FBQ0w0QyxRQUFBQSxLQUFLLEVBQUUsS0FBS0MsaUJBQUwsQ0FBdUJWLEtBQXZCLEVBQThCUyxLQURoQztBQUVMRSxRQUFBQSxPQUFPLEVBQUVILFdBQVcsYUFDYixLQUFLcEIsTUFBTCxDQUFZaUIsU0FBWixDQUFzQnZDLFdBQXRCLENBRGEsaUJBQzRCMEMsV0FBVyxDQUFDSSxXQUFaLElBQTJCSixXQUFXLENBQUNLLElBRG5FLElBRWhCakI7QUFKQyxPQUFQO0FBTUQ7OztXQUVELHNCQUFha0IsTUFBYixFQUFxQjtBQUNuQjtBQUNBLGFBQU9BLE1BQVA7QUFDRDtBQUVEO0FBQ0Y7QUFDQTs7OztXQUNFLHlDQUFnREMsT0FBaEQsRUFBeUQ7QUFBQSxVQUEvQkMsSUFBK0IsU0FBL0JBLElBQStCO0FBQUEsVUFBekI3QixhQUF5QixTQUF6QkEsYUFBeUI7QUFDdkQsV0FBSzhCLHFCQUFMLENBQTJCRixPQUEzQjtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7Ozs7V0FDRSwrQkFBc0JBLE9BQXRCLEVBQStCO0FBQzdCO0FBQ0EsV0FBS0csaUJBQUwsQ0FBdUJILE9BQXZCO0FBQ0EsV0FBS0ksdUJBQUwsQ0FBNkJKLE9BQTdCO0FBQ0EsV0FBS0ssYUFBTCxDQUFtQkwsT0FBbkI7QUFDRDtBQUVEO0FBQ0Y7QUFDQTs7OztXQUNFLGlDQUF3QkEsT0FBeEIsRUFBaUM7QUFDL0IsVUFBTU0sYUFBYSxHQUFHLEtBQUtkLGNBQUwsQ0FBb0JRLE9BQXBCLENBQXRCO0FBRCtCLFVBRXhCbEQsS0FGd0IsR0FFRndELGFBRkUsQ0FFeEJ4RCxLQUZ3QjtBQUFBLFVBRWpCQyxXQUZpQixHQUVGdUQsYUFGRSxDQUVqQnZELFdBRmlCO0FBRy9CLFVBQU13RCxrQkFBa0IsR0FBRyxLQUFLQyxxQkFBTCxDQUEyQlIsT0FBM0IsQ0FBM0I7O0FBRUEsVUFBSSxDQUFDakQsV0FBTCxFQUFrQjtBQUNoQjtBQUNEOztBQUVELFVBQUksQ0FBQ3dELGtCQUFrQixDQUFDbkQsTUFBeEIsRUFBZ0M7QUFDOUI7QUFDQSxhQUFLcUQsaUJBQUwsc0NBQXlCM0QsS0FBekIsRUFBaUMsSUFBakM7QUFDRCxPQUhELE1BR08sSUFBSSxDQUFDeUQsa0JBQWtCLENBQUNHLFFBQW5CLENBQTRCLEtBQUtyQyxNQUFMLENBQVlpQixTQUFaLENBQXNCdkMsV0FBdEIsQ0FBNUIsQ0FBTCxFQUFzRTtBQUMzRTtBQUNBO0FBQ0EsYUFBSzRELG9CQUFMLHNDQUE0QjVELFdBQTVCLEVBQTBDd0Qsa0JBQWtCLENBQUMsQ0FBRCxDQUE1RDtBQUNEO0FBQ0Y7OztXQUVELCtCQUFzQlAsT0FBdEIsRUFBK0I7QUFDN0IsVUFBTU0sYUFBYSxHQUFHLEtBQUtkLGNBQUwsQ0FBb0JRLE9BQXBCLENBQXRCO0FBRDZCLFVBRXRCbEQsS0FGc0IsR0FFS3dELGFBRkwsQ0FFdEJ4RCxLQUZzQjtBQUFBLFVBRWY0QixnQkFGZSxHQUVLNEIsYUFGTCxDQUVmNUIsZ0JBRmU7QUFJN0IsYUFBT2tDLE1BQU0sQ0FBQ0MsSUFBUCxDQUNMLEtBQUt4QyxNQUFMLENBQVl2QixLQUFaLElBQ0lnRSw0QkFBVyxLQUFLekMsTUFBTCxDQUFZdkIsS0FBWixFQUFtQmlFLElBQTlCLEVBQW9DN0IsS0FBcEMsQ0FBMENSLGdCQUExQyxDQURKLEdBRUlzQyxxQ0FBb0J0QyxnQkFBcEIsQ0FIQyxDQUFQO0FBS0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBOzs7O1dBQ0UseUJBQWdCc0IsT0FBaEIsRUFBeUI7QUFDdkIsVUFBTU0sYUFBYSxHQUFHLEtBQUtkLGNBQUwsQ0FBb0JRLE9BQXBCLENBQXRCO0FBRHVCLFVBRWhCbEQsS0FGZ0IsR0FFd0J3RCxhQUZ4QixDQUVoQnhELEtBRmdCO0FBQUEsVUFFVEMsV0FGUyxHQUV3QnVELGFBRnhCLENBRVR2RCxXQUZTO0FBQUEsVUFFSTJCLGdCQUZKLEdBRXdCNEIsYUFGeEIsQ0FFSTVCLGdCQUZKO0FBR3ZCLFVBQU11QyxlQUFlLEdBQUcsS0FBSzVDLE1BQUwsQ0FBWWlCLFNBQVosQ0FBc0J2QyxXQUF0QixDQUF4QjtBQUNBLGFBQU8sS0FBS3NCLE1BQUwsQ0FBWXZCLEtBQVosSUFDSDtBQUNBZ0Usa0NBQVcsS0FBS3pDLE1BQUwsQ0FBWXZCLEtBQVosRUFBbUJpRSxJQUE5QixFQUFvQzdCLEtBQXBDLENBQTBDUixnQkFBMUMsRUFBNER1QyxlQUE1RCxDQUZHLEdBR0g7QUFDQUQsMkNBQW9CdEMsZ0JBQXBCLEVBQXNDdUMsZUFBdEMsQ0FKSjtBQUtEO0FBRUQ7QUFDRjtBQUNBOzs7O1dBQ0UsMkJBQWtCQyxRQUFsQixFQUE0QkMsU0FBNUIsRUFBdUM7QUFDckMsYUFBTyxJQUFQO0FBQ0Q7OztXQUVELHlCQUFnQi9DLGFBQWhCLEVBQStCZ0QsV0FBL0IsRUFBNEM7QUFDMUM7QUFDQSxVQUFNQyxNQUFNLEdBQUcsS0FBS0MsZUFBTCxDQUFxQmxELGFBQXJCLEVBQW9DZ0QsV0FBcEMsQ0FBZjtBQUVBLFdBQUtHLFVBQUwsQ0FBZ0I7QUFBQ0YsUUFBQUEsTUFBTSxFQUFOQTtBQUFELE9BQWhCO0FBQ0Q7OztXQUVELHVDQUF1REQsV0FBdkQsRUFBb0U7QUFBQSxVQUE1Q2hELGFBQTRDLFNBQTVDQSxhQUE0QztBQUFBLFVBQTdCb0QsYUFBNkIsU0FBN0JBLGFBQTZCO0FBQ2xFLFVBQU12QixJQUFJLEdBQUcsRUFBYjs7QUFFQSxXQUFLLElBQUl0QyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHNkQsYUFBYSxDQUFDcEUsTUFBbEMsRUFBMENPLENBQUMsRUFBM0MsRUFBK0M7QUFDN0MsWUFBTWpCLEtBQUssR0FBRzhFLGFBQWEsQ0FBQzdELENBQUQsQ0FBM0I7QUFDQSxZQUFNOEQsR0FBRyxHQUFHTCxXQUFXLENBQUM7QUFBQzFFLFVBQUFBLEtBQUssRUFBTEE7QUFBRCxTQUFELENBQXZCLENBRjZDLENBSTdDO0FBQ0E7O0FBQ0EsWUFBSStFLEdBQUcsQ0FBQ2hFLEtBQUosQ0FBVWlFLE1BQU0sQ0FBQ0MsUUFBakIsQ0FBSixFQUFnQztBQUM5QjFCLFVBQUFBLElBQUksQ0FBQzJCLElBQUwsQ0FBVTtBQUNSbEYsWUFBQUEsS0FBSyxFQUFMQTtBQURRLFdBQVY7QUFHRDtBQUNGOztBQUVELGFBQU91RCxJQUFQO0FBQ0Q7OztXQUVELHlCQUFnQmlCLFFBQWhCLEVBQTBCVyxZQUExQixFQUF3QztBQUFBLGtDQUNIWCxRQUFRLENBQUMsS0FBSzdDLE1BQUwsQ0FBWXlELE1BQWIsQ0FETDtBQUFBLFVBQy9CQyxTQUQrQix5QkFDL0JBLFNBRCtCO0FBQUEsVUFDcEIzRCxhQURvQix5QkFDcEJBLGFBRG9CO0FBRXRDLFVBQU1nRCxXQUFXLEdBQUcsS0FBS2pELG1CQUFMLENBQXlCQyxhQUF6QixDQUFwQjtBQUVBLFVBQU00RCxhQUFhLEdBQUduRixnQkFBZ0IsQ0FDcEMsS0FBS3dCLE1BQUwsQ0FBWTRELFVBRHdCLEVBRXBDLEtBQUs1RCxNQUFMLENBQVlpQixTQUFaLENBQXNCNEMsZ0JBRmMsQ0FBdEM7QUFLQSxVQUFNQyxpQkFBaUIsR0FBR3RGLGdCQUFnQixDQUN4QyxLQUFLd0IsTUFBTCxDQUFZK0QsU0FENEIsRUFFeEMsS0FBSy9ELE1BQUwsQ0FBWWlCLFNBQVosQ0FBc0IrQyxlQUZrQixDQUExQztBQUlBLFVBQU1DLFNBQVMsR0FBRzFCLE1BQU0sQ0FBQzJCLE1BQVAsQ0FBY1IsU0FBUyxDQUFDekUsV0FBeEIsRUFBcUNrRixJQUFyQyxDQUEwQyxVQUFBQyxHQUFHO0FBQUEsZUFBSUEsR0FBRyxDQUFDRCxJQUFKLENBQVMsVUFBQUUsQ0FBQztBQUFBLGlCQUFJQSxDQUFDLEtBQUssQ0FBVjtBQUFBLFNBQVYsQ0FBSjtBQUFBLE9BQTdDLENBQWxCO0FBRUEsVUFBTW5GLGNBQWMsR0FBR3dFLFNBQVMsQ0FBQ1ksbUJBQVYsQ0FBOEJ2RSxhQUE5QixHQUF2QjtBQUNBLFVBQU13RSxVQUFVLEdBQUdOLFNBQVMsR0FDeEJqRixpQkFBaUIsQ0FBQzBFLFNBQVMsQ0FBQ3pFLFdBQVgsRUFBd0JDLGNBQXhCLENBRE8sR0FFeEJzRixTQUZKOztBQWhCc0MsNkJBb0J2QixLQUFLQyxVQUFMLENBQWdCNUIsUUFBaEIsRUFBMEJXLFlBQTFCLENBcEJ1QjtBQUFBLFVBb0IvQjVCLElBcEIrQixvQkFvQi9CQSxJQXBCK0I7O0FBc0J0QztBQUNFQSxRQUFBQSxJQUFJLEVBQUpBLElBREY7QUFFRW1CLFFBQUFBLFdBQVcsRUFBWEEsV0FGRjtBQUdFMkIsUUFBQUEsV0FBVyxFQUFFSDtBQUhmLFNBSU1aLGFBQWEsR0FBRztBQUFDQSxRQUFBQSxhQUFhLEVBQWJBO0FBQUQsT0FBSCxHQUFxQixFQUp4QyxHQUtNRyxpQkFBaUIsR0FBRztBQUFDQSxRQUFBQSxpQkFBaUIsRUFBakJBO0FBQUQsT0FBSCxHQUF5QixFQUxoRDtBQU9EOzs7V0FFRCxrQ0FBeUJhLElBQXpCLEVBQStCO0FBQzdCLFVBQU1DLFFBQVEsb0lBQWtDRCxJQUFsQyxDQUFkO0FBQ0EsNkNBQ0tDLFFBREw7QUFFRUMsUUFBQUEsY0FBYyxFQUFFQyxrQ0FGbEI7QUFHRTtBQUNBQyxRQUFBQSxVQUFVLEVBQUUsRUFKZDtBQUtFQyxRQUFBQSxhQUFhLEVBQUUsS0FBS2hGLE1BQUwsQ0FBWWlCLFNBQVosQ0FBc0JDO0FBTHZDO0FBT0Q7OztXQUVELHdDQUErQnlELElBQS9CLEVBQXFDO0FBQUEsVUFDNUJqQixTQUQ0QixHQUNnQmlCLElBRGhCLENBQzVCakIsU0FENEI7QUFBQSxVQUNqQnVCLFFBRGlCLEdBQ2dCTixJQURoQixDQUNqQk0sUUFEaUI7QUFBQSxpQ0FDZ0JOLElBRGhCLENBQ1BPLGNBRE87QUFBQSxVQUNQQSxjQURPLHFDQUNVLEVBRFY7QUFBQSxVQUU1QmpFLFNBRjRCLEdBRWYsS0FBS2pCLE1BRlUsQ0FFNUJpQixTQUY0QjtBQUduQyxVQUFNa0UsYUFBYSxHQUFHLEtBQUtDLHNCQUFMLENBQTRCSCxRQUE1QixDQUF0QjtBQUVBLFVBQU1JLGNBQWMsR0FBRztBQUNyQjFCLFFBQUFBLGFBQWEsRUFBRTtBQUNiQyxVQUFBQSxVQUFVLEVBQUUsS0FBSzVELE1BQUwsQ0FBWTRELFVBRFg7QUFFYkMsVUFBQUEsZ0JBQWdCLEVBQUUsS0FBSzdELE1BQUwsQ0FBWWlCLFNBQVosQ0FBc0I0QztBQUYzQixTQURNO0FBS3JCQyxRQUFBQSxpQkFBaUIsRUFBRTtBQUNqQkMsVUFBQUEsU0FBUyxFQUFFLEtBQUsvRCxNQUFMLENBQVkrRCxTQUROO0FBRWpCQyxVQUFBQSxlQUFlLEVBQUUsS0FBS2hFLE1BQUwsQ0FBWWlCLFNBQVosQ0FBc0IrQztBQUZ0QixTQUxFO0FBU3JCVSxRQUFBQSxXQUFXO0FBQ1R6RixVQUFBQSxXQUFXLEVBQUV5RSxTQUFTLENBQUN6RTtBQURkLFdBRU55RSxTQUFTLENBQUM0Qix5QkFGSjtBQVRVLE9BQXZCO0FBZUEsNkNBQ0ssS0FBS0Msd0JBQUwsQ0FBOEJaLElBQTlCLENBREw7QUFFRWEsUUFBQUEsUUFBUSxFQUFFdkUsU0FBUyxDQUFDdUUsUUFGdEI7QUFJRTtBQUNBaEcsUUFBQUEsVUFBVSxFQUFFLEtBQUtVLGFBQUwsQ0FBbUJlLFNBQVMsQ0FBQ3pCLFVBQTdCLENBTGQ7QUFNRWlHLFFBQUFBLGNBQWMsRUFBRSxLQUFLekYsTUFBTCxDQUFZMEYsVUFOOUI7QUFPRUMsUUFBQUEsZUFBZSxFQUFFMUUsU0FBUyxDQUFDMkUsVUFBVixDQUFxQixDQUFyQixDQVBuQjtBQVFFQyxRQUFBQSxlQUFlLEVBQUU1RSxTQUFTLENBQUMyRSxVQUFWLENBQXFCLENBQXJCLENBUm5CO0FBU0UvQixRQUFBQSxnQkFBZ0IsRUFBRTVDLFNBQVMsQ0FBQzRDLGdCQVQ5QjtBQVdFO0FBQ0FpQyxRQUFBQSxRQUFRLEVBQUU3RSxTQUFTLENBQUNDLFFBWnRCO0FBYUU2RSxRQUFBQSxjQUFjLEVBQUU5RSxTQUFTLENBQUM4RSxjQUFWLEdBQTJCWixhQWI3QztBQWNFYSxRQUFBQSxrQkFBa0IsRUFBRSxLQUFLaEcsTUFBTCxDQUFZaUcsU0FkbEM7QUFlRUMsUUFBQUEsY0FBYyxFQUFFakYsU0FBUyxDQUFDa0YsU0FmNUI7QUFnQkVDLFFBQUFBLHdCQUF3QixFQUFFbkYsU0FBUyxDQUFDb0YsbUJBQVYsQ0FBOEIsQ0FBOUIsQ0FoQjVCO0FBaUJFQyxRQUFBQSx3QkFBd0IsRUFBRXJGLFNBQVMsQ0FBQ29GLG1CQUFWLENBQThCLENBQTlCLENBakI1QjtBQW1CRTtBQUNBaEIsUUFBQUEsY0FBYyxFQUFkQSxjQXBCRjtBQXNCRTtBQUNBa0IsUUFBQUEsZ0JBQWdCLEVBQUVyQixjQUFjLENBQUNzQjtBQXZCbkM7QUF5QkQ7OztFQW5SMkNDLHFCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIxIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IG1lbW9pemUgZnJvbSAnbG9kYXNoLm1lbW9pemUnO1xuaW1wb3J0IExheWVyIGZyb20gJy4vYmFzZS1sYXllcic7XG5pbXBvcnQge2hleFRvUmdifSBmcm9tICd1dGlscy9jb2xvci11dGlscyc7XG5pbXBvcnQge2FnZ3JlZ2F0ZX0gZnJvbSAndXRpbHMvYWdncmVnYXRlLXV0aWxzJztcbmltcG9ydCB7XG4gIEhJR0hMSUdIX0NPTE9SXzNELFxuICBDSEFOTkVMX1NDQUxFUyxcbiAgRklFTERfT1BUUyxcbiAgREVGQVVMVF9BR0dSRUdBVElPTlxufSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbmV4cG9ydCBjb25zdCBwb2ludFBvc0FjY2Vzc29yID0gKHtsYXQsIGxuZ30pID0+IGRjID0+IGQgPT4gW1xuICBkYy52YWx1ZUF0KGQuaW5kZXgsIGxuZy5maWVsZElkeCksXG4gIGRjLnZhbHVlQXQoZC5pbmRleCwgbGF0LmZpZWxkSWR4KVxuXTtcblxuZXhwb3J0IGNvbnN0IHBvaW50UG9zUmVzb2x2ZXIgPSAoe2xhdCwgbG5nfSkgPT4gYCR7bGF0LmZpZWxkSWR4fS0ke2xuZy5maWVsZElkeH1gO1xuXG5leHBvcnQgY29uc3QgZ2V0VmFsdWVBZ2dyRnVuYyA9IChmaWVsZCwgYWdncmVnYXRpb24pID0+IHtcbiAgcmV0dXJuIHBvaW50cyA9PiB7XG4gICAgcmV0dXJuIGZpZWxkXG4gICAgICA/IGFnZ3JlZ2F0ZShcbiAgICAgICAgICBwb2ludHMubWFwKHAgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGZpZWxkLnZhbHVlQWNjZXNzb3IocCk7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgYWdncmVnYXRpb25cbiAgICAgICAgKVxuICAgICAgOiBwb2ludHMubGVuZ3RoO1xuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEZpbHRlckRhdGFGdW5jID0gKGZpbHRlclJhbmdlLCBnZXRGaWx0ZXJWYWx1ZSkgPT4gcHQgPT5cbiAgZ2V0RmlsdGVyVmFsdWUocHQpLmV2ZXJ5KCh2YWwsIGkpID0+IHZhbCA+PSBmaWx0ZXJSYW5nZVtpXVswXSAmJiB2YWwgPD0gZmlsdGVyUmFuZ2VbaV1bMV0pO1xuXG5jb25zdCBnZXRMYXllckNvbG9yUmFuZ2UgPSBjb2xvclJhbmdlID0+IGNvbG9yUmFuZ2UuY29sb3JzLm1hcChoZXhUb1JnYik7XG5cbmV4cG9ydCBjb25zdCBhZ2dyZWdhdGVSZXF1aXJlZENvbHVtbnMgPSBbJ2xhdCcsICdsbmcnXTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWdncmVnYXRpb25MYXllciBleHRlbmRzIExheWVyIHtcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLmdldFBvc2l0aW9uQWNjZXNzb3IgPSBkYXRhQ29udGFpbmVyID0+XG4gICAgICBwb2ludFBvc0FjY2Vzc29yKHRoaXMuY29uZmlnLmNvbHVtbnMpKGRhdGFDb250YWluZXIpO1xuICAgIHRoaXMuZ2V0Q29sb3JSYW5nZSA9IG1lbW9pemUoZ2V0TGF5ZXJDb2xvclJhbmdlKTtcbiAgfVxuXG4gIGdldCBpc0FnZ3JlZ2F0ZWQoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBnZXQgcmVxdWlyZWRMYXllckNvbHVtbnMoKSB7XG4gICAgcmV0dXJuIGFnZ3JlZ2F0ZVJlcXVpcmVkQ29sdW1ucztcbiAgfVxuXG4gIGdldCBjb2x1bW5QYWlycygpIHtcbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0UG9pbnRDb2x1bW5QYWlycztcbiAgfVxuXG4gIGdldCBub25lTGF5ZXJEYXRhQWZmZWN0aW5nUHJvcHMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLnN1cGVyLm5vbmVMYXllckRhdGFBZmZlY3RpbmdQcm9wcyxcbiAgICAgICdlbmFibGUzZCcsXG4gICAgICAnY29sb3JSYW5nZScsXG4gICAgICAnY29sb3JEb21haW4nLFxuICAgICAgJ3NpemVSYW5nZScsXG4gICAgICAnc2l6ZVNjYWxlJyxcbiAgICAgICdzaXplRG9tYWluJyxcbiAgICAgICdwZXJjZW50aWxlJyxcbiAgICAgICdjb3ZlcmFnZScsXG4gICAgICAnZWxldmF0aW9uUGVyY2VudGlsZScsXG4gICAgICAnZWxldmF0aW9uU2NhbGUnLFxuICAgICAgJ2VuYWJsZUVsZXZhdGlvblpvb21GYWN0b3InXG4gICAgXTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6IHtcbiAgICAgICAgYWdncmVnYXRpb246ICdjb2xvckFnZ3JlZ2F0aW9uJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMuY29sb3JBZ2dyLFxuICAgICAgICBkZWZhdWx0TWVhc3VyZTogJ3Byb3BlcnR5LnBvaW50Q291bnQnLFxuICAgICAgICBkb21haW46ICdjb2xvckRvbWFpbicsXG4gICAgICAgIGZpZWxkOiAnY29sb3JGaWVsZCcsXG4gICAgICAgIGtleTogJ2NvbG9yJyxcbiAgICAgICAgcHJvcGVydHk6ICdjb2xvcicsXG4gICAgICAgIHJhbmdlOiAnY29sb3JSYW5nZScsXG4gICAgICAgIHNjYWxlOiAnY29sb3JTY2FsZSdcbiAgICAgIH0sXG4gICAgICBzaXplOiB7XG4gICAgICAgIGFnZ3JlZ2F0aW9uOiAnc2l6ZUFnZ3JlZ2F0aW9uJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMuc2l6ZUFnZ3IsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcuZW5hYmxlM2QsXG4gICAgICAgIGRlZmF1bHRNZWFzdXJlOiAncHJvcGVydHkucG9pbnRDb3VudCcsXG4gICAgICAgIGRvbWFpbjogJ3NpemVEb21haW4nLFxuICAgICAgICBmaWVsZDogJ3NpemVGaWVsZCcsXG4gICAgICAgIGtleTogJ3NpemUnLFxuICAgICAgICBwcm9wZXJ0eTogJ2hlaWdodCcsXG4gICAgICAgIHJhbmdlOiAnc2l6ZVJhbmdlJyxcbiAgICAgICAgc2NhbGU6ICdzaXplU2NhbGUnXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRlc2NyaXB0aW9uIG9mIGEgdmlzdWFsQ2hhbm5lbCBjb25maWdcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcmV0dXJucyB7e2xhYmVsOiBzdHJpbmcsIG1lYXN1cmU6IChzdHJpbmd8c3RyaW5nKX19XG4gICAqL1xuICBnZXRWaXN1YWxDaGFubmVsRGVzY3JpcHRpb24oa2V5KSB7XG4gICAgLy8gZS5nLiBsYWJlbDogQ29sb3IsIG1lYXN1cmU6IEF2ZXJhZ2Ugb2YgRVRBXG4gICAgY29uc3Qge3JhbmdlLCBmaWVsZCwgZGVmYXVsdE1lYXN1cmUsIGFnZ3JlZ2F0aW9ufSA9IHRoaXMudmlzdWFsQ2hhbm5lbHNba2V5XTtcbiAgICBjb25zdCBmaWVsZENvbmZpZyA9IHRoaXMuY29uZmlnW2ZpZWxkXTtcbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IHRoaXMudmlzQ29uZmlnU2V0dGluZ3NbcmFuZ2VdLmxhYmVsLFxuICAgICAgbWVhc3VyZTogZmllbGRDb25maWdcbiAgICAgICAgPyBgJHt0aGlzLmNvbmZpZy52aXNDb25maWdbYWdncmVnYXRpb25dfSBvZiAke2ZpZWxkQ29uZmlnLmRpc3BsYXlOYW1lIHx8IGZpZWxkQ29uZmlnLm5hbWV9YFxuICAgICAgICA6IGRlZmF1bHRNZWFzdXJlXG4gICAgfTtcbiAgfVxuXG4gIGdldEhvdmVyRGF0YShvYmplY3QpIHtcbiAgICAvLyByZXR1cm4gYWdncmVnYXRlZCBvYmplY3RcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFnZ3JlZ2F0aW9uIGxheWVyIGhhbmRsZXMgdmlzdWFsIGNoYW5uZWwgYWdncmVnYXRpb24gaW5zaWRlIGRlY2suZ2wgbGF5ZXJcbiAgICovXG4gIHVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbCh7ZGF0YSwgZGF0YUNvbnRhaW5lcn0sIGNoYW5uZWwpIHtcbiAgICB0aGlzLnZhbGlkYXRlVmlzdWFsQ2hhbm5lbChjaGFubmVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhZ2dyZWdhdGlvbiB0eXBlIG9uIHRvcCBvZiBiYXNpYyBsYXllciB2aXN1YWwgY2hhbm5lbCB2YWxpZGF0aW9uXG4gICAqIEBwYXJhbSBjaGFubmVsXG4gICAqL1xuICB2YWxpZGF0ZVZpc3VhbENoYW5uZWwoY2hhbm5lbCkge1xuICAgIC8vIGZpZWxkIHR5cGUgZGVjaWRlcyBhZ2dyZWdhdGlvbiB0eXBlIGRlY2lkZXMgc2NhbGUgdHlwZVxuICAgIHRoaXMudmFsaWRhdGVGaWVsZFR5cGUoY2hhbm5lbCk7XG4gICAgdGhpcy52YWxpZGF0ZUFnZ3JlZ2F0aW9uVHlwZShjaGFubmVsKTtcbiAgICB0aGlzLnZhbGlkYXRlU2NhbGUoY2hhbm5lbCk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYWdncmVnYXRpb24gdHlwZSBiYXNlZCBvbiBzZWxlY3RlZCBmaWVsZFxuICAgKi9cbiAgdmFsaWRhdGVBZ2dyZWdhdGlvblR5cGUoY2hhbm5lbCkge1xuICAgIGNvbnN0IHZpc3VhbENoYW5uZWwgPSB0aGlzLnZpc3VhbENoYW5uZWxzW2NoYW5uZWxdO1xuICAgIGNvbnN0IHtmaWVsZCwgYWdncmVnYXRpb259ID0gdmlzdWFsQ2hhbm5lbDtcbiAgICBjb25zdCBhZ2dyZWdhdGlvbk9wdGlvbnMgPSB0aGlzLmdldEFnZ3JlZ2F0aW9uT3B0aW9ucyhjaGFubmVsKTtcblxuICAgIGlmICghYWdncmVnYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWFnZ3JlZ2F0aW9uT3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgIC8vIGlmIGZpZWxkIGNhbm5vdCBiZSBhZ2dyZWdhdGVkLCBzZXQgZmllbGQgdG8gbnVsbFxuICAgICAgdGhpcy51cGRhdGVMYXllckNvbmZpZyh7W2ZpZWxkXTogbnVsbH0pO1xuICAgIH0gZWxzZSBpZiAoIWFnZ3JlZ2F0aW9uT3B0aW9ucy5pbmNsdWRlcyh0aGlzLmNvbmZpZy52aXNDb25maWdbYWdncmVnYXRpb25dKSkge1xuICAgICAgLy8gY3VycmVudCBhZ2dyZWdhdGlvbiB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBmaWVsZFxuICAgICAgLy8gc2V0IGFnZ3JlZ2F0aW9uIHRvIHRoZSBmaXJzdCBzdXBwb3J0ZWQgb3B0aW9uXG4gICAgICB0aGlzLnVwZGF0ZUxheWVyVmlzQ29uZmlnKHtbYWdncmVnYXRpb25dOiBhZ2dyZWdhdGlvbk9wdGlvbnNbMF19KTtcbiAgICB9XG4gIH1cblxuICBnZXRBZ2dyZWdhdGlvbk9wdGlvbnMoY2hhbm5lbCkge1xuICAgIGNvbnN0IHZpc3VhbENoYW5uZWwgPSB0aGlzLnZpc3VhbENoYW5uZWxzW2NoYW5uZWxdO1xuICAgIGNvbnN0IHtmaWVsZCwgY2hhbm5lbFNjYWxlVHlwZX0gPSB2aXN1YWxDaGFubmVsO1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKFxuICAgICAgdGhpcy5jb25maWdbZmllbGRdXG4gICAgICAgID8gRklFTERfT1BUU1t0aGlzLmNvbmZpZ1tmaWVsZF0udHlwZV0uc2NhbGVbY2hhbm5lbFNjYWxlVHlwZV1cbiAgICAgICAgOiBERUZBVUxUX0FHR1JFR0FUSU9OW2NoYW5uZWxTY2FsZVR5cGVdXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2NhbGUgb3B0aW9ucyBiYXNlZCBvbiBjdXJyZW50IGZpZWxkIGFuZCBhZ2dyZWdhdGlvbiB0eXBlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFubmVsXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX1cbiAgICovXG4gIGdldFNjYWxlT3B0aW9ucyhjaGFubmVsKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge2ZpZWxkLCBhZ2dyZWdhdGlvbiwgY2hhbm5lbFNjYWxlVHlwZX0gPSB2aXN1YWxDaGFubmVsO1xuICAgIGNvbnN0IGFnZ3JlZ2F0aW9uVHlwZSA9IHRoaXMuY29uZmlnLnZpc0NvbmZpZ1thZ2dyZWdhdGlvbl07XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnW2ZpZWxkXVxuICAgICAgPyAvLyBzY2FsZSBvcHRpb25zIGJhc2VkIG9uIGFnZ3JlZ2F0aW9uXG4gICAgICAgIEZJRUxEX09QVFNbdGhpcy5jb25maWdbZmllbGRdLnR5cGVdLnNjYWxlW2NoYW5uZWxTY2FsZVR5cGVdW2FnZ3JlZ2F0aW9uVHlwZV1cbiAgICAgIDogLy8gZGVmYXVsdCBzY2FsZSBvcHRpb25zIGZvciBwb2ludCBjb3VudFxuICAgICAgICBERUZBVUxUX0FHR1JFR0FUSU9OW2NoYW5uZWxTY2FsZVR5cGVdW2FnZ3JlZ2F0aW9uVHlwZV07XG4gIH1cblxuICAvKipcbiAgICogQWdncmVnYXRpb24gbGF5ZXIgaGFuZGxlcyB2aXN1YWwgY2hhbm5lbCBhZ2dyZWdhdGlvbiBpbnNpZGUgZGVjay5nbCBsYXllclxuICAgKi9cbiAgdXBkYXRlTGF5ZXJEb21haW4oZGF0YXNldHMsIG5ld0ZpbHRlcikge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJNZXRhKGRhdGFDb250YWluZXIsIGdldFBvc2l0aW9uKSB7XG4gICAgLy8gZ2V0IGJvdW5kcyBmcm9tIHBvaW50c1xuICAgIGNvbnN0IGJvdW5kcyA9IHRoaXMuZ2V0UG9pbnRzQm91bmRzKGRhdGFDb250YWluZXIsIGdldFBvc2l0aW9uKTtcblxuICAgIHRoaXMudXBkYXRlTWV0YSh7Ym91bmRzfSk7XG4gIH1cblxuICBjYWxjdWxhdGVEYXRhQXR0cmlidXRlKHtkYXRhQ29udGFpbmVyLCBmaWx0ZXJlZEluZGV4fSwgZ2V0UG9zaXRpb24pIHtcbiAgICBjb25zdCBkYXRhID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbHRlcmVkSW5kZXgubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gZmlsdGVyZWRJbmRleFtpXTtcbiAgICAgIGNvbnN0IHBvcyA9IGdldFBvc2l0aW9uKHtpbmRleH0pO1xuXG4gICAgICAvLyBpZiBkb2Vzbid0IGhhdmUgcG9pbnQgbGF0IG9yIGxuZywgZG8gbm90IGFkZCB0aGUgcG9pbnRcbiAgICAgIC8vIGRlY2suZ2wgY2FuJ3QgaGFuZGxlIHBvc2l0aW9uID0gbnVsbFxuICAgICAgaWYgKHBvcy5ldmVyeShOdW1iZXIuaXNGaW5pdGUpKSB7XG4gICAgICAgIGRhdGEucHVzaCh7XG4gICAgICAgICAgaW5kZXhcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBmb3JtYXRMYXllckRhdGEoZGF0YXNldHMsIG9sZExheWVyRGF0YSkge1xuICAgIGNvbnN0IHtncHVGaWx0ZXIsIGRhdGFDb250YWluZXJ9ID0gZGF0YXNldHNbdGhpcy5jb25maWcuZGF0YUlkXTtcbiAgICBjb25zdCBnZXRQb3NpdGlvbiA9IHRoaXMuZ2V0UG9zaXRpb25BY2Nlc3NvcihkYXRhQ29udGFpbmVyKTtcblxuICAgIGNvbnN0IGdldENvbG9yVmFsdWUgPSBnZXRWYWx1ZUFnZ3JGdW5jKFxuICAgICAgdGhpcy5jb25maWcuY29sb3JGaWVsZCxcbiAgICAgIHRoaXMuY29uZmlnLnZpc0NvbmZpZy5jb2xvckFnZ3JlZ2F0aW9uXG4gICAgKTtcblxuICAgIGNvbnN0IGdldEVsZXZhdGlvblZhbHVlID0gZ2V0VmFsdWVBZ2dyRnVuYyhcbiAgICAgIHRoaXMuY29uZmlnLnNpemVGaWVsZCxcbiAgICAgIHRoaXMuY29uZmlnLnZpc0NvbmZpZy5zaXplQWdncmVnYXRpb25cbiAgICApO1xuICAgIGNvbnN0IGhhc0ZpbHRlciA9IE9iamVjdC52YWx1ZXMoZ3B1RmlsdGVyLmZpbHRlclJhbmdlKS5zb21lKGFyciA9PiBhcnIuc29tZSh2ID0+IHYgIT09IDApKTtcblxuICAgIGNvbnN0IGdldEZpbHRlclZhbHVlID0gZ3B1RmlsdGVyLmZpbHRlclZhbHVlQWNjZXNzb3IoZGF0YUNvbnRhaW5lcikoKTtcbiAgICBjb25zdCBmaWx0ZXJEYXRhID0gaGFzRmlsdGVyXG4gICAgICA/IGdldEZpbHRlckRhdGFGdW5jKGdwdUZpbHRlci5maWx0ZXJSYW5nZSwgZ2V0RmlsdGVyVmFsdWUpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHtkYXRhfSA9IHRoaXMudXBkYXRlRGF0YShkYXRhc2V0cywgb2xkTGF5ZXJEYXRhKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgZ2V0UG9zaXRpb24sXG4gICAgICBfZmlsdGVyRGF0YTogZmlsdGVyRGF0YSxcbiAgICAgIC4uLihnZXRDb2xvclZhbHVlID8ge2dldENvbG9yVmFsdWV9IDoge30pLFxuICAgICAgLi4uKGdldEVsZXZhdGlvblZhbHVlID8ge2dldEVsZXZhdGlvblZhbHVlfSA6IHt9KVxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0RGVja0xheWVyUHJvcHMob3B0cykge1xuICAgIGNvbnN0IGJhc2VQcm9wID0gc3VwZXIuZ2V0RGVmYXVsdERlY2tMYXllclByb3BzKG9wdHMpO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5iYXNlUHJvcCxcbiAgICAgIGhpZ2hsaWdodENvbG9yOiBISUdITElHSF9DT0xPUl8zRCxcbiAgICAgIC8vIGdwdSBkYXRhIGZpbHRlcmluZyBpcyBub3Qgc3VwcG9ydGVkIGluIGFnZ3JlZ2F0aW9uIGxheWVyXG4gICAgICBleHRlbnNpb25zOiBbXSxcbiAgICAgIGF1dG9IaWdobGlnaHQ6IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5lbmFibGUzZFxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0QWdncmVnYXRpb25MYXllclByb3Aob3B0cykge1xuICAgIGNvbnN0IHtncHVGaWx0ZXIsIG1hcFN0YXRlLCBsYXllckNhbGxiYWNrcyA9IHt9fSA9IG9wdHM7XG4gICAgY29uc3Qge3Zpc0NvbmZpZ30gPSB0aGlzLmNvbmZpZztcbiAgICBjb25zdCBlbGVab29tRmFjdG9yID0gdGhpcy5nZXRFbGV2YXRpb25ab29tRmFjdG9yKG1hcFN0YXRlKTtcblxuICAgIGNvbnN0IHVwZGF0ZVRyaWdnZXJzID0ge1xuICAgICAgZ2V0Q29sb3JWYWx1ZToge1xuICAgICAgICBjb2xvckZpZWxkOiB0aGlzLmNvbmZpZy5jb2xvckZpZWxkLFxuICAgICAgICBjb2xvckFnZ3JlZ2F0aW9uOiB0aGlzLmNvbmZpZy52aXNDb25maWcuY29sb3JBZ2dyZWdhdGlvblxuICAgICAgfSxcbiAgICAgIGdldEVsZXZhdGlvblZhbHVlOiB7XG4gICAgICAgIHNpemVGaWVsZDogdGhpcy5jb25maWcuc2l6ZUZpZWxkLFxuICAgICAgICBzaXplQWdncmVnYXRpb246IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5zaXplQWdncmVnYXRpb25cbiAgICAgIH0sXG4gICAgICBfZmlsdGVyRGF0YToge1xuICAgICAgICBmaWx0ZXJSYW5nZTogZ3B1RmlsdGVyLmZpbHRlclJhbmdlLFxuICAgICAgICAuLi5ncHVGaWx0ZXIuZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2Vyc1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5nZXREZWZhdWx0RGVja0xheWVyUHJvcHMob3B0cyksXG4gICAgICBjb3ZlcmFnZTogdmlzQ29uZmlnLmNvdmVyYWdlLFxuXG4gICAgICAvLyBjb2xvclxuICAgICAgY29sb3JSYW5nZTogdGhpcy5nZXRDb2xvclJhbmdlKHZpc0NvbmZpZy5jb2xvclJhbmdlKSxcbiAgICAgIGNvbG9yU2NhbGVUeXBlOiB0aGlzLmNvbmZpZy5jb2xvclNjYWxlLFxuICAgICAgdXBwZXJQZXJjZW50aWxlOiB2aXNDb25maWcucGVyY2VudGlsZVsxXSxcbiAgICAgIGxvd2VyUGVyY2VudGlsZTogdmlzQ29uZmlnLnBlcmNlbnRpbGVbMF0sXG4gICAgICBjb2xvckFnZ3JlZ2F0aW9uOiB2aXNDb25maWcuY29sb3JBZ2dyZWdhdGlvbixcblxuICAgICAgLy8gZWxldmF0aW9uXG4gICAgICBleHRydWRlZDogdmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgZWxldmF0aW9uU2NhbGU6IHZpc0NvbmZpZy5lbGV2YXRpb25TY2FsZSAqIGVsZVpvb21GYWN0b3IsXG4gICAgICBlbGV2YXRpb25TY2FsZVR5cGU6IHRoaXMuY29uZmlnLnNpemVTY2FsZSxcbiAgICAgIGVsZXZhdGlvblJhbmdlOiB2aXNDb25maWcuc2l6ZVJhbmdlLFxuICAgICAgZWxldmF0aW9uTG93ZXJQZXJjZW50aWxlOiB2aXNDb25maWcuZWxldmF0aW9uUGVyY2VudGlsZVswXSxcbiAgICAgIGVsZXZhdGlvblVwcGVyUGVyY2VudGlsZTogdmlzQ29uZmlnLmVsZXZhdGlvblBlcmNlbnRpbGVbMV0sXG5cbiAgICAgIC8vIHVwZGF0ZVRyaWdnZXJzXG4gICAgICB1cGRhdGVUcmlnZ2VycyxcblxuICAgICAgLy8gY2FsbGJhY2tzXG4gICAgICBvblNldENvbG9yRG9tYWluOiBsYXllckNhbGxiYWNrcy5vblNldExheWVyRG9tYWluXG4gICAgfTtcbiAgfVxufVxuIl19