kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
297 lines (290 loc) • 37.2 kB
JavaScript
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 _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 _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 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 = 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);
return {
radiusValue: radiusValue
};
}
}];
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 (_AggregationLayer) {
function ClusterLayer() {
(0, _classCallCheck2["default"])(this, ClusterLayer);
return _callSuper(this, ClusterLayer, arguments);
}
(0, _inherits2["default"])(ClusterLayer, _AggregationLayer);
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
};
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,
visible = _this$props2.visible,
opacity = _this$props2.opacity,
pickable = _this$props2.pickable,
autoHighlight = _this$props2.autoHighlight,
highlightColor = _this$props2.highlightColor;
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));
}
}]);
}(_aggregationLayers._AggregationLayer);
ClusterLayer.layerName = 'ClusterLayer';
ClusterLayer.defaultProps = defaultProps;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGF5ZXJzIiwicmVxdWlyZSIsIl9hZ2dyZWdhdGlvbkxheWVycyIsIl9nZW9WaWV3cG9ydCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY3B1QWdncmVnYXRvciIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX3ZpZXdwb3J0TWVyY2F0b3JQcm9qZWN0IiwiX2QzQXJyYXkiLCJfY29uc3RhbnRzIiwiX2NsdXN0ZXJVdGlscyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiX3R5cGVvZiIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIm93bktleXMiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsIl9jYWxsU3VwZXIiLCJfZ2V0UHJvdG90eXBlT2YyIiwiX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yIiwiX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCIsIlJlZmxlY3QiLCJjb25zdHJ1Y3QiLCJjb25zdHJ1Y3RvciIsIkJvb2xlYW4iLCJwcm90b3R5cGUiLCJ2YWx1ZU9mIiwiZGVmYXVsdFJhZGl1cyIsIkxBWUVSX1ZJU19DT05GSUdTIiwiY2x1c3RlclJhZGl1cyIsImRlZmF1bHRWYWx1ZSIsImRlZmF1bHRSYWRpdXNSYW5nZSIsImNsdXN0ZXJSYWRpdXNSYW5nZSIsImRlZmF1bHRHZXRDb2xvclZhbHVlIiwicG9pbnRzIiwiZGVmYXVsdEdldFJhZGl1c1ZhbHVlIiwiY2VsbCIsImZpbHRlcmVkUG9pbnRzIiwicHJvY2Vzc0dlb0pTT04iLCJzdGVwIiwicHJvcHMiLCJhZ2dyZWdhdGlvbiIsIl9yZWYiLCJ2aWV3cG9ydCIsImRhdGEiLCJnZXRQb3NpdGlvbiIsImZpbHRlckRhdGEiLCJnZW9KU09OIiwiZ2V0R2VvSlNPTiIsImNsdXN0ZXJCdWlsZGVyIiwiQ2x1c3RlckJ1aWxkZXIiLCJzZXRTdGF0ZSIsImdldENsdXN0ZXJzIiwiX3JlZjIiLCJfdGhpcyRzdGF0ZSIsInN0YXRlIiwiem9vbSIsIndpZHRoIiwiaGVpZ2h0IiwibG9uZ2l0dWRlIiwibGF0aXR1ZGUiLCJiYm94IiwiZ2VvVmlld3BvcnQiLCJib3VuZHMiLCJjbHVzdGVycyIsImNsdXN0ZXJzQXRab29tIiwibGF5ZXJEYXRhIiwiZ2V0U3ViTGF5ZXJSYWRpdXMiLCJkaW1lbnNpb25TdGF0ZSIsImRpbWVuc2lvbiIsImxheWVyUHJvcHMiLCJnZXRSYWRpdXNWYWx1ZSIsInNjYWxlRnVuYyIsImNsdXN0ZXJBZ2dyZWdhdGlvbiIsImV4cG9ydHMiLCJrZXkiLCJ1cGRhdGVTdGVwcyIsInRyaWdnZXJzIiwicG9zaXRpb24iLCJwcm9wIiwidXBkYXRlVHJpZ2dlciIsInVwZGF0ZXIiLCJnZXRSYWRpdXNWYWx1ZURvbWFpbiIsImRpbWVuc2lvblVwZGF0ZXIiLCJ2YWx1ZURvbWFpbiIsIm1heCIsIl9zZXREaW1lbnNpb25TdGF0ZSIsImNsdXN0ZXJMYXllckRpbWVuc2lvbnMiLCJkZWZhdWx0Q29sb3JEaW1lbnNpb24iLCJhY2Nlc3NvciIsIm51bGxWYWx1ZSIsInZhbHVlIiwiZG9tYWluIiwicmFuZ2UiLCJzY2FsZVR5cGUiLCJnZXREaW1lbnNpb25TY2FsZSIsImdldFN1YkxheWVyQWNjZXNzb3IiLCJnZXRQaWNraW5nSW5mbyIsInJhZGl1c1ZhbHVlIiwiZGVmYXVsdFByb3BzIiwiY29sb3JEb21haW4iLCJjb2xvclJhbmdlIiwiREVGQVVMVF9DT0xPUl9SQU5HRSIsImNvbG9yU2NhbGVUeXBlIiwiU0NBTEVfVFlQRVMiLCJxdWFudGl6ZSIsInJhZGl1c1NjYWxlVHlwZSIsInNxcnQiLCJyYWRpdXNSYW5nZSIsInR5cGUiLCJ4IiwiZ2V0Q29sb3JWYWx1ZSIsIkNsdXN0ZXJMYXllciIsIl9BZ2dyZWdhdGlvbkxheWVyIiwiX2NsYXNzQ2FsbENoZWNrMiIsIl9pbmhlcml0czIiLCJfY3JlYXRlQ2xhc3MyIiwiaW5pdGlhbGl6ZVN0YXRlIiwiY3B1QWdncmVnYXRvciIsIkNQVUFnZ3JlZ2F0b3IiLCJkaW1lbnNpb25zIiwiYWdncmVnYXRvclN0YXRlIiwiYXR0cmlidXRlTWFuYWdlciIsImdldEF0dHJpYnV0ZU1hbmFnZXIiLCJhZGQiLCJwb3NpdGlvbnMiLCJzaXplIiwidXBkYXRlU3RhdGUiLCJfcmVmMyIsIm9sZFByb3BzIiwiY2hhbmdlRmxhZ3MiLCJjb250ZXh0IiwiYXR0cmlidXRlcyIsImdldEF0dHJpYnV0ZXMiLCJudW1JbnN0YW5jZXMiLCJnZXROdW1JbnN0YW5jZXMiLCJfcmVmNCIsImluZm8iLCJfZ2V0U3VibGF5ZXJVcGRhdGVUcmlnZ2VycyIsImdldFVwZGF0ZVRyaWdnZXJzIiwiX2dldFN1YkxheWVyQWNjZXNzb3JzIiwiZ2V0UmFkaXVzIiwiZ2V0QWNjZXNzb3IiLCJnZXRGaWxsQ29sb3IiLCJyZW5kZXJMYXllcnMiLCJfdGhpcyRwcm9wcyIsImlkIiwicmFkaXVzU2NhbGUiLCJfdGhpcyRwcm9wczIiLCJ2aXNpYmxlIiwib3BhY2l0eSIsInBpY2thYmxlIiwiYXV0b0hpZ2hsaWdodCIsImhpZ2hsaWdodENvbG9yIiwidXBkYXRlVHJpZ2dlcnMiLCJhY2Nlc3NvcnMiLCJkaXN0YW5jZVNjYWxlIiwiZ2V0RGlzdGFuY2VTY2FsZXMiLCJtZXRlcnNQZXJQaXhlbCIsIlNjYXR0ZXJwbG90TGF5ZXIiLCJjb25jYXQiLCJwYXJhbWV0ZXJzIiwiZGVwdGhNYXNrIiwiQWdncmVnYXRpb25MYXllciIsImxheWVyTmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbHVzdGVyLWxheWVyL2NsdXN0ZXItbGF5ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHtTY2F0dGVycGxvdExheWVyfSBmcm9tICdAZGVjay5nbC9sYXllcnMnO1xuaW1wb3J0IHtfQWdncmVnYXRpb25MYXllciBhcyBBZ2dyZWdhdGlvbkxheWVyfSBmcm9tICdAZGVjay5nbC9hZ2dyZWdhdGlvbi1sYXllcnMnO1xuXG5pbXBvcnQgZ2VvVmlld3BvcnQgZnJvbSAnQG1hcGJveC9nZW8tdmlld3BvcnQnO1xuaW1wb3J0IENQVUFnZ3JlZ2F0b3IsIHtcbiAgQWdncmVnYXRpb25UeXBlLFxuICBkZWZhdWx0Q29sb3JEaW1lbnNpb24sXG4gIERpbWVuc2lvblR5cGUsXG4gIGdldERpbWVuc2lvblNjYWxlXG59IGZyb20gJy4uL2xheWVyLXV0aWxzL2NwdS1hZ2dyZWdhdG9yJztcbmltcG9ydCB7Z2V0RGlzdGFuY2VTY2FsZXN9IGZyb20gJ3ZpZXdwb3J0LW1lcmNhdG9yLXByb2plY3QnO1xuaW1wb3J0IHttYXh9IGZyb20gJ2QzLWFycmF5JztcblxuaW1wb3J0IHtTQ0FMRV9UWVBFUywgREVGQVVMVF9DT0xPUl9SQU5HRSwgTEFZRVJfVklTX0NPTkZJR1N9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCBDbHVzdGVyQnVpbGRlciwge2dldEdlb0pTT059IGZyb20gJy4uL2xheWVyLXV0aWxzL2NsdXN0ZXItdXRpbHMnO1xuaW1wb3J0IHtSR0JBQ29sb3J9IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtBZ2dyZWdhdGlvbkxheWVyUHJvcHN9IGZyb20gJ0BkZWNrLmdsL2FnZ3JlZ2F0aW9uLWxheWVycy9hZ2dyZWdhdGlvbi1sYXllcic7XG5cbmNvbnN0IGRlZmF1bHRSYWRpdXMgPSBMQVlFUl9WSVNfQ09ORklHUy5jbHVzdGVyUmFkaXVzLmRlZmF1bHRWYWx1ZTtcbmNvbnN0IGRlZmF1bHRSYWRpdXNSYW5nZSA9IExBWUVSX1ZJU19DT05GSUdTLmNsdXN0ZXJSYWRpdXNSYW5nZS5kZWZhdWx0VmFsdWU7XG5cbmNvbnN0IGRlZmF1bHRHZXRDb2xvclZhbHVlID0gcG9pbnRzID0+IHBvaW50cy5sZW5ndGg7XG5jb25zdCBkZWZhdWx0R2V0UmFkaXVzVmFsdWUgPSBjZWxsID0+XG4gIGNlbGwuZmlsdGVyZWRQb2ludHMgPyBjZWxsLmZpbHRlcmVkUG9pbnRzLmxlbmd0aCA6IGNlbGwucG9pbnRzLmxlbmd0aDtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuZnVuY3Rpb24gcHJvY2Vzc0dlb0pTT04odGhpczogQ1BVQWdncmVnYXRvciwgc3RlcCwgcHJvcHMsIGFnZ3JlZ2F0aW9uLCB7dmlld3BvcnR9KSB7XG4gIGNvbnN0IHtkYXRhLCBnZXRQb3NpdGlvbiwgZmlsdGVyRGF0YX0gPSBwcm9wcztcbiAgY29uc3QgZ2VvSlNPTiA9IGdldEdlb0pTT04oZGF0YSwgZ2V0UG9zaXRpb24sIGZpbHRlckRhdGEpO1xuICBjb25zdCBjbHVzdGVyQnVpbGRlciA9IG5ldyBDbHVzdGVyQnVpbGRlcigpO1xuXG4gIHRoaXMuc2V0U3RhdGUoe2dlb0pTT04sIGNsdXN0ZXJCdWlsZGVyfSk7XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIGdldENsdXN0ZXJzKHRoaXM6IENQVUFnZ3JlZ2F0b3IsIHN0ZXAsIHByb3BzLCBhZ2dyZWdhdGlvbiwge3ZpZXdwb3J0fSkge1xuICBjb25zdCB7Z2VvSlNPTiwgY2x1c3RlckJ1aWxkZXJ9ID0gdGhpcy5zdGF0ZTtcbiAgY29uc3Qge2NsdXN0ZXJSYWRpdXMsIHpvb20sIHdpZHRoLCBoZWlnaHR9ID0gcHJvcHM7XG4gIGNvbnN0IHtsb25naXR1ZGUsIGxhdGl0dWRlfSA9IHZpZXdwb3J0O1xuXG4gIC8vIHpvb20gbmVlZHMgdG8gYmUgYW4gaW50ZWdlciBmb3IgdGhlIGRpZmZlcmVudCBtYXAgdXRpbHMuIEFsc28gaGVscHMgd2l0aCBjYWNoZSBrZXkuXG4gIGNvbnN0IGJib3ggPSBnZW9WaWV3cG9ydC5ib3VuZHMoW2xvbmdpdHVkZSwgbGF0aXR1ZGVdLCB6b29tLCBbd2lkdGgsIGhlaWdodF0pO1xuICBjb25zdCBjbHVzdGVycyA9IGNsdXN0ZXJCdWlsZGVyLmNsdXN0ZXJzQXRab29tKHtiYm94LCBjbHVzdGVyUmFkaXVzLCBnZW9KU09OLCB6b29tfSk7XG5cbiAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgbGF5ZXJEYXRhOiB7ZGF0YTogY2x1c3RlcnN9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRTdWJMYXllclJhZGl1cyhkaW1lbnNpb25TdGF0ZSwgZGltZW5zaW9uLCBsYXllclByb3BzKSB7XG4gIHJldHVybiBjZWxsID0+IHtcbiAgICBjb25zdCB7Z2V0UmFkaXVzVmFsdWV9ID0gbGF5ZXJQcm9wcztcbiAgICBjb25zdCB7c2NhbGVGdW5jfSA9IGRpbWVuc2lvblN0YXRlO1xuICAgIHJldHVybiBzY2FsZUZ1bmMoZ2V0UmFkaXVzVmFsdWUoY2VsbCkpO1xuICB9O1xufVxuXG5leHBvcnQgY29uc3QgY2x1c3RlckFnZ3JlZ2F0aW9uOiBBZ2dyZWdhdGlvblR5cGUgPSB7XG4gIGtleTogJ3Bvc2l0aW9uJyxcbiAgdXBkYXRlU3RlcHM6IFtcbiAgICB7XG4gICAgICBrZXk6ICdnZW9qc29uJyxcbiAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgcHJvcDogJ2dldFBvc2l0aW9uJyxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZ2V0UG9zaXRpb24nXG4gICAgICAgIH0sXG4gICAgICAgIGZpbHRlckRhdGE6IHtcbiAgICAgICAgICBwcm9wOiAnZmlsdGVyRGF0YScsXG4gICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ2ZpbHRlckRhdGEnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1cGRhdGVyOiBwcm9jZXNzR2VvSlNPTlxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnY2x1c3RlcmluZycsXG4gICAgICB0cmlnZ2Vyczoge1xuICAgICAgICBjbHVzdGVyUmFkaXVzOiB7XG4gICAgICAgICAgcHJvcDogJ2NsdXN0ZXJSYWRpdXMnXG4gICAgICAgIH0sXG4gICAgICAgIHpvb206IHtcbiAgICAgICAgICBwcm9wOiAnem9vbSdcbiAgICAgICAgfSxcbiAgICAgICAgd2lkdGg6IHtcbiAgICAgICAgICBwcm9wOiAnd2lkdGgnXG4gICAgICAgIH0sXG4gICAgICAgIGhlaWdodDoge1xuICAgICAgICAgIHByb3A6ICdoZWlnaHQnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1cGRhdGVyOiBnZXRDbHVzdGVyc1xuICAgIH1cbiAgXVxufTtcblxuZnVuY3Rpb24gZ2V0UmFkaXVzVmFsdWVEb21haW4odGhpczogQ1BVQWdncmVnYXRvciwgc3RlcCwgcHJvcHMsIGRpbWVuc2lvblVwZGF0ZXIpIHtcbiAgY29uc3Qge2tleX0gPSBkaW1lbnNpb25VcGRhdGVyO1xuICBjb25zdCB7Z2V0UmFkaXVzVmFsdWV9ID0gcHJvcHM7XG4gIGNvbnN0IHtsYXllckRhdGF9ID0gdGhpcy5zdGF0ZTtcblxuICBjb25zdCB2YWx1ZURvbWFpbiA9IFswLCBtYXgobGF5ZXJEYXRhLmRhdGEsIGdldFJhZGl1c1ZhbHVlKV07XG4gIHRoaXMuX3NldERpbWVuc2lvblN0YXRlKGtleSwge3ZhbHVlRG9tYWlufSk7XG59XG5cbmNvbnN0IGNsdXN0ZXJMYXllckRpbWVuc2lvbnM6IFtEaW1lbnNpb25UeXBlPFJHQkFDb2xvcj4sIERpbWVuc2lvblR5cGU8bnVtYmVyPl0gPSBbXG4gIGRlZmF1bHRDb2xvckRpbWVuc2lvbixcbiAge1xuICAgIGtleTogJ3JhZGl1cycsXG4gICAgYWNjZXNzb3I6ICdnZXRSYWRpdXMnLFxuICAgIG51bGxWYWx1ZTogMCxcbiAgICB1cGRhdGVTdGVwczogW1xuICAgICAge1xuICAgICAgICBrZXk6ICdnZXREb21haW4nLFxuICAgICAgICB0cmlnZ2Vyczoge1xuICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICBwcm9wOiAnZ2V0UmFkaXVzVmFsdWUnLFxuICAgICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ2dldFJhZGl1c1ZhbHVlJ1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgdXBkYXRlcjogZ2V0UmFkaXVzVmFsdWVEb21haW5cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ2dldFNjYWxlRnVuYycsXG4gICAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgICAgZG9tYWluOiB7cHJvcDogJ3JhZGl1c0RvbWFpbid9LFxuICAgICAgICAgIHJhbmdlOiB7cHJvcDogJ3JhZGl1c1JhbmdlJ30sXG4gICAgICAgICAgc2NhbGVUeXBlOiB7cHJvcDogJ3JhZGl1c1NjYWxlVHlwZSd9XG4gICAgICAgIH0sXG4gICAgICAgIHVwZGF0ZXI6IGdldERpbWVuc2lvblNjYWxlXG4gICAgICB9XG4gICAgXSxcbiAgICBnZXRTdWJMYXllckFjY2Vzc29yOiBnZXRTdWJMYXllclJhZGl1cyxcbiAgICBnZXRQaWNraW5nSW5mbzogKGRpbWVuc2lvblN0YXRlLCBjZWxsLCBsYXllclByb3BzKSA9PiB7XG4gICAgICBjb25zdCByYWRpdXNWYWx1ZSA9IGxheWVyUHJvcHMuZ2V0UmFkaXVzVmFsdWUoY2VsbCk7XG4gICAgICByZXR1cm4ge3JhZGl1c1ZhbHVlfTtcbiAgICB9XG4gIH1cbl07XG5cbmNvbnN0IGRlZmF1bHRQcm9wcyA9IHtcbiAgY2x1c3RlclJhZGl1czogZGVmYXVsdFJhZGl1cyxcbiAgY29sb3JEb21haW46IG51bGwsXG4gIGNvbG9yUmFuZ2U6IERFRkFVTFRfQ09MT1JfUkFOR0UsXG4gIGNvbG9yU2NhbGVUeXBlOiBTQ0FMRV9UWVBFUy5xdWFudGl6ZSxcbiAgcmFkaXVzU2NhbGVUeXBlOiBTQ0FMRV9UWVBFUy5zcXJ0LFxuICByYWRpdXNSYW5nZTogZGVmYXVsdFJhZGl1c1JhbmdlLFxuICBnZXRQb3NpdGlvbjoge3R5cGU6ICdhY2Nlc3NvcicsIHZhbHVlOiB4ID0+IHgucG9zaXRpb259LFxuICBnZXRDb2xvclZhbHVlOiB7dHlwZTogJ2FjY2Vzc29yJywgdmFsdWU6IGRlZmF1bHRHZXRDb2xvclZhbHVlfSxcbiAgZ2V0UmFkaXVzVmFsdWU6IHt0eXBlOiAnYWNjZXNzb3InLCB2YWx1ZTogZGVmYXVsdEdldFJhZGl1c1ZhbHVlfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2x1c3RlckxheWVyIGV4dGVuZHMgQWdncmVnYXRpb25MYXllcjxcbiAgYW55LFxuICBBZ2dyZWdhdGlvbkxheWVyUHJvcHM8YW55PiAmIHtyYWRpdXNTY2FsZTogbnVtYmVyfVxuPiB7XG4gIGluaXRpYWxpemVTdGF0ZSgpIHtcbiAgICBjb25zdCBjcHVBZ2dyZWdhdG9yID0gbmV3IENQVUFnZ3JlZ2F0b3Ioe1xuICAgICAgYWdncmVnYXRpb246IGNsdXN0ZXJBZ2dyZWdhdGlvbixcbiAgICAgIGRpbWVuc2lvbnM6IGNsdXN0ZXJMYXllckRpbWVuc2lvbnNcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBjcHVBZ2dyZWdhdG9yLFxuICAgICAgYWdncmVnYXRvclN0YXRlOiBjcHVBZ2dyZWdhdG9yLnN0YXRlXG4gICAgfTtcbiAgICBjb25zdCBhdHRyaWJ1dGVNYW5hZ2VyID0gdGhpcy5nZXRBdHRyaWJ1dGVNYW5hZ2VyKCk7XG4gICAgYXR0cmlidXRlTWFuYWdlci5hZGQoe1xuICAgICAgcG9zaXRpb25zOiB7c2l6ZTogMywgYWNjZXNzb3I6ICdnZXRQb3NpdGlvbid9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVTdGF0ZSh7b2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFnc30pIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIG1ha2UgYSBjb3B5IG9mIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiBjcHVBZ2dyZWdhdG9yIGZvciB0ZXN0aW5nXG4gICAgICBhZ2dyZWdhdG9yU3RhdGU6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci51cGRhdGVTdGF0ZShcbiAgICAgICAge29sZFByb3BzLCBwcm9wcywgY2hhbmdlRmxhZ3N9LFxuICAgICAgICB7XG4gICAgICAgICAgdmlld3BvcnQ6IHRoaXMuY29udGV4dC52aWV3cG9ydCxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB0aGlzLmdldEF0dHJpYnV0ZXMoKSxcbiAgICAgICAgICBudW1JbnN0YW5jZXM6IHRoaXMuZ2V0TnVtSW5zdGFuY2VzKHByb3BzKVxuICAgICAgICB9XG4gICAgICApXG4gICAgfSk7XG4gIH1cblxuICBnZXRQaWNraW5nSW5mbyh7aW5mb30pIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5jcHVBZ2dyZWdhdG9yLmdldFBpY2tpbmdJbmZvKHtpbmZvfSwgdGhpcy5wcm9wcyk7XG4gIH1cblxuICBfZ2V0U3VibGF5ZXJVcGRhdGVUcmlnZ2VycygpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5jcHVBZ2dyZWdhdG9yLmdldFVwZGF0ZVRyaWdnZXJzKHRoaXMucHJvcHMpO1xuICB9XG5cbiAgX2dldFN1YkxheWVyQWNjZXNzb3JzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRSYWRpdXM6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcigncmFkaXVzJywgdGhpcy5wcm9wcyksXG4gICAgICBnZXRGaWxsQ29sb3I6IHRoaXMuc3RhdGUuY3B1QWdncmVnYXRvci5nZXRBY2Nlc3NvcignZmlsbENvbG9yJywgdGhpcy5wcm9wcylcbiAgICB9O1xuICB9XG5cbiAgcmVuZGVyTGF5ZXJzKCkge1xuICAgIC8vIGZvciBzdWJjbGFzc2luZywgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuXG4gICAgLy8gY3VzdG9taXplZCBzdWIgbGF5ZXIgcHJvcHNcbiAgICBjb25zdCB7aWQsIHJhZGl1c1NjYWxlfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3Qge2NwdUFnZ3JlZ2F0b3J9ID0gdGhpcy5zdGF0ZTtcblxuICAgIC8vIGJhc2UgbGF5ZXIgcHJvcHNcbiAgICBjb25zdCB7dmlzaWJsZSwgb3BhY2l0eSwgcGlja2FibGUsIGF1dG9IaWdobGlnaHQsIGhpZ2hsaWdodENvbG9yfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgdXBkYXRlVHJpZ2dlcnMgPSB0aGlzLl9nZXRTdWJsYXllclVwZGF0ZVRyaWdnZXJzKCk7XG4gICAgY29uc3QgYWNjZXNzb3JzID0gdGhpcy5fZ2V0U3ViTGF5ZXJBY2Nlc3NvcnMoKTtcblxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICBjb25zdCBkaXN0YW5jZVNjYWxlID0gZ2V0RGlzdGFuY2VTY2FsZXModGhpcy5jb250ZXh0LnZpZXdwb3J0KTtcbiAgICBjb25zdCBtZXRlcnNQZXJQaXhlbCA9IGRpc3RhbmNlU2NhbGUubWV0ZXJzUGVyUGl4ZWxbMF07XG5cbiAgICAvLyByZXR1cm4gcHJvcHMgdG8gdGhlIHN1YmxheWVyIGNvbnN0cnVjdG9yXG4gICAgcmV0dXJuIG5ldyBTY2F0dGVycGxvdExheWVyKHtcbiAgICAgIGlkOiBgJHtpZH0tY2x1c3RlcmAsXG4gICAgICBkYXRhOiBjcHVBZ2dyZWdhdG9yLnN0YXRlLmxheWVyRGF0YS5kYXRhLFxuICAgICAgcmFkaXVzU2NhbGU6IG1ldGVyc1BlclBpeGVsICogcmFkaXVzU2NhbGUsXG4gICAgICB2aXNpYmxlLFxuICAgICAgb3BhY2l0eSxcbiAgICAgIHBpY2thYmxlLFxuICAgICAgYXV0b0hpZ2hsaWdodCxcbiAgICAgIGhpZ2hsaWdodENvbG9yLFxuICAgICAgdXBkYXRlVHJpZ2dlcnMsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIGRlcHRoTWFzazogZmFsc2VcbiAgICAgIH0sXG4gICAgICAuLi5hY2Nlc3NvcnNcbiAgICB9KTtcbiAgfVxufVxuXG5DbHVzdGVyTGF5ZXIubGF5ZXJOYW1lID0gJ0NsdXN0ZXJMYXllcic7XG5DbHVzdGVyTGF5ZXIuZGVmYXVsdFByb3BzID0gZGVmYXVsdFByb3BzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUdBLElBQUFBLE9BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLGtCQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxZQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxjQUFBLEdBQUFDLHVCQUFBLENBQUFMLE9BQUE7QUFNQSxJQUFBTSx3QkFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sUUFBQSxHQUFBUCxPQUFBO0FBRUEsSUFBQVEsVUFBQSxHQUFBUixPQUFBO0FBQ0EsSUFBQVMsYUFBQSxHQUFBSix1QkFBQSxDQUFBTCxPQUFBO0FBQXdFLFNBQUFVLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLHlCQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBTix3QkFBQU0sQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLGdCQUFBSyxPQUFBLENBQUFMLENBQUEsMEJBQUFBLENBQUEsc0JBQUFBLENBQUEsUUFBQUcsQ0FBQSxHQUFBSix3QkFBQSxDQUFBRyxDQUFBLE9BQUFDLENBQUEsSUFBQUEsQ0FBQSxDQUFBRyxHQUFBLENBQUFOLENBQUEsVUFBQUcsQ0FBQSxDQUFBSSxHQUFBLENBQUFQLENBQUEsT0FBQVEsQ0FBQSxLQUFBQyxTQUFBLFVBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxjQUFBLElBQUFELE1BQUEsQ0FBQUUsd0JBQUEsV0FBQUMsQ0FBQSxJQUFBZCxDQUFBLG9CQUFBYyxD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
;