UNPKG

kepler.gl

Version:

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

296 lines (290 loc) 38.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.clusterAggregation = void 0; 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 _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _core = require("@deck.gl/core"); var _layers = require("@deck.gl/layers"); var _geoViewport = _interopRequireDefault(require("@mapbox/geo-viewport")); var _cpuAggregator = _interopRequireWildcard(require("../layer-utils/cpu-aggregator")); var _viewportMercatorProject = require("viewport-mercator-project"); var _d3Array = require("d3-array"); var _constants = require("@kepler.gl/constants"); var _clusterUtils = _interopRequireWildcard(require("../layer-utils/cluster-utils")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 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 _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project var defaultRadius = _constants.LAYER_VIS_CONFIGS.clusterRadius.defaultValue; var defaultRadiusRange = _constants.LAYER_VIS_CONFIGS.clusterRadiusRange.defaultValue; var defaultGetColorValue = function defaultGetColorValue(points) { return points.length; }; var defaultGetRadiusValue = function defaultGetRadiusValue(cell) { return cell.filteredPoints ? cell.filteredPoints.length : cell.points.length; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars function processGeoJSON(step, props, aggregation, _ref) { var viewport = _ref.viewport; var data = props.data, getPosition = props.getPosition, filterData = props.filterData; var geoJSON = (0, _clusterUtils.getGeoJSON)(data, getPosition, filterData); var clusterBuilder = new _clusterUtils["default"](); this.setState({ geoJSON: geoJSON, clusterBuilder: clusterBuilder }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars function getClusters(step, props, aggregation, _ref2) { var _clusterBuilder$clust; var viewport = _ref2.viewport; var _this$state = this.state, geoJSON = _this$state.geoJSON, clusterBuilder = _this$state.clusterBuilder; var clusterRadius = props.clusterRadius, zoom = props.zoom, width = props.width, height = props.height; var longitude = viewport.longitude, latitude = viewport.latitude; // zoom needs to be an integer for the different map utils. Also helps with cache key. var bbox = _geoViewport["default"].bounds([longitude, latitude], zoom, [width, height]); var clusters = (_clusterBuilder$clust = clusterBuilder === null || clusterBuilder === void 0 ? void 0 : clusterBuilder.clustersAtZoom({ bbox: bbox, clusterRadius: clusterRadius, geoJSON: geoJSON, zoom: zoom })) !== null && _clusterBuilder$clust !== void 0 ? _clusterBuilder$clust : []; this.setState({ layerData: { data: clusters } }); } function getSubLayerRadius(dimensionState, dimension, layerProps) { return function (cell) { var getRadiusValue = layerProps.getRadiusValue; var scaleFunc = dimensionState.scaleFunc; return scaleFunc(getRadiusValue(cell)); }; } var clusterAggregation = exports.clusterAggregation = { key: 'position', updateSteps: [{ key: 'geojson', triggers: { position: { prop: 'getPosition', updateTrigger: 'getPosition' }, filterData: { prop: 'filterData', updateTrigger: 'filterData' } }, updater: processGeoJSON }, { key: 'clustering', triggers: { clusterRadius: { prop: 'clusterRadius' }, zoom: { prop: 'zoom' }, width: { prop: 'width' }, height: { prop: 'height' } }, updater: getClusters }] }; function getRadiusValueDomain(step, props, dimensionUpdater) { var key = dimensionUpdater.key; var getRadiusValue = props.getRadiusValue; var layerData = this.state.layerData; var valueDomain = [0, (0, _d3Array.max)(layerData.data, getRadiusValue)]; this._setDimensionState(key, { valueDomain: valueDomain }); } var clusterLayerDimensions = [_cpuAggregator.defaultColorDimension, { key: 'radius', accessor: 'getRadius', nullValue: 0, updateSteps: [{ key: 'getDomain', triggers: { value: { prop: 'getRadiusValue', updateTrigger: 'getRadiusValue' } }, updater: getRadiusValueDomain }, { key: 'getScaleFunc', triggers: { domain: { prop: 'radiusDomain' }, range: { prop: 'radiusRange' }, scaleType: { prop: 'radiusScaleType' } }, updater: _cpuAggregator.getDimensionScale }], getSubLayerAccessor: getSubLayerRadius, getPickingInfo: function getPickingInfo(dimensionState, cell, layerProps) { var radiusValue = layerProps.getRadiusValue(cell); var scaleFunc = dimensionState.scaleFunc; var scaledRadiusValue = scaleFunc ? scaleFunc(radiusValue) : radiusValue; return { radiusValue: radiusValue, scaledRadiusValue: scaledRadiusValue }; } }]; var defaultProps = { clusterRadius: defaultRadius, colorDomain: null, colorRange: _constants.DEFAULT_COLOR_RANGE, colorScaleType: _constants.SCALE_TYPES.quantize, radiusScaleType: _constants.SCALE_TYPES.sqrt, radiusRange: defaultRadiusRange, getPosition: { type: 'accessor', value: function value(x) { return x.position; } }, getColorValue: { type: 'accessor', value: defaultGetColorValue }, getRadiusValue: { type: 'accessor', value: defaultGetRadiusValue } }; var ClusterLayer = exports["default"] = /*#__PURE__*/function (_CompositeLayer) { function ClusterLayer() { (0, _classCallCheck2["default"])(this, ClusterLayer); return _callSuper(this, ClusterLayer, arguments); } (0, _inherits2["default"])(ClusterLayer, _CompositeLayer); return (0, _createClass2["default"])(ClusterLayer, [{ key: "initializeState", value: function initializeState() { var cpuAggregator = new _cpuAggregator["default"]({ aggregation: clusterAggregation, dimensions: clusterLayerDimensions }); this.state = { cpuAggregator: cpuAggregator, aggregatorState: cpuAggregator.state }; } }, { key: "updateState", value: function updateState(_ref3) { var oldProps = _ref3.oldProps, props = _ref3.props, changeFlags = _ref3.changeFlags; this.setState({ aggregatorState: this.state.cpuAggregator.updateState({ oldProps: oldProps, props: props, changeFlags: changeFlags }, { viewport: this.context.viewport, // @ts-expect-error props passed for internal calculation numInstances: this.getNumInstances(props) }) }); } }, { key: "getPickingInfo", value: function getPickingInfo(_ref4) { var info = _ref4.info; var obj = this.state.cpuAggregator.getPickingInfo({ info: info }, this.props); if (obj !== null && obj !== void 0 && obj.object) { // @ts-expect-error var distanceScale = (0, _viewportMercatorProject.getDistanceScales)(this.context.viewport); var metersPerPixel = distanceScale.metersPerPixel[0]; obj.object.scaledRadiusValue = obj.object.scaledRadiusValue * metersPerPixel; } return obj; } }, { key: "_getSublayerUpdateTriggers", value: function _getSublayerUpdateTriggers() { return this.state.cpuAggregator.getUpdateTriggers(this.props); } }, { key: "_getSubLayerAccessors", value: function _getSubLayerAccessors() { return { getRadius: this.state.cpuAggregator.getAccessor('radius', this.props), getFillColor: this.state.cpuAggregator.getAccessor('fillColor', this.props) }; } }, { key: "renderLayers", value: function renderLayers() { var _ref5 = this.props, id = _ref5.id, radiusScale = _ref5.radiusScale, visible = _ref5.visible, opacity = _ref5.opacity, pickable = _ref5.pickable, autoHighlight = _ref5.autoHighlight, highlightColor = _ref5.highlightColor; var _ref6 = this.state, cpuAggregator = _ref6.cpuAggregator; var updateTriggers = this._getSublayerUpdateTriggers(); var accessors = this._getSubLayerAccessors(); // @ts-expect-error var distanceScale = (0, _viewportMercatorProject.getDistanceScales)(this.context.viewport); var metersPerPixel = distanceScale.metersPerPixel[0]; // return props to the sublayer constructor return new _layers.ScatterplotLayer(_objectSpread({ id: "".concat(id, "-cluster"), data: cpuAggregator.state.layerData.data, radiusScale: metersPerPixel * radiusScale, visible: visible, opacity: opacity, pickable: pickable, autoHighlight: autoHighlight, highlightColor: highlightColor, updateTriggers: updateTriggers, parameters: { depthMask: false } }, accessors)); } }]); }(_core.CompositeLayer); ClusterLayer.layerName = 'ClusterLayer'; ClusterLayer.defaultProps = defaultProps; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29yZSIsInJlcXVpcmUiLCJfbGF5ZXJzIiwiX2dlb1ZpZXdwb3J0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9jcHVBZ2dyZWdhdG9yIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJfdmlld3BvcnRNZXJjYXRvclByb2plY3QiLCJfZDNBcnJheSIsIl9jb25zdGFudHMiLCJfY2x1c3RlclV0aWxzIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJfdHlwZW9mIiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0Iiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiX2NhbGxTdXBlciIsIl9nZXRQcm90b3R5cGVPZjIiLCJfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIiLCJfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IiwiUmVmbGVjdCIsImNvbnN0cnVjdCIsImNvbnN0cnVjdG9yIiwiQm9vbGVhbiIsInByb3RvdHlwZSIsInZhbHVlT2YiLCJkZWZhdWx0UmFkaXVzIiwiTEFZRVJfVklTX0NPTkZJR1MiLCJjbHVzdGVyUmFkaXVzIiwiZGVmYXVsdFZhbHVlIiwiZGVmYXVsdFJhZGl1c1JhbmdlIiwiY2x1c3RlclJhZGl1c1JhbmdlIiwiZGVmYXVsdEdldENvbG9yVmFsdWUiLCJwb2ludHMiLCJkZWZhdWx0R2V0UmFkaXVzVmFsdWUiLCJjZWxsIiwiZmlsdGVyZWRQb2ludHMiLCJwcm9jZXNzR2VvSlNPTiIsInN0ZXAiLCJwcm9wcyIsImFnZ3JlZ2F0aW9uIiwiX3JlZiIsInZpZXdwb3J0IiwiZGF0YSIsImdldFBvc2l0aW9uIiwiZmlsdGVyRGF0YSIsImdlb0pTT04iLCJnZXRHZW9KU09OIiwiY2x1c3RlckJ1aWxkZXIiLCJDbHVzdGVyQnVpbGRlciIsInNldFN0YXRlIiwiZ2V0Q2x1c3RlcnMiLCJfcmVmMiIsIl9jbHVzdGVyQnVpbGRlciRjbHVzdCIsIl90aGlzJHN0YXRlIiwic3RhdGUiLCJ6b29tIiwid2lkdGgiLCJoZWlnaHQiLCJsb25naXR1ZGUiLCJsYXRpdHVkZSIsImJib3giLCJnZW9WaWV3cG9ydCIsImJvdW5kcyIsImNsdXN0ZXJzIiwiY2x1c3RlcnNBdFpvb20iLCJsYXllckRhdGEiLCJnZXRTdWJMYXllclJhZGl1cyIsImRpbWVuc2lvblN0YXRlIiwiZGltZW5zaW9uIiwibGF5ZXJQcm9wcyIsImdldFJhZGl1c1ZhbHVlIiwic2NhbGVGdW5jIiwiY2x1c3RlckFnZ3JlZ2F0aW9uIiwiZXhwb3J0cyIsImtleSIsInVwZGF0ZVN0ZXBzIiwidHJpZ2dlcnMiLCJwb3NpdGlvbiIsInByb3AiLCJ1cGRhdGVUcmlnZ2VyIiwidXBkYXRlciIsImdldFJhZGl1c1ZhbHVlRG9tYWluIiwiZGltZW5zaW9uVXBkYXRlciIsInZhbHVlRG9tYWluIiwibWF4IiwiX3NldERpbWVuc2lvblN0YXRlIiwiY2x1c3RlckxheWVyRGltZW5zaW9ucyIsImRlZmF1bHRDb2xvckRpbWVuc2lvbiIsImFjY2Vzc29yIiwibnVsbFZhbHVlIiwidmFsdWUiLCJkb21haW4iLCJyYW5nZSIsInNjYWxlVHlwZSIsImdldERpbWVuc2lvblNjYWxlIiwiZ2V0U3ViTGF5ZXJBY2Nlc3NvciIsImdldFBpY2tpbmdJbmZvIiwicmFkaXVzVmFsdWUiLCJzY2FsZWRSYWRpdXNWYWx1ZSIsImRlZmF1bHRQcm9wcyIsImNvbG9yRG9tYWluIiwiY29sb3JSYW5nZSIsIkRFRkFVTFRfQ09MT1JfUkFOR0UiLCJjb2xvclNjYWxlVHlwZSIsIlNDQUxFX1RZUEVTIiwicXVhbnRpemUiLCJyYWRpdXNTY2FsZVR5cGUiLCJzcXJ0IiwicmFkaXVzUmFuZ2UiLCJ0eXBlIiwieCIsImdldENvbG9yVmFsdWUiLCJDbHVzdGVyTGF5ZXIiLCJfQ29tcG9zaXRlTGF5ZXIiLCJfY2xhc3NDYWxsQ2hlY2syIiwiX2luaGVyaXRzMiIsIl9jcmVhdGVDbGFzczIiLCJpbml0aWFsaXplU3RhdGUiLCJjcHVBZ2dyZWdhdG9yIiwiQ1BVQWdncmVnYXRvciIsImRpbWVuc2lvbnMiLCJhZ2dyZWdhdG9yU3RhdGUiLCJ1cGRhdGVTdGF0ZSIsIl9yZWYzIiwib2xkUHJvcHMiLCJjaGFuZ2VGbGFncyIsImNvbnRleHQiLCJudW1JbnN0YW5jZXMiLCJnZXROdW1JbnN0YW5jZXMiLCJfcmVmNCIsImluZm8iLCJvYmoiLCJvYmplY3QiLCJkaXN0YW5jZVNjYWxlIiwiZ2V0RGlzdGFuY2VTY2FsZXMiLCJtZXRlcnNQZXJQaXhlbCIsIl9nZXRTdWJsYXllclVwZGF0ZVRyaWdnZXJzIiwiZ2V0VXBkYXRlVHJpZ2dlcnMiLCJfZ2V0U3ViTGF5ZXJBY2Nlc3NvcnMiLCJnZXRSYWRpdXMiLCJnZXRBY2Nlc3NvciIsImdldEZpbGxDb2xvciIsInJlbmRlckxheWVycyIsIl9yZWY1IiwiaWQiLCJyYWRpdXNTY2FsZSIsInZpc2libGUiLCJvcGFjaXR5IiwicGlja2FibGUiLCJhdXRvSGlnaGxpZ2h0IiwiaGlnaGxpZ2h0Q29sb3IiLCJfcmVmNiIsInVwZGF0ZVRyaWdnZXJzIiwiYWNjZXNzb3JzIiwiU2NhdHRlcnBsb3RMYXllciIsImNvbmNhdCIsInBhcmFtZXRlcnMiLCJkZXB0aE1hc2siLCJDb21wb3NpdGVMYXllciIsImxheWVyTmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbHVzdGVyLWxheWVyL2NsdXN0ZXItbGF5ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHtDb21wb3NpdGVMYXllciwgR2V0UGlja2luZ0luZm9QYXJhbXMsIFBpY2tpbmdJbmZvfSBmcm9tICdAZGVjay5nbC9jb3JlJztcbmltcG9ydCB7U2NhdHRlcnBsb3RMYXllcn0gZnJvbSAnQGRlY2suZ2wvbGF5ZXJzJztcblxuaW1wb3J0IGdlb1ZpZXdwb3J0IGZyb20gJ0BtYXBib3gvZ2VvLXZpZXdwb3J0JztcbmltcG9ydCBDUFVBZ2dyZWdhdG9yLCB7XG4gIEFnZ3JlZ2F0aW9uVHlwZSxcbiAgZGVmYXVsdENvbG9yRGltZW5zaW9uLFxuICBEaW1lbnNpb25UeXBlLFxuICBnZXREaW1lbnNpb25TY2FsZVxufSBmcm9tICcuLi9sYXllci11dGlscy9jcHUtYWdncmVnYXRvcic7XG5pbXBvcnQge2dldERpc3RhbmNlU2NhbGVzfSBmcm9tICd2aWV3cG9ydC1tZXJjYXRvci1wcm9qZWN0JztcbmltcG9ydCB7bWF4fSBmcm9tICdkMy1hcnJheSc7XG5cbmltcG9ydCB7U0NBTEVfVFlQRVMsIERFRkFVTFRfQ09MT1JfUkFOR0UsIExBWUVSX1ZJU19DT05GSUdTfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQgQ2x1c3RlckJ1aWxkZXIsIHtnZXRHZW9KU09OfSBmcm9tICcuLi9sYXllci11dGlscy9jbHVzdGVyLXV0aWxzJztcbmltcG9ydCB7UkdCQUNvbG9yfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuY29uc3QgZGVmYXVsdFJhZGl1cyA9IExBWUVSX1ZJU19DT05GSUdTLmNsdXN0ZXJSYWRpdXMuZGVmYXVsdFZhbHVlO1xuY29uc3QgZGVmYXVsdFJhZGl1c1JhbmdlID0gTEFZRVJfVklTX0NPTkZJR1MuY2x1c3RlclJhZGl1c1JhbmdlLmRlZmF1bHRWYWx1ZTtcblxuY29uc3QgZGVmYXVsdEdldENvbG9yVmFsdWUgPSAocG9pbnRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdKSA9PiBwb2ludHMubGVuZ3RoO1xuY29uc3QgZGVmYXVsdEdldFJhZGl1c1ZhbHVlID0gKGNlbGw6IHtmaWx0ZXJlZFBvaW50cz86IHVua25vd25bXTsgcG9pbnRzOiB1bmtub3duW119KSA9PlxuICBjZWxsLmZpbHRlcmVkUG9pbnRzID8gY2VsbC5maWx0ZXJlZFBvaW50cy5sZW5ndGggOiBjZWxsLnBvaW50cy5sZW5ndGg7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIHByb2Nlc3NHZW9KU09OKHRoaXM6IENQVUFnZ3JlZ2F0b3IsIHN0ZXAsIHByb3BzLCBhZ2dyZWdhdGlvbiwge3ZpZXdwb3J0fSkge1xuICBjb25zdCB7ZGF0YSwgZ2V0UG9zaXRpb24sIGZpbHRlckRhdGF9ID0gcHJvcHM7XG4gIGNvbnN0IGdlb0pTT04gPSBnZXRHZW9KU09OKGRhdGEsIGdldFBvc2l0aW9uLCBmaWx0ZXJEYXRhKTtcbiAgY29uc3QgY2x1c3RlckJ1aWxkZXIgPSBuZXcgQ2x1c3RlckJ1aWxkZXIoKTtcblxuICB0aGlzLnNldFN0YXRlKHtnZW9KU09OLCBjbHVzdGVyQnVpbGRlcn0pO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5mdW5jdGlvbiBnZXRDbHVzdGVycyh0aGlzOiBDUFVBZ2dyZWdhdG9yLCBzdGVwLCBwcm9wcywgYWdncmVnYXRpb24sIHt2aWV3cG9ydH0pIHtcbiAgY29uc3Qge2dlb0pTT04sIGNsdXN0ZXJCdWlsZGVyfSA9IHRoaXMuc3RhdGU7XG4gIGNvbnN0IHtjbHVzdGVyUmFkaXVzLCB6b29tLCB3aWR0aCwgaGVpZ2h0fSA9IHByb3BzO1xuICBjb25zdCB7bG9uZ2l0dWRlLCBsYXRpdHVkZX0gPSB2aWV3cG9ydDtcblxuICAvLyB6b29tIG5lZWRzIHRvIGJlIGFuIGludGVnZXIgZm9yIHRoZSBkaWZmZXJlbnQgbWFwIHV0aWxzLiBBbHNvIGhlbHBzIHdpdGggY2FjaGUga2V5LlxuICBjb25zdCBiYm94ID0gZ2VvVmlld3BvcnQuYm91bmRzKFtsb25naXR1ZGUsIGxhdGl0dWRlXSwgem9vbSwgW3dpZHRoLCBoZWlnaHRdKTtcbiAgY29uc3QgY2x1c3RlcnMgPSBjbHVzdGVyQnVpbGRlcj8uY2x1c3RlcnNBdFpvb20oe2Jib3gsIGNsdXN0ZXJSYWRpdXMsIGdlb0pTT04sIHpvb219KSA/PyBbXTtcblxuICB0aGlzLnNldFN0YXRlKHtcbiAgICBsYXllckRhdGE6IHtkYXRhOiBjbHVzdGVyc31cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFN1YkxheWVyUmFkaXVzKFxuICBkaW1lbnNpb25TdGF0ZToge3NjYWxlRnVuYzogKHY6IG51bWJlcikgPT4gbnVtYmVyfSxcbiAgZGltZW5zaW9uOiBEaW1lbnNpb25UeXBlLFxuICBsYXllclByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4pIHtcbiAgcmV0dXJuIChjZWxsOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IG51bWJlciA9PiB7XG4gICAgY29uc3Qge2dldFJhZGl1c1ZhbHVlfSA9IGxheWVyUHJvcHM7XG4gICAgY29uc3Qge3NjYWxlRnVuY30gPSBkaW1lbnNpb25TdGF0ZTtcbiAgICByZXR1cm4gc2NhbGVGdW5jKGdldFJhZGl1c1ZhbHVlKGNlbGwpKTtcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IGNsdXN0ZXJBZ2dyZWdhdGlvbjogQWdncmVnYXRpb25UeXBlID0ge1xuICBrZXk6ICdwb3NpdGlvbicsXG4gIHVwZGF0ZVN0ZXBzOiBbXG4gICAge1xuICAgICAga2V5OiAnZ2VvanNvbicsXG4gICAgICB0cmlnZ2Vyczoge1xuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIHByb3A6ICdnZXRQb3NpdGlvbicsXG4gICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ2dldFBvc2l0aW9uJ1xuICAgICAgICB9LFxuICAgICAgICBmaWx0ZXJEYXRhOiB7XG4gICAgICAgICAgcHJvcDogJ2ZpbHRlckRhdGEnLFxuICAgICAgICAgIHVwZGF0ZVRyaWdnZXI6ICdmaWx0ZXJEYXRhJ1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdXBkYXRlcjogcHJvY2Vzc0dlb0pTT05cbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ2NsdXN0ZXJpbmcnLFxuICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgY2x1c3RlclJhZGl1czoge1xuICAgICAgICAgIHByb3A6ICdjbHVzdGVyUmFkaXVzJ1xuICAgICAgICB9LFxuICAgICAgICB6b29tOiB7XG4gICAgICAgICAgcHJvcDogJ3pvb20nXG4gICAgICAgIH0sXG4gICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgcHJvcDogJ3dpZHRoJ1xuICAgICAgICB9LFxuICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICBwcm9wOiAnaGVpZ2h0J1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdXBkYXRlcjogZ2V0Q2x1c3RlcnNcbiAgICB9XG4gIF1cbn07XG5cbmZ1bmN0aW9uIGdldFJhZGl1c1ZhbHVlRG9tYWluKHRoaXM6IENQVUFnZ3JlZ2F0b3IsIHN0ZXAsIHByb3BzLCBkaW1lbnNpb25VcGRhdGVyKSB7XG4gIGNvbnN0IHtrZXl9ID0gZGltZW5zaW9uVXBkYXRlcjtcbiAgY29uc3Qge2dldFJhZGl1c1ZhbHVlfSA9IHByb3BzO1xuICBjb25zdCB7bGF5ZXJEYXRhfSA9IHRoaXMuc3RhdGU7XG5cbiAgY29uc3QgdmFsdWVEb21haW4gPSBbMCwgbWF4KGxheWVyRGF0YS5kYXRhIGFzIHVua25vd24gYXMgbnVtYmVyW10sIGdldFJhZGl1c1ZhbHVlKV07XG4gIHRoaXMuX3NldERpbWVuc2lvblN0YXRlKGtleSwge3ZhbHVlRG9tYWlufSk7XG59XG5cbmNvbnN0IGNsdXN0ZXJMYXllckRpbWVuc2lvbnM6IFtEaW1lbnNpb25UeXBlPFJHQkFDb2xvcj4sIERpbWVuc2lvblR5cGU8bnVtYmVyPl0gPSBbXG4gIGRlZmF1bHRDb2xvckRpbWVuc2lvbixcbiAge1xuICAgIGtleTogJ3JhZGl1cycsXG4gICAgYWNjZXNzb3I6ICdnZXRSYWRpdXMnLFxuICAgIG51bGxWYWx1ZTogMCxcbiAgICB1cGRhdGVTdGVwczogW1xuICAgICAge1xuICAgICAgICBrZXk6ICdnZXREb21haW4nLFxuICAgICAgICB0cmlnZ2Vyczoge1xuICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICBwcm9wOiAnZ2V0UmFkaXVzVmFsdWUnLFxuICAgICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ2dldFJhZGl1c1ZhbHVlJ1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgdXBkYXRlcjogZ2V0UmFkaXVzVmFsdWVEb21haW5cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ2dldFNjYWxlRnVuYycsXG4gICAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgICAgZG9tYWluOiB7cHJvcDogJ3JhZGl1c0RvbWFpbid9LFxuICAgICAgICAgIHJhbmdlOiB7cHJvcDogJ3JhZGl1c1JhbmdlJ30sXG4gICAgICAgICAgc2NhbGVUeXBlOiB7cHJvcDogJ3JhZGl1c1NjYWxlVHlwZSd9XG4gICAgICAgIH0sXG4gICAgICAgIHVwZGF0ZXI6IGdldERpbWVuc2lvblNjYWxlXG4gICAgICB9XG4gICAgXSxcbiAgICBnZXRTdWJMYXllckFjY2Vzc29yOiBnZXRTdWJMYXllclJhZGl1cyxcbiAgICBnZXRQaWNraW5nSW5mbzogKGRpbWVuc2lvblN0YXRlLCBjZWxsLCBsYXllclByb3BzKSA9PiB7XG4gICAgICBjb25zdCByYWRpdXNWYWx1ZSA9IGxheWVyUHJvcHMuZ2V0UmFkaXVzVmFsdWUoY2VsbCk7XG4gICAgICBjb25zdCB7c2NhbGVGdW5jfSA9IGRpbWVuc2lvblN0YXRlO1xuICAgICAgY29uc3Qgc2NhbGVkUmFkaXVzVmFsdWUgPSBzY2FsZUZ1bmMgPyBzY2FsZUZ1bmMocmFkaXVzVmFsdWUpIDogcmFkaXVzVmFsdWU7XG5cbiAgICAgIHJldHVybiB7cmFkaXVzVmFsdWUsIHNjYWxlZFJhZGl1c1ZhbHVlfTtcbiAgICB9XG4gIH1cbl07XG5cbmNvbnN0IGRlZmF1bHRQcm9wcyA9IHtcbiAgY2x1c3RlclJhZGl1czogZGVmYXVsdFJhZGl1cyxcbiAgY29sb3JEb21haW46IG51bGwsXG4gIGNvbG9yUmFuZ2U6IERFRkFVTFRfQ09MT1JfUkFOR0UsXG4gIGNvbG9yU2NhbGVUeXBlOiBTQ0FMRV9UWVBFUy5xdWFudGl6ZSxcbiAgcmFkaXVzU2NhbGVUeXBlOiBTQ0FMRV9UWVBFUy5zcXJ0LFxuICByYWRpdXNSYW5nZTogZGVmYXVsdFJhZGl1c1JhbmdlLFxuICBnZXRQb3NpdGlvbjoge3R5cGU6ICdhY2Nlc3NvcicsIHZhbHVlOiB4ID0+IHgucG9zaXRpb259LFxuICBnZXRDb2xvclZhbHVlOiB7dHlwZTogJ2FjY2Vzc29yJywgdmFsdWU6IGRlZmF1bHRHZXRDb2xvclZhbHVlfSxcbiAgZ2V0UmFkaXVzVmFsdWU6IHt0eXBlOiAnYWNjZXNzb3InLCB2YWx1ZTogZGVmYXVsdEdldFJhZGl1c1ZhbHVlfVxufTtcblxuaW50ZXJmYWNlIENsdXN0ZXJMYXllclN0YXRlIHtcbiAgY3B1QWdncmVnYXRvcjogQ1BVQWdncmVnYXRvcjtcbiAgYWdncmVnYXRvclN0YXRlOiBDUFVBZ2dyZWdhdG9yWydzdGF0ZSddO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDbHVzdGVyTGF5ZXIgZXh0ZW5kcyBDb21wb3NpdGVMYXllciB7XG4gIGluaXRpYWxpemVTdGF0ZSgpIHtcbiAgICBjb25zdCBjcHVBZ2dyZWdhdG9yID0gbmV3IENQVUFnZ3JlZ2F0b3Ioe1xuICAgICAgYWdncmVnYXRpb246IGNsdXN0ZXJBZ2dyZWdhdGlvbixcbiAgICAgIGRpbWVuc2lvbnM6IGNsdXN0ZXJMYXllckRpbWVuc2lvbnNcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBjcHVBZ2dyZWdhdG9yLFxuICAgICAgYWdncmVnYXRvclN0YXRlOiBjcHVBZ2dyZWdhdG9yLnN0YXRlXG4gICAgfTtcbiAgfVxuXG4gIHVwZGF0ZVN0YXRlKHtcbiAgICBvbGRQcm9wcyxcbiAgICBwcm9wcyxcbiAgICBjaGFuZ2VGbGFnc1xuICB9OiB7XG4gICAgb2xkUHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgcHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgY2hhbmdlRmxhZ3M6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIH0pIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGFnZ3JlZ2F0b3JTdGF0ZTogKHRoaXMuc3RhdGUgYXMgdW5rbm93biBhcyBDbHVzdGVyTGF5ZXJTdGF0ZSkuY3B1QWdncmVnYXRvci51cGRhdGVTdGF0ZShcbiAgICAgICAge29sZFByb3BzLCBwcm9wcywgY2hhbmdlRmxhZ3N9LFxuICAgICAgICB7XG4gICAgICAgICAgdmlld3BvcnQ6IHRoaXMuY29udGV4dC52aWV3cG9ydCxcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHByb3BzIHBhc3NlZCBmb3IgaW50ZXJuYWwgY2FsY3VsYXRpb25cbiAgICAgICAgICBudW1JbnN0YW5jZXM6IHRoaXMuZ2V0TnVtSW5zdGFuY2VzKHByb3BzKVxuICAgICAgICB9XG4gICAgICApXG4gICAgfSk7XG4gIH1cblxuICBnZXRQaWNraW5nSW5mbyh7aW5mb306IEdldFBpY2tpbmdJbmZvUGFyYW1zKTogUGlja2luZ0luZm8ge1xuICAgIGNvbnN0IG9iaiA9ICh0aGlzLnN0YXRlIGFzIHVua25vd24gYXMgQ2x1c3RlckxheWVyU3RhdGUpLmNwdUFnZ3JlZ2F0b3IuZ2V0UGlja2luZ0luZm8oXG4gICAgICB7aW5mb30sXG4gICAgICB0aGlzLnByb3BzXG4gICAgKTtcbiAgICBpZiAob2JqPy5vYmplY3QpIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIGNvbnN0IGRpc3RhbmNlU2NhbGUgPSBnZXREaXN0YW5jZVNjYWxlcyh0aGlzLmNvbnRleHQudmlld3BvcnQpO1xuICAgICAgY29uc3QgbWV0ZXJzUGVyUGl4ZWwgPSBkaXN0YW5jZVNjYWxlLm1ldGVyc1BlclBpeGVsWzBdO1xuICAgICAgb2JqLm9iamVjdC5zY2FsZWRSYWRpdXNWYWx1ZSA9IG9iai5vYmplY3Quc2NhbGVkUmFkaXVzVmFsdWUgKiBtZXRlcnNQZXJQaXhlbDtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqIGFzIFBpY2tpbmdJbmZvO1xuICB9XG5cbiAgX2dldFN1YmxheWVyVXBkYXRlVHJpZ2dlcnMoKSB7XG4gICAgcmV0dXJuICh0aGlzLnN0YXRlIGFzIHVua25vd24gYXMgQ2x1c3RlckxheWVyU3RhdGUpLmNwdUFnZ3JlZ2F0b3IuZ2V0VXBkYXRlVHJpZ2dlcnModGhpcy5wcm9wcyk7XG4gIH1cblxuICBfZ2V0U3ViTGF5ZXJBY2Nlc3NvcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGdldFJhZGl1czogKHRoaXMuc3RhdGUgYXMgdW5rbm93biBhcyBDbHVzdGVyTGF5ZXJTdGF0ZSkuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcihcbiAgICAgICAgJ3JhZGl1cycsXG4gICAgICAgIHRoaXMucHJvcHNcbiAgICAgICksXG4gICAgICBnZXRGaWxsQ29sb3I6ICh0aGlzLnN0YXRlIGFzIHVua25vd24gYXMgQ2x1c3RlckxheWVyU3RhdGUpLmNwdUFnZ3JlZ2F0b3IuZ2V0QWNjZXNzb3IoXG4gICAgICAgICdmaWxsQ29sb3InLFxuICAgICAgICB0aGlzLnByb3BzXG4gICAgICApXG4gICAgfTtcbiAgfVxuXG4gIHJlbmRlckxheWVycygpIHtcbiAgICBjb25zdCB7aWQsIHJhZGl1c1NjYWxlLCB2aXNpYmxlLCBvcGFjaXR5LCBwaWNrYWJsZSwgYXV0b0hpZ2hsaWdodCwgaGlnaGxpZ2h0Q29sb3J9ID0gdGhpc1xuICAgICAgLnByb3BzIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgY29uc3Qge2NwdUFnZ3JlZ2F0b3J9ID0gdGhpcy5zdGF0ZSBhcyB1bmtub3duIGFzIENsdXN0ZXJMYXllclN0YXRlO1xuICAgIGNvbnN0IHVwZGF0ZVRyaWdnZXJzID0gdGhpcy5fZ2V0U3VibGF5ZXJVcGRhdGVUcmlnZ2VycygpO1xuICAgIGNvbnN0IGFjY2Vzc29ycyA9IHRoaXMuX2dldFN1YkxheWVyQWNjZXNzb3JzKCk7XG5cbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgY29uc3QgZGlzdGFuY2VTY2FsZSA9IGdldERpc3RhbmNlU2NhbGVzKHRoaXMuY29udGV4dC52aWV3cG9ydCk7XG4gICAgY29uc3QgbWV0ZXJzUGVyUGl4ZWwgPSBkaXN0YW5jZVNjYWxlLm1ldGVyc1BlclBpeGVsWzBdO1xuXG4gICAgLy8gcmV0dXJuIHByb3BzIHRvIHRoZSBzdWJsYXllciBjb25zdHJ1Y3RvclxuICAgIHJldHVybiBuZXcgU2NhdHRlcnBsb3RMYXllcih7XG4gICAgICBpZDogYCR7aWR9LWNsdXN0ZXJgLFxuICAgICAgZGF0YTogY3B1QWdncmVnYXRvci5zdGF0ZS5sYXllckRhdGEuZGF0YSxcbiAgICAgIHJhZGl1c1NjYWxlOiBtZXRlcnNQZXJQaXhlbCAqIHJhZGl1c1NjYWxlLFxuICAgICAgdmlzaWJsZSxcbiAgICAgIG9wYWNpdHksXG4gICAgICBwaWNrYWJsZSxcbiAgICAgIGF1dG9IaWdobGlnaHQsXG4gICAgICBoaWdobGlnaHRDb2xvcixcbiAgICAgIHVwZGF0ZVRyaWdnZXJzLFxuICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICBkZXB0aE1hc2s6IGZhbHNlXG4gICAgICB9LFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfSk7XG4gIH1cbn1cblxuQ2x1c3RlckxheWVyLmxheWVyTmFtZSA9ICdDbHVzdGVyTGF5ZXInO1xuQ2x1c3RlckxheWVyLmRlZmF1bHRQcm9wcyA9IGRlZmF1bHRQcm9wcztcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxLQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7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