UNPKG

kepler.gl

Version:

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

323 lines (281 loc) 31.9 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); 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 _layers = require("@deck.gl/layers"); var _aggregationLayers = require("@deck.gl/aggregation-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 _colorRanges = require("../../constants/color-ranges"); var _layerFactory = require("../../layers/layer-factory"); var _defaultSettings = require("../../constants/default-settings"); var _clusterUtils = _interopRequireWildcard(require("../layer-utils/cluster-utils")); 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 defaultRadius = _layerFactory.LAYER_VIS_CONFIGS.clusterRadius.defaultValue; var defaultRadiusRange = _layerFactory.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; }; 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 }); } function getClusters(step, props, aggregation, _ref2) { 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.clustersAtZoom({ bbox: bbox, clusterRadius: clusterRadius, geoJSON: geoJSON, zoom: zoom }); 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 = { 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 }] }; exports.clusterAggregation = clusterAggregation; 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); return { radiusValue: radiusValue }; } }]; var defaultProps = { clusterRadius: defaultRadius, colorDomain: null, colorRange: _colorRanges.DefaultColorRange, colorScaleType: _defaultSettings.SCALE_TYPES.quantize, radiusScaleType: _defaultSettings.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 = /*#__PURE__*/ function (_AggregationLayer) { (0, _inherits2["default"])(ClusterLayer, _AggregationLayer); function ClusterLayer() { (0, _classCallCheck2["default"])(this, ClusterLayer); return (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(ClusterLayer).apply(this, arguments)); } (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 }; var attributeManager = this.getAttributeManager(); attributeManager.add({ positions: { size: 3, accessor: 'getPosition' } }); } }, { key: "updateState", value: function updateState(_ref3) { var oldProps = _ref3.oldProps, props = _ref3.props, changeFlags = _ref3.changeFlags; this.setState({ // make a copy of the internal state of cpuAggregator for testing aggregatorState: this.state.cpuAggregator.updateState({ oldProps: oldProps, props: props, changeFlags: changeFlags }, { viewport: this.context.viewport, attributes: this.getAttributes(), numInstances: this.getNumInstances(props) }) }); } }, { key: "getPickingInfo", value: function getPickingInfo(_ref4) { var info = _ref4.info; return this.state.cpuAggregator.getPickingInfo({ info: info }, this.props); } }, { 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() { // for subclassing, override this method to return // customized sub layer props var _this$props = this.props, id = _this$props.id, radiusScale = _this$props.radiusScale; var cpuAggregator = this.state.cpuAggregator; // base layer props var _this$props2 = this.props, opacity = _this$props2.opacity, pickable = _this$props2.pickable, autoHighlight = _this$props2.autoHighlight, highlightColor = _this$props2.highlightColor; var updateTriggers = this._getSublayerUpdateTriggers(); var accessors = this._getSubLayerAccessors(); 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, opacity: opacity, pickable: pickable, autoHighlight: autoHighlight, highlightColor: highlightColor, updateTriggers: updateTriggers }, accessors)); } }]); return ClusterLayer; }(_aggregationLayers._AggregationLayer); exports["default"] = ClusterLayer; ClusterLayer.layerName = 'ClusterLayer'; ClusterLayer.defaultProps = defaultProps; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNrZ2wtbGF5ZXJzL2NsdXN0ZXItbGF5ZXIvY2x1c3Rlci1sYXllci5qcyJdLCJuYW1lcyI6WyJkZWZhdWx0UmFkaXVzIiwiTEFZRVJfVklTX0NPTkZJR1MiLCJjbHVzdGVyUmFkaXVzIiwiZGVmYXVsdFZhbHVlIiwiZGVmYXVsdFJhZGl1c1JhbmdlIiwiY2x1c3RlclJhZGl1c1JhbmdlIiwiZGVmYXVsdEdldENvbG9yVmFsdWUiLCJwb2ludHMiLCJsZW5ndGgiLCJkZWZhdWx0R2V0UmFkaXVzVmFsdWUiLCJjZWxsIiwiZmlsdGVyZWRQb2ludHMiLCJwcm9jZXNzR2VvSlNPTiIsInN0ZXAiLCJwcm9wcyIsImFnZ3JlZ2F0aW9uIiwidmlld3BvcnQiLCJkYXRhIiwiZ2V0UG9zaXRpb24iLCJmaWx0ZXJEYXRhIiwiZ2VvSlNPTiIsImNsdXN0ZXJCdWlsZGVyIiwiQ2x1c3RlckJ1aWxkZXIiLCJzZXRTdGF0ZSIsImdldENsdXN0ZXJzIiwic3RhdGUiLCJ6b29tIiwid2lkdGgiLCJoZWlnaHQiLCJsb25naXR1ZGUiLCJsYXRpdHVkZSIsImJib3giLCJnZW9WaWV3cG9ydCIsImJvdW5kcyIsImNsdXN0ZXJzIiwiY2x1c3RlcnNBdFpvb20iLCJsYXllckRhdGEiLCJnZXRTdWJMYXllclJhZGl1cyIsImRpbWVuc2lvblN0YXRlIiwiZGltZW5zaW9uIiwibGF5ZXJQcm9wcyIsImdldFJhZGl1c1ZhbHVlIiwic2NhbGVGdW5jIiwiY2x1c3RlckFnZ3JlZ2F0aW9uIiwia2V5IiwidXBkYXRlU3RlcHMiLCJ0cmlnZ2VycyIsInBvc2l0aW9uIiwicHJvcCIsInVwZGF0ZVRyaWdnZXIiLCJ1cGRhdGVyIiwiZ2V0UmFkaXVzVmFsdWVEb21haW4iLCJkaW1lbnNpb25VcGRhdGVyIiwidmFsdWVEb21haW4iLCJfc2V0RGltZW5zaW9uU3RhdGUiLCJjbHVzdGVyTGF5ZXJEaW1lbnNpb25zIiwiZGVmYXVsdENvbG9yRGltZW5zaW9uIiwiYWNjZXNzb3IiLCJudWxsVmFsdWUiLCJ2YWx1ZSIsImRvbWFpbiIsInJhbmdlIiwic2NhbGVUeXBlIiwiZ2V0RGltZW5zaW9uU2NhbGUiLCJnZXRTdWJMYXllckFjY2Vzc29yIiwiZ2V0UGlja2luZ0luZm8iLCJyYWRpdXNWYWx1ZSIsImRlZmF1bHRQcm9wcyIsImNvbG9yRG9tYWluIiwiY29sb3JSYW5nZSIsIkRlZmF1bHRDb2xvclJhbmdlIiwiY29sb3JTY2FsZVR5cGUiLCJTQ0FMRV9UWVBFUyIsInF1YW50aXplIiwicmFkaXVzU2NhbGVUeXBlIiwic3FydCIsInJhZGl1c1JhbmdlIiwidHlwZSIsIngiLCJnZXRDb2xvclZhbHVlIiwiQ2x1c3RlckxheWVyIiwiY3B1QWdncmVnYXRvciIsIkNQVUFnZ3JlZ2F0b3IiLCJkaW1lbnNpb25zIiwiYWdncmVnYXRvclN0YXRlIiwiYXR0cmlidXRlTWFuYWdlciIsImdldEF0dHJpYnV0ZU1hbmFnZXIiLCJhZGQiLCJwb3NpdGlvbnMiLCJzaXplIiwib2xkUHJvcHMiLCJjaGFuZ2VGbGFncyIsInVwZGF0ZVN0YXRlIiwiY29udGV4dCIsImF0dHJpYnV0ZXMiLCJnZXRBdHRyaWJ1dGVzIiwibnVtSW5zdGFuY2VzIiwiZ2V0TnVtSW5zdGFuY2VzIiwiaW5mbyIsImdldFVwZGF0ZVRyaWdnZXJzIiwiZ2V0UmFkaXVzIiwiZ2V0QWNjZXNzb3IiLCJnZXRGaWxsQ29sb3IiLCJpZCIsInJhZGl1c1NjYWxlIiwib3BhY2l0eSIsInBpY2thYmxlIiwiYXV0b0hpZ2hsaWdodCIsImhpZ2hsaWdodENvbG9yIiwidXBkYXRlVHJpZ2dlcnMiLCJfZ2V0U3VibGF5ZXJVcGRhdGVUcmlnZ2VycyIsImFjY2Vzc29ycyIsIl9nZXRTdWJMYXllckFjY2Vzc29ycyIsImRpc3RhbmNlU2NhbGUiLCJtZXRlcnNQZXJQaXhlbCIsIlNjYXR0ZXJwbG90TGF5ZXIiLCJBZ2dyZWdhdGlvbkxheWVyIiwibGF5ZXJOYW1lIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFD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QSxRQUxLO0FBTUxDLFFBQUFBLGFBQWEsRUFBYkEsYUFOSztBQU9MQyxRQUFBQSxjQUFjLEVBQWRBLGNBUEs7QUFRTEMsUUFBQUEsY0FBYyxFQUFkQTtBQVJLLFNBU0ZFLFNBVEUsRUFBUDtBQVdEOzs7RUF4RXVDSyxvQzs7O0FBMkUxQ3BDLFlBQVksQ0FBQ3FDLFNBQWIsR0FBeUIsY0FBekI7QUFDQXJDLFlBQVksQ0FBQ2IsWUFBYixHQUE0QkEsWUFBNUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjAgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQge1NjYXR0ZXJwbG90TGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycyc7XG5pbXBvcnQge19BZ2dyZWdhdGlvbkxheWVyIGFzIEFnZ3JlZ2F0aW9uTGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2FnZ3JlZ2F0aW9uLWxheWVycyc7XG5cbmltcG9ydCBnZW9WaWV3cG9ydCBmcm9tICdAbWFwYm94L2dlby12aWV3cG9ydCc7XG5pbXBvcnQgQ1BVQWdncmVnYXRvciwge1xuICBkZWZhdWx0Q29sb3JEaW1lbnNpb24sXG4gIGdldERpbWVuc2lvblNjYWxlXG59IGZyb20gJy4uL2xheWVyLXV0aWxzL2NwdS1hZ2dyZWdhdG9yJztcbmltcG9ydCB7Z2V0RGlzdGFuY2VTY2FsZXN9IGZyb20gJ3ZpZXdwb3J0LW1lcmNhdG9yLXByb2plY3QnO1xuaW1wb3J0IHttYXh9IGZyb20gJ2QzLWFycmF5JztcblxuaW1wb3J0IHtEZWZhdWx0Q29sb3JSYW5nZX0gZnJvbSAnY29uc3RhbnRzL2NvbG9yLXJhbmdlcyc7XG5pbXBvcnQge0xBWUVSX1ZJU19DT05GSUdTfSBmcm9tICdsYXllcnMvbGF5ZXItZmFjdG9yeSc7XG5pbXBvcnQge1NDQUxFX1RZUEVTfSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbmltcG9ydCBDbHVzdGVyQnVpbGRlciwge2dldEdlb0pTT059IGZyb20gJy4uL2xheWVyLXV0aWxzL2NsdXN0ZXItdXRpbHMnO1xuXG5jb25zdCBkZWZhdWx0UmFkaXVzID0gTEFZRVJfVklTX0NPTkZJR1MuY2x1c3RlclJhZGl1cy5kZWZhdWx0VmFsdWU7XG5jb25zdCBkZWZhdWx0UmFkaXVzUmFuZ2UgPSBMQVlFUl9WSVNfQ09ORklHUy5jbHVzdGVyUmFkaXVzUmFuZ2UuZGVmYXVsdFZhbHVlO1xuXG5jb25zdCBkZWZhdWx0R2V0Q29sb3JWYWx1ZSA9IHBvaW50cyA9PiBwb2ludHMubGVuZ3RoO1xuY29uc3QgZGVmYXVsdEdldFJhZGl1c1ZhbHVlID0gY2VsbCA9PlxuICBjZWxsLmZpbHRlcmVkUG9pbnRzID8gY2VsbC5maWx0ZXJlZFBvaW50cy5sZW5ndGggOiBjZWxsLnBvaW50cy5sZW5ndGg7XG5cbmZ1bmN0aW9uIHByb2Nlc3NHZW9KU09OKHN0ZXAsIHByb3BzLCBhZ2dyZWdhdGlvbiwge3ZpZXdwb3J0fSkge1xuICBjb25zdCB7ZGF0YSwgZ2V0UG9zaXRpb24sIGZpbHRlckRhdGF9ID0gcHJvcHM7XG4gIGNvbnN0IGdlb0pTT04gPSBnZXRHZW9KU09OKGRhdGEsIGdldFBvc2l0aW9uLCBmaWx0ZXJEYXRhKTtcbiAgY29uc3QgY2x1c3RlckJ1aWxkZXIgPSBuZXcgQ2x1c3RlckJ1aWxkZXIoKTtcblxuICB0aGlzLnNldFN0YXRlKHtnZW9KU09OLCBjbHVzdGVyQnVpbGRlcn0pO1xufVxuXG5mdW5jdGlvbiBnZXRDbHVzdGVycyhzdGVwLCBwcm9wcywgYWdncmVnYXRpb24sIHt2aWV3cG9ydH0pIHtcbiAgY29uc3Qge2dlb0pTT04sIGNsdXN0ZXJCdWlsZGVyfSA9IHRoaXMuc3RhdGU7XG4gIGNvbnN0IHtjbHVzdGVyUmFkaXVzLCB6b29tLCB3aWR0aCwgaGVpZ2h0fSA9IHByb3BzO1xuICBjb25zdCB7bG9uZ2l0dWRlLCBsYXRpdHVkZX0gPSB2aWV3cG9ydDtcblxuICAvLyB6b29tIG5lZWRzIHRvIGJlIGFuIGludGVnZXIgZm9yIHRoZSBkaWZmZXJlbnQgbWFwIHV0aWxzLiBBbHNvIGhlbHBzIHdpdGggY2FjaGUga2V5LlxuICBjb25zdCBiYm94ID0gZ2VvVmlld3BvcnQuYm91bmRzKFtsb25naXR1ZGUsIGxhdGl0dWRlXSwgem9vbSwgW3dpZHRoLCBoZWlnaHRdKTtcbiAgY29uc3QgY2x1c3RlcnMgPSBjbHVzdGVyQnVpbGRlci5jbHVzdGVyc0F0Wm9vbSh7YmJveCwgY2x1c3RlclJhZGl1cywgZ2VvSlNPTiwgem9vbX0pO1xuXG4gIHRoaXMuc2V0U3RhdGUoe1xuICAgIGxheWVyRGF0YToge2RhdGE6IGNsdXN0ZXJzfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3ViTGF5ZXJSYWRpdXMoZGltZW5zaW9uU3RhdGUsIGRpbWVuc2lvbiwgbGF5ZXJQcm9wcykge1xuICByZXR1cm4gY2VsbCA9PiB7XG4gICAgY29uc3Qge2dldFJhZGl1c1ZhbHVlfSA9IGxheWVyUHJvcHM7XG4gICAgY29uc3Qge3NjYWxlRnVuY30gPSBkaW1lbnNpb25TdGF0ZTtcbiAgICByZXR1cm4gc2NhbGVGdW5jKGdldFJhZGl1c1ZhbHVlKGNlbGwpKTtcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IGNsdXN0ZXJBZ2dyZWdhdGlvbiA9IHtcbiAga2V5OiAncG9zaXRpb24nLFxuICB1cGRhdGVTdGVwczogW1xuICAgIHtcbiAgICAgIGtleTogJ2dlb2pzb24nLFxuICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBwcm9wOiAnZ2V0UG9zaXRpb24nLFxuICAgICAgICAgIHVwZGF0ZVRyaWdnZXI6ICdnZXRQb3NpdGlvbidcbiAgICAgICAgfSxcbiAgICAgICAgZmlsdGVyRGF0YToge1xuICAgICAgICAgIHByb3A6ICdmaWx0ZXJEYXRhJyxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZmlsdGVyRGF0YSdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHVwZGF0ZXI6IHByb2Nlc3NHZW9KU09OXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdjbHVzdGVyaW5nJyxcbiAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgIGNsdXN0ZXJSYWRpdXM6IHtcbiAgICAgICAgICBwcm9wOiAnY2x1c3RlclJhZGl1cydcbiAgICAgICAgfSxcbiAgICAgICAgem9vbToge1xuICAgICAgICAgIHByb3A6ICd6b29tJ1xuICAgICAgICB9LFxuICAgICAgICB3aWR0aDoge1xuICAgICAgICAgIHByb3A6ICd3aWR0aCdcbiAgICAgICAgfSxcbiAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgcHJvcDogJ2hlaWdodCdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHVwZGF0ZXI6IGdldENsdXN0ZXJzXG4gICAgfVxuICBdXG59O1xuXG5mdW5jdGlvbiBnZXRSYWRpdXNWYWx1ZURvbWFpbihzdGVwLCBwcm9wcywgZGltZW5zaW9uVXBkYXRlcikge1xuICBjb25zdCB7a2V5fSA9IGRpbWVuc2lvblVwZGF0ZXI7XG4gIGNvbnN0IHtnZXRSYWRpdXNWYWx1ZX0gPSBwcm9wcztcbiAgY29uc3Qge2xheWVyRGF0YX0gPSB0aGlzLnN0YXRlO1xuXG4gIGNvbnN0IHZhbHVlRG9tYWluID0gWzAsIG1heChsYXllckRhdGEuZGF0YSwgZ2V0UmFkaXVzVmFsdWUpXTtcbiAgdGhpcy5fc2V0RGltZW5zaW9uU3RhdGUoa2V5LCB7dmFsdWVEb21haW59KTtcbn1cblxuY29uc3QgY2x1c3RlckxheWVyRGltZW5zaW9ucyA9IFtcbiAgZGVmYXVsdENvbG9yRGltZW5zaW9uLFxuICB7XG4gICAga2V5OiAncmFkaXVzJyxcbiAgICBhY2Nlc3NvcjogJ2dldFJhZGl1cycsXG4gICAgbnVsbFZhbHVlOiAwLFxuICAgIHVwZGF0ZVN0ZXBzOiBbXG4gICAgICB7XG4gICAgICAgIGtleTogJ2dldERvbWFpbicsXG4gICAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIHByb3A6ICdnZXRSYWRpdXNWYWx1ZScsXG4gICAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZ2V0UmFkaXVzVmFsdWUnXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB1cGRhdGVyOiBnZXRSYWRpdXNWYWx1ZURvbWFpblxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAga2V5OiAnZ2V0U2NhbGVGdW5jJyxcbiAgICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgICBkb21haW46IHtwcm9wOiAncmFkaXVzRG9tYWluJ30sXG4gICAgICAgICAgcmFuZ2U6IHtwcm9wOiAncmFkaXVzUmFuZ2UnfSxcbiAgICAgICAgICBzY2FsZVR5cGU6IHtwcm9wOiAncmFkaXVzU2NhbGVUeXBlJ31cbiAgICAgICAgfSxcbiAgICAgICAgdXBkYXRlcjogZ2V0RGltZW5zaW9uU2NhbGVcbiAgICAgIH1cbiAgICBdLFxuICAgIGdldFN1YkxheWVyQWNjZXNzb3I6IGdldFN1YkxheWVyUmFkaXVzLFxuICAgIGdldFBpY2tpbmdJbmZvOiAoZGltZW5zaW9uU3RhdGUsIGNlbGwsIGxheWVyUHJvcHMpID0+IHtcbiAgICAgIGNvbnN0IHJhZGl1c1ZhbHVlID0gbGF5ZXJQcm9wcy5nZXRSYWRpdXNWYWx1ZShjZWxsKTtcbiAgICAgIHJldHVybiB7cmFkaXVzVmFsdWV9O1xuICAgIH1cbiAgfVxuXTtcblxuY29uc3QgZGVmYXVsdFByb3BzID0ge1xuICBjbHVzdGVyUmFkaXVzOiBkZWZhdWx0UmFkaXVzLFxuICBjb2xvckRvbWFpbjogbnVsbCxcbiAgY29sb3JSYW5nZTogRGVmYXVsdENvbG9yUmFuZ2UsXG4gIGNvbG9yU2NhbGVUeXBlOiBTQ0FMRV9UWVBFUy5xdWFudGl6ZSxcbiAgcmFkaXVzU2NhbGVUeXBlOiBTQ0FMRV9UWVBFUy5zcXJ0LFxuICByYWRpdXNSYW5nZTogZGVmYXVsdFJhZGl1c1JhbmdlLFxuICBnZXRQb3NpdGlvbjoge3R5cGU6ICdhY2Nlc3NvcicsIHZhbHVlOiB4ID0+IHgucG9zaXRpb259LFxuICBnZXRDb2xvclZhbHVlOiB7dHlwZTogJ2FjY2Vzc29yJywgdmFsdWU6IGRlZmF1bHRHZXRDb2xvclZhbHVlfSxcbiAgZ2V0UmFkaXVzVmFsdWU6IHt0eXBlOiAnYWNjZXNzb3InLCB2YWx1ZTogZGVmYXVsdEdldFJhZGl1c1ZhbHVlfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2x1c3RlckxheWVyIGV4dGVuZHMgQWdncmVnYXRpb25MYXllciB7XG4gIGluaXRpYWxpemVTdGF0ZSgpIHtcbiAgICBjb25zdCBjcHVBZ2dyZWdhdG9yID0gbmV3IENQVUFnZ3JlZ2F0b3Ioe1xuICAgICAgYWdncmVnYXRpb246IGNsdXN0ZXJBZ2dyZWdhdGlvbixcbiAgICAgIGRpbWVuc2lvbnM6IGNsdXN0ZXJMYXllckRpbWVuc2lvbnNcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBjcHVBZ2dyZWdhdG9yLFxuICAgICAgYWdncmVnYXRvclN0YXRlOiBjcHVBZ2dyZWdhdG9yLnN0YXRlXG4gICAgfTtcbiAgICBjb25zdCBhdHRyaWJ1dGVNYW5hZ2VyID0gdGhpcy5nZXRBdHRyaWJ1dGVNYW5hZ2VyKCk7XG4gICAgYXR0cmlidXRlTWFuYWdlci5hZGQoe1xuICAgICAgcG9zaXRpb25zOiB7c2l6ZTogMywgYWNjZXNzb3I6ICdnZXRQb3NpdGlvbid9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVTdGF0ZSh7b2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFnc30pIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIG1ha2UgYSBjb3B5IG9mIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiBjcHVBZ2dyZWdhdG9yIGZvciB0ZXN0aW5nXG4gICAgICBhZ2dyZWdhdG9yU3RhdGU6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci51cGRhdGVTdGF0ZShcbiAgICAgICAge29sZFByb3BzLCBwcm9wcywgY2hhbmdlRmxhZ3N9LFxuICAgICAgICB7XG4gICAgICAgICAgdmlld3BvcnQ6IHRoaXMuY29udGV4dC52aWV3cG9ydCxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB0aGlzLmdldEF0dHJpYnV0ZXMoKSxcbiAgICAgICAgICBudW1JbnN0YW5jZXM6IHRoaXMuZ2V0TnVtSW5zdGFuY2VzKHByb3BzKVxuICAgICAgICB9XG4gICAgICApXG4gICAgfSk7XG4gIH1cblxuICBnZXRQaWNraW5nSW5mbyh7aW5mb30pIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5jcHVBZ2dyZWdhdG9yLmdldFBpY2tpbmdJbmZvKHtpbmZvfSwgdGhpcy5wcm9wcyk7XG4gIH1cblxuICBfZ2V0U3VibGF5ZXJVcGRhdGVUcmlnZ2VycygpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5jcHVBZ2dyZWdhdG9yLmdldFVwZGF0ZVRyaWdnZXJzKHRoaXMucHJvcHMpO1xuICB9XG5cbiAgX2dldFN1YkxheWVyQWNjZXNzb3JzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRSYWRpdXM6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcigncmFkaXVzJywgdGhpcy5wcm9wcyksXG4gICAgICBnZXRGaWxsQ29sb3I6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcignZmlsbENvbG9yJywgdGhpcy5wcm9wcylcbiAgICB9O1xuICB9XG5cbiAgcmVuZGVyTGF5ZXJzKCkge1xuICAgIC8vIGZvciBzdWJjbGFzc2luZywgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuXG4gICAgLy8gY3VzdG9taXplZCBzdWIgbGF5ZXIgcHJvcHNcbiAgICBjb25zdCB7aWQsIHJhZGl1c1NjYWxlfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3Qge2NwdUFnZ3JlZ2F0b3J9ID0gdGhpcy5zdGF0ZTtcblxuICAgIC8vIGJhc2UgbGF5ZXIgcHJvcHNcbiAgICBjb25zdCB7b3BhY2l0eSwgcGlja2FibGUsIGF1dG9IaWdobGlnaHQsIGhpZ2hsaWdodENvbG9yfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgdXBkYXRlVHJpZ2dlcnMgPSB0aGlzLl9nZXRTdWJsYXllclVwZGF0ZVRyaWdnZXJzKCk7XG4gICAgY29uc3QgYWNjZXNzb3JzID0gdGhpcy5fZ2V0U3ViTGF5ZXJBY2Nlc3NvcnMoKTtcblxuICAgIGNvbnN0IGRpc3RhbmNlU2NhbGUgPSBnZXREaXN0YW5jZVNjYWxlcyh0aGlzLmNvbnRleHQudmlld3BvcnQpO1xuICAgIGNvbnN0IG1ldGVyc1BlclBpeGVsID0gZGlzdGFuY2VTY2FsZS5tZXRlcnNQZXJQaXhlbFswXTtcblxuICAgIC8vIHJldHVybiBwcm9wcyB0byB0aGUgc3VibGF5ZXIgY29uc3RydWN0b3JcbiAgICByZXR1cm4gbmV3IFNjYXR0ZXJwbG90TGF5ZXIoe1xuICAgICAgaWQ6IGAke2lkfS1jbHVzdGVyYCxcbiAgICAgIGRhdGE6IGNwdUFnZ3JlZ2F0b3Iuc3RhdGUubGF5ZXJEYXRhLmRhdGEsXG4gICAgICByYWRpdXNTY2FsZTogbWV0ZXJzUGVyUGl4ZWwgKiByYWRpdXNTY2FsZSxcbiAgICAgIG9wYWNpdHksXG4gICAgICBwaWNrYWJsZSxcbiAgICAgIGF1dG9IaWdobGlnaHQsXG4gICAgICBoaWdobGlnaHRDb2xvcixcbiAgICAgIHVwZGF0ZVRyaWdnZXJzLFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfSk7XG4gIH1cbn1cblxuQ2x1c3RlckxheWVyLmxheWVyTmFtZSA9ICdDbHVzdGVyTGF5ZXInO1xuQ2x1c3RlckxheWVyLmRlZmF1bHRQcm9wcyA9IGRlZmF1bHRQcm9wcztcbiJdfQ==