kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
529 lines (461 loc) • 66.9 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = MapContainerFactory;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
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 _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _reactMapGl = _interopRequireDefault(require("react-map-gl"));
var _react2 = _interopRequireDefault(require("@deck.gl/react"));
var _reselect = require("reselect");
var _viewportMercatorProject = _interopRequireDefault(require("viewport-mercator-project"));
var _mapPopover = _interopRequireDefault(require("./map/map-popover"));
var _mapControl = _interopRequireDefault(require("./map/map-control"));
var _styledComponents = require("./common/styled-components");
var _editor = _interopRequireDefault(require("./editor/editor"));
var _mapboxUtils = require("../layers/mapbox-utils");
var _baseLayer = require("../layers/base-layer");
var _glUtils = require("../utils/gl-utils");
var _mapboxUtils2 = require("../utils/map-style-utils/mapbox-utils");
var _dBuildingLayer = _interopRequireDefault(require("../deckgl-layers/3d-building-layer/3d-building-layer"));
var _defaultSettings = require("../constants/default-settings");
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var MAP_STYLE = {
container: {
display: 'inline-block',
position: 'relative'
},
top: {
position: 'absolute',
top: '0px',
pointerEvents: 'none'
}
};
var MAPBOXGL_STYLE_UPDATE = 'style.load';
var MAPBOXGL_RENDER = 'render';
var TRANSITION_DURATION = 0;
MapContainerFactory.deps = [_mapPopover["default"], _mapControl["default"]];
function MapContainerFactory(MapPopover, MapControl) {
var MapContainer =
/*#__PURE__*/
function (_Component) {
(0, _inherits2["default"])(MapContainer, _Component);
function MapContainer(_props) {
var _this;
(0, _classCallCheck2["default"])(this, MapContainer);
_this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(MapContainer).call(this, _props));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "layersSelector", function (props) {
return props.layers;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "layerDataSelector", function (props) {
return props.layerData;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "mapLayersSelector", function (props) {
return props.mapLayers;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "layerOrderSelector", function (props) {
return props.layerOrder;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "layersToRenderSelector", (0, _reselect.createSelector)(_this.layersSelector, _this.layerDataSelector, _this.mapLayersSelector, // {[id]: true \ false}
function (layers, layerData, mapLayers) {
return layers.reduce(function (accu, layer, idx) {
return _objectSpread({}, accu, (0, _defineProperty2["default"])({}, layer.id, layer.shouldRenderLayer(layerData[idx]) && _this._isVisibleMapLayer(layer, mapLayers)));
}, {});
}));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "filtersSelector", function (props) {
return props.filters;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "polygonFilters", (0, _reselect.createSelector)(_this.filtersSelector, function (filters) {
return filters.filter(function (f) {
return f.type === _defaultSettings.FILTER_TYPES.polygon;
});
}));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "mapboxLayersSelector", (0, _reselect.createSelector)(_this.layersSelector, _this.layerDataSelector, _this.layerOrderSelector, _this.layersToRenderSelector, _mapboxUtils.generateMapboxLayers));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onCloseMapPopover", function () {
_this.props.visStateActions.onLayerClick(null);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onLayerSetDomain", function (idx, colorDomain) {
_this.props.visStateActions.layerConfigChange(_this.props.layers[idx], {
colorDomain: colorDomain
});
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleMapToggleLayer", function (layerId) {
var _this$props = _this.props,
_this$props$index = _this$props.index,
mapIndex = _this$props$index === void 0 ? 0 : _this$props$index,
visStateActions = _this$props.visStateActions;
visStateActions.toggleLayerForMap(mapIndex, layerId);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onMapboxStyleUpdate", function () {
// force refresh mapboxgl layers
_this.previousLayers = {};
_this._updateMapboxLayers();
if (typeof _this.props.onMapStyleLoaded === 'function') {
_this.props.onMapStyleLoaded(_this._map);
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setMapboxMap", function (mapbox) {
if (!_this._map && mapbox) {
_this._map = mapbox.getMap(); // i noticed in certain context we don't access the actual map element
if (!_this._map) {
return;
} // bind mapboxgl event listener
_this._map.on(MAPBOXGL_STYLE_UPDATE, _this._onMapboxStyleUpdate);
_this._map.on(MAPBOXGL_RENDER, function () {
if (typeof _this.props.onMapRender === 'function') {
_this.props.onMapRender(_this._map);
}
});
}
if (_this.props.getMapboxRef) {
// The parent component can gain access to our MapboxGlMap by
// providing this callback. Note that 'mapbox' will be null when the
// ref is unset (e.g. when a split map is closed).
_this.props.getMapboxRef(mapbox, _this.props.index);
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onBeforeRender", function (_ref) {
var gl = _ref.gl;
(0, _glUtils.setLayerBlending)(gl, _this.props.layerBlending);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderLayer", function (overlays, idx) {
var _this$props2 = _this.props,
datasets = _this$props2.datasets,
layers = _this$props2.layers,
layerData = _this$props2.layerData,
hoverInfo = _this$props2.hoverInfo,
clicked = _this$props2.clicked,
mapState = _this$props2.mapState,
interactionConfig = _this$props2.interactionConfig,
animationConfig = _this$props2.animationConfig;
var layer = layers[idx];
var data = layerData[idx];
var _ref2 = datasets[layer.config.dataId] || {},
gpuFilter = _ref2.gpuFilter;
var objectHovered = clicked || hoverInfo;
var layerCallbacks = {
onSetLayerDomain: function onSetLayerDomain(val) {
return _this._onLayerSetDomain(idx, val);
}
}; // Layer is Layer class
var layerOverlay = layer.renderLayer({
data: data,
gpuFilter: gpuFilter,
idx: idx,
interactionConfig: interactionConfig,
layerCallbacks: layerCallbacks,
mapState: mapState,
animationConfig: animationConfig,
objectHovered: objectHovered
});
return overlays.concat(layerOverlay || []);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onViewportChange", function (viewState) {
if (typeof _this.props.onViewStateChange === 'function') {
_this.props.onViewStateChange(viewState);
}
_this.props.mapStateActions.updateMap(viewState);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_toggleMapControl", function (panelId) {
var _this$props3 = _this.props,
index = _this$props3.index,
uiStateActions = _this$props3.uiStateActions;
uiStateActions.toggleMapControl(panelId, index);
});
_this.previousLayers = {// [layers.id]: mapboxLayerConfig
};
_this._deck = null;
return _this;
}
(0, _createClass2["default"])(MapContainer, [{
key: "componentWillUnmount",
value: function componentWillUnmount() {
// unbind mapboxgl event listener
if (this._map) {
this._map.off(MAPBOXGL_STYLE_UPDATE);
this._map.off(MAPBOXGL_RENDER);
}
}
}, {
key: "_isVisibleMapLayer",
/* component private functions */
value: function _isVisibleMapLayer(layer, mapLayers) {
// if layer.id is not in mapLayers, don't render it
return !mapLayers || mapLayers && mapLayers[layer.id];
}
}, {
key: "_renderMapPopover",
/* component render functions */
/* eslint-disable complexity */
value: function _renderMapPopover(layersToRender) {
// TODO: move this into reducer so it can be tested
var _this$props4 = this.props,
mapState = _this$props4.mapState,
hoverInfo = _this$props4.hoverInfo,
clicked = _this$props4.clicked,
datasets = _this$props4.datasets,
interactionConfig = _this$props4.interactionConfig,
layers = _this$props4.layers,
_this$props4$mousePos = _this$props4.mousePos,
mousePosition = _this$props4$mousePos.mousePosition,
coordinate = _this$props4$mousePos.coordinate,
pinned = _this$props4$mousePos.pinned;
if (!mousePosition) {
return null;
} // if clicked something, ignore hover behavior
var objectInfo = clicked || hoverInfo;
var layerHoverProp = null;
var position = {
x: mousePosition[0],
y: mousePosition[1]
};
if (interactionConfig.tooltip.enabled && objectInfo && objectInfo.picked) {
// if anything hovered
var object = objectInfo.object,
overlay = objectInfo.layer; // deckgl layer to kepler-gl layer
var layer = layers[overlay.props.idx];
if (layer.getHoverData && layersToRender[layer.id]) {
// if layer is visible and have hovered data
var dataId = layer.config.dataId;
var _datasets$dataId = datasets[dataId],
allData = _datasets$dataId.allData,
fields = _datasets$dataId.fields;
var data = layer.getHoverData(object, allData);
var fieldsToShow = interactionConfig.tooltip.config.fieldsToShow[dataId];
layerHoverProp = {
data: data,
fields: fields,
fieldsToShow: fieldsToShow,
layer: layer
};
}
}
if (pinned || clicked) {
// project lnglat to screen so that tooltip follows the object on zoom
var viewport = new _viewportMercatorProject["default"](mapState);
var lngLat = clicked ? clicked.lngLat : pinned.coordinate;
position = this._getHoverXY(viewport, lngLat);
}
return _react["default"].createElement("div", null, _react["default"].createElement(MapPopover, (0, _extends2["default"])({}, position, {
layerHoverProp: layerHoverProp,
coordinate: interactionConfig.coordinate.enabled && ((pinned || {}).coordinate || coordinate),
freezed: Boolean(clicked || pinned),
onClose: this._onCloseMapPopover,
mapW: mapState.width,
mapH: mapState.height
})));
}
/* eslint-enable complexity */
}, {
key: "_getHoverXY",
value: function _getHoverXY(viewport, lngLat) {
var screenCoord = !viewport || !lngLat ? null : viewport.project(lngLat);
return screenCoord && {
x: screenCoord[0],
y: screenCoord[1]
};
}
}, {
key: "_renderDeckOverlay",
value: function _renderDeckOverlay(layersToRender) {
var _this2 = this;
var _this$props5 = this.props,
mapState = _this$props5.mapState,
mapStyle = _this$props5.mapStyle,
layerData = _this$props5.layerData,
layerOrder = _this$props5.layerOrder,
layers = _this$props5.layers,
visStateActions = _this$props5.visStateActions,
mapboxApiAccessToken = _this$props5.mapboxApiAccessToken,
mapboxApiUrl = _this$props5.mapboxApiUrl;
var deckGlLayers = []; // wait until data is ready before render data layers
if (layerData && layerData.length) {
// last layer render first
deckGlLayers = layerOrder.slice().reverse().filter(function (idx) {
return layers[idx].overlayType === _baseLayer.OVERLAY_TYPE.deckgl && layersToRender[layers[idx].id];
}).reduce(this._renderLayer, []);
}
if (mapStyle.visibleLayerGroups['3d building']) {
deckGlLayers.push(new _dBuildingLayer["default"]({
id: '_keplergl_3d-building',
mapboxApiAccessToken: mapboxApiAccessToken,
mapboxApiUrl: mapboxApiUrl,
threeDBuildingColor: mapStyle.threeDBuildingColor,
updateTriggers: {
getFillColor: mapStyle.threeDBuildingColor
}
}));
}
return _react["default"].createElement(_react2["default"], (0, _extends2["default"])({}, this.props.deckGlProps, {
viewState: mapState,
id: "default-deckgl-overlay",
layers: deckGlLayers,
onBeforeRender: this._onBeforeRender,
onHover: visStateActions.onLayerHover,
onClick: visStateActions.onLayerClick,
ref: function ref(comp) {
if (comp && comp.deck && !_this2._deck) {
_this2._deck = comp.deck;
}
}
}));
}
}, {
key: "_updateMapboxLayers",
value: function _updateMapboxLayers() {
var mapboxLayers = this.mapboxLayersSelector(this.props);
if (!Object.keys(mapboxLayers).length && !Object.keys(this.previousLayers).length) {
return;
}
(0, _mapboxUtils.updateMapboxLayers)(this._map, mapboxLayers, this.previousLayers);
this.previousLayers = mapboxLayers;
}
}, {
key: "_renderMapboxOverlays",
value: function _renderMapboxOverlays() {
if (this._map && this._map.isStyleLoaded()) {
this._updateMapboxLayers();
}
}
}, {
key: "render",
value: function render() {
var _this$props6 = this.props,
mapState = _this$props6.mapState,
mapStyle = _this$props6.mapStyle,
mapStateActions = _this$props6.mapStateActions,
mapLayers = _this$props6.mapLayers,
layers = _this$props6.layers,
MapComponent = _this$props6.MapComponent,
datasets = _this$props6.datasets,
mapboxApiAccessToken = _this$props6.mapboxApiAccessToken,
mapboxApiUrl = _this$props6.mapboxApiUrl,
mapControls = _this$props6.mapControls,
uiState = _this$props6.uiState,
uiStateActions = _this$props6.uiStateActions,
visStateActions = _this$props6.visStateActions,
editor = _this$props6.editor,
index = _this$props6.index;
var layersToRender = this.layersToRenderSelector(this.props);
if (!mapStyle.bottomMapStyle) {
// style not yet loaded
return _react["default"].createElement("div", null);
}
var mapProps = _objectSpread({}, mapState, {
preserveDrawingBuffer: true,
mapboxApiAccessToken: mapboxApiAccessToken,
mapboxApiUrl: mapboxApiUrl,
onViewportChange: this._onViewportChange,
transformRequest: _mapboxUtils2.transformRequest
});
var isEdit = uiState.mapControls.mapDraw.active;
return _react["default"].createElement(_styledComponents.StyledMapContainer, {
style: MAP_STYLE.container
}, _react["default"].createElement(MapControl, {
datasets: datasets,
dragRotate: mapState.dragRotate,
isSplit: Boolean(mapLayers),
isExport: this.props.isExport,
layers: layers,
layersToRender: layersToRender,
mapIndex: index,
mapControls: mapControls,
readOnly: this.props.readOnly,
scale: mapState.scale || 1,
top: 0,
editor: editor,
locale: uiState.locale,
onTogglePerspective: mapStateActions.togglePerspective,
onToggleSplitMap: mapStateActions.toggleSplitMap,
onMapToggleLayer: this._handleMapToggleLayer,
onToggleMapControl: this._toggleMapControl,
onSetEditorMode: visStateActions.setEditorMode,
onSetLocale: uiStateActions.setLocale,
onToggleEditorVisibility: visStateActions.toggleEditorVisibility
}), _react["default"].createElement(MapComponent, (0, _extends2["default"])({}, mapProps, {
key: "bottom",
ref: this._setMapboxMap,
mapStyle: mapStyle.bottomMapStyle,
getCursor: this.props.hoverInfo ? function () {
return 'pointer';
} : undefined,
transitionDuration: TRANSITION_DURATION,
onMouseMove: this.props.visStateActions.onMouseMove
}), this._renderDeckOverlay(layersToRender), this._renderMapboxOverlays(layersToRender), _react["default"].createElement(_editor["default"], {
index: index,
datasets: datasets,
editor: editor,
filters: this.polygonFilters(this.props),
isEnabled: isEdit,
layers: layers,
layersToRender: layersToRender,
onDeleteFeature: visStateActions.deleteFeature,
onSelect: visStateActions.setSelectedFeature,
onUpdate: visStateActions.setFeatures,
onTogglePolygonFilter: visStateActions.setPolygonFilterLayer,
style: {
pointerEvents: isEdit ? 'all' : 'none',
position: 'absolute',
display: editor.visible ? 'block' : 'none'
}
})), mapStyle.topMapStyle && _react["default"].createElement("div", {
style: MAP_STYLE.top
}, _react["default"].createElement(MapComponent, (0, _extends2["default"])({}, mapProps, {
key: "top",
mapStyle: mapStyle.topMapStyle
}))), this._renderMapPopover(layersToRender));
}
}]);
return MapContainer;
}(_react.Component);
(0, _defineProperty2["default"])(MapContainer, "propTypes", {
// required
datasets: _propTypes["default"].object,
interactionConfig: _propTypes["default"].object.isRequired,
layerBlending: _propTypes["default"].string.isRequired,
layerOrder: _propTypes["default"].arrayOf(_propTypes["default"].any).isRequired,
layerData: _propTypes["default"].arrayOf(_propTypes["default"].any).isRequired,
layers: _propTypes["default"].arrayOf(_propTypes["default"].any).isRequired,
filters: _propTypes["default"].arrayOf(_propTypes["default"].any).isRequired,
mapState: _propTypes["default"].object.isRequired,
mapControls: _propTypes["default"].object.isRequired,
uiState: _propTypes["default"].object.isRequired,
mapStyle: _propTypes["default"].object.isRequired,
mousePos: _propTypes["default"].object.isRequired,
mapboxApiAccessToken: _propTypes["default"].string.isRequired,
mapboxApiUrl: _propTypes["default"].string,
visStateActions: _propTypes["default"].object.isRequired,
mapStateActions: _propTypes["default"].object.isRequired,
uiStateActions: _propTypes["default"].object.isRequired,
// optional
readOnly: _propTypes["default"].bool,
isExport: _propTypes["default"].bool,
clicked: _propTypes["default"].object,
hoverInfo: _propTypes["default"].object,
mapLayers: _propTypes["default"].object,
onMapToggleLayer: _propTypes["default"].func,
onMapStyleLoaded: _propTypes["default"].func,
onMapRender: _propTypes["default"].func,
getMapboxRef: _propTypes["default"].func,
index: _propTypes["default"].number
});
(0, _defineProperty2["default"])(MapContainer, "defaultProps", {
MapComponent: _reactMapGl["default"],
deckGlProps: {},
index: 0
});
MapContainer.displayName = 'MapContainer';
return MapContainer;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL21hcC1jb250YWluZXIuanMiXSwibmFtZXMiOlsiTUFQX1NUWUxFIiwiY29udGFpbmVyIiwiZGlzcGxheSIsInBvc2l0aW9uIiwidG9wIiwicG9pbnRlckV2ZW50cyIsIk1BUEJPWEdMX1NUWUxFX1VQREFURSIsIk1BUEJPWEdMX1JFTkRFUiIsIlRSQU5TSVRJT05fRFVSQVRJT04iLCJNYXBDb250YWluZXJGYWN0b3J5IiwiZGVwcyIsIk1hcFBvcG92ZXJGYWN0b3J5IiwiTWFwQ29udHJvbEZhY3RvcnkiLCJNYXBQb3BvdmVyIiwiTWFwQ29udHJvbCIsIk1hcENvbnRhaW5lciIsInByb3BzIiwibGF5ZXJzIiwibGF5ZXJEYXRhIiwibWFwTGF5ZXJzIiwibGF5ZXJPcmRlciIsImxheWVyc1NlbGVjdG9yIiwibGF5ZXJEYXRhU2VsZWN0b3IiLCJtYXBMYXllcnNTZWxlY3RvciIsInJlZHVjZSIsImFjY3UiLCJsYXllciIsImlkeCIsImlkIiwic2hvdWxkUmVuZGVyTGF5ZXIiLCJfaXNWaXNpYmxlTWFwTGF5ZXIiLCJmaWx0ZXJzIiwiZmlsdGVyc1NlbGVjdG9yIiwiZmlsdGVyIiwiZiIsInR5cGUiLCJGSUxURVJfVFlQRVMiLCJwb2x5Z29uIiwibGF5ZXJPcmRlclNlbGVjdG9yIiwibGF5ZXJzVG9SZW5kZXJTZWxlY3RvciIsImdlbmVyYXRlTWFwYm94TGF5ZXJzIiwidmlzU3RhdGVBY3Rpb25zIiwib25MYXllckNsaWNrIiwiY29sb3JEb21haW4iLCJsYXllckNvbmZpZ0NoYW5nZSIsImxheWVySWQiLCJpbmRleCIsIm1hcEluZGV4IiwidG9nZ2xlTGF5ZXJGb3JNYXAiLCJwcmV2aW91c0xheWVycyIsIl91cGRhdGVNYXBib3hMYXllcnMiLCJvbk1hcFN0eWxlTG9hZGVkIiwiX21hcCIsIm1hcGJveCIsImdldE1hcCIsIm9uIiwiX29uTWFwYm94U3R5bGVVcGRhdGUiLCJvbk1hcFJlbmRlciIsImdldE1hcGJveFJlZiIsImdsIiwibGF5ZXJCbGVuZGluZyIsIm92ZXJsYXlzIiwiZGF0YXNldHMiLCJob3ZlckluZm8iLCJjbGlja2VkIiwibWFwU3RhdGUiLCJpbnRlcmFjdGlvbkNvbmZpZyIsImFuaW1hdGlvbkNvbmZpZyIsImRhdGEiLCJjb25maWciLCJkYXRhSWQiLCJncHVGaWx0ZXIiLCJvYmplY3RIb3ZlcmVkIiwibGF5ZXJDYWxsYmFja3MiLCJvblNldExheWVyRG9tYWluIiwidmFsIiwiX29uTGF5ZXJTZXREb21haW4iLCJsYXllck92ZXJsYXkiLCJyZW5kZXJMYXllciIsImNvbmNhdCIsInZpZXdTdGF0ZSIsIm9uVmlld1N0YXRlQ2hhbmdlIiwibWFwU3RhdGVBY3Rpb25zIiwidXBkYXRlTWFwIiwicGFuZWxJZCIsInVpU3RhdGVBY3Rpb25zIiwidG9nZ2xlTWFwQ29udHJvbCIsIl9kZWNrIiwib2ZmIiwibGF5ZXJzVG9SZW5kZXIiLCJtb3VzZVBvcyIsIm1vdXNlUG9zaXRpb24iLCJjb29yZGluYXRlIiwicGlubmVkIiwib2JqZWN0SW5mbyIsImxheWVySG92ZXJQcm9wIiwieCIsInkiLCJ0b29sdGlwIiwiZW5hYmxlZCIsInBpY2tlZCIsIm9iamVjdCIsIm92ZXJsYXkiLCJnZXRIb3ZlckRhdGEiLCJhbGxEYXRhIiwiZmllbGRzIiwiZmllbGRzVG9TaG93Iiwidmlld3BvcnQiLCJXZWJNZXJjYXRvclZpZXdwb3J0IiwibG5nTGF0IiwiX2dldEhvdmVyWFkiLCJCb29sZWFuIiwiX29uQ2xvc2VNYXBQb3BvdmVyIiwid2lkdGgiLCJoZWlnaHQiLCJzY3JlZW5Db29yZCIsInByb2plY3QiLCJtYXBTdHlsZSIsIm1hcGJveEFwaUFjY2Vzc1Rva2VuIiwibWFwYm94QXBpVXJsIiwiZGVja0dsTGF5ZXJzIiwibGVuZ3RoIiwic2xpY2UiLCJyZXZlcnNlIiwib3ZlcmxheVR5cGUiLCJPVkVSTEFZX1RZUEUiLCJkZWNrZ2wiLCJfcmVuZGVyTGF5ZXIiLCJ2aXNpYmxlTGF5ZXJHcm91cHMiLCJwdXNoIiwiVGhyZWVEQnVpbGRpbmdMYXllciIsInRocmVlREJ1aWxkaW5nQ29sb3IiLCJ1cGRhdGVUcmlnZ2VycyIsImdldEZpbGxDb2xvciIsImRlY2tHbFByb3BzIiwiX29uQmVmb3JlUmVuZGVyIiwib25MYXllckhvdmVyIiwiY29tcCIsImRlY2siLCJtYXBib3hMYXllcnMiLCJtYXBib3hMYXllcnNTZWxlY3RvciIsIk9iamVjdCIsImtleXMiLCJpc1N0eWxlTG9hZGVkIiwiTWFwQ29tcG9uZW50IiwibWFwQ29udHJvbHMiLCJ1aVN0YXRlIiwiZWRpdG9yIiwiYm90dG9tTWFwU3R5bGUiLCJtYXBQcm9wcyIsInByZXNlcnZlRHJhd2luZ0J1ZmZlciIsIm9uVmlld3BvcnRDaGFuZ2UiLCJfb25WaWV3cG9ydENoYW5nZSIsInRyYW5zZm9ybVJlcXVlc3QiLCJpc0VkaXQiLCJtYXBEcmF3IiwiYWN0aXZlIiwiZHJhZ1JvdGF0ZSIsImlzRXhwb3J0IiwicmVhZE9ubHkiLCJzY2FsZSIsImxvY2FsZSIsInRvZ2dsZVBlcnNwZWN0aXZlIiwidG9nZ2xlU3BsaXRNYXAiLCJfaGFuZGxlTWFwVG9nZ2xlTGF5ZXIiLCJfdG9nZ2xlTWFwQ29udHJvbCIsInNldEVkaXRvck1vZGUiLCJzZXRMb2NhbGUiLCJ0b2dnbGVFZGl0b3JWaXNpYmlsaXR5IiwiX3NldE1hcGJveE1hcCIsInVuZGVmaW5lZCIsIm9uTW91c2VNb3ZlIiwiX3JlbmRlckRlY2tPdmVybGF5IiwiX3JlbmRlck1hcGJveE92ZXJsYXlzIiwicG9seWdvbkZpbHRlcnMiLCJkZWxldGVGZWF0dXJlIiwic2V0U2VsZWN0ZWRGZWF0dXJlIiwic2V0RmVhdHVyZXMiLCJzZXRQb2x5Z29uRmlsdGVyTGF5ZXIiLCJ2aXNpYmxlIiwidG9wTWFwU3R5bGUiLCJfcmVuZGVyTWFwUG9wb3ZlciIsIkNvbXBvbmVudCIsIlByb3BUeXBlcyIsImlzUmVxdWlyZWQiLCJzdHJpbmciLCJhcnJheU9mIiwiYW55IiwiYm9vbCIsIm9uTWFwVG9nZ2xlTGF5ZXIiLCJmdW5jIiwibnVtYmVyIiwiTWFw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O0FBc2NsRS9CLEVBQUFBLFlBQVksQ0FBQ2tMLFdBQWIsR0FBMkIsY0FBM0I7QUFFQSxTQUFPbEwsWUFBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIwIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuLy8gbGlicmFyaWVzXG5pbXBvcnQgUmVhY3QsIHtDb21wb25lbnR9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgTWFwYm94R0xNYXAgZnJvbSAncmVhY3QtbWFwLWdsJztcbmltcG9ydCBEZWNrR0wgZnJvbSAnQGRlY2suZ2wvcmVhY3QnO1xuaW1wb3J0IHtjcmVhdGVTZWxlY3Rvcn0gZnJvbSAncmVzZWxlY3QnO1xuaW1wb3J0IFdlYk1lcmNhdG9yVmlld3BvcnQgZnJvbSAndmlld3BvcnQtbWVyY2F0b3ItcHJvamVjdCc7XG5cbi8vIGNvbXBvbmVudHNcbmltcG9ydCBNYXBQb3BvdmVyRmFjdG9yeSBmcm9tICdjb21wb25lbnRzL21hcC9tYXAtcG9wb3Zlcic7XG5pbXBvcnQgTWFwQ29udHJvbEZhY3RvcnkgZnJvbSAnY29tcG9uZW50cy9tYXAvbWFwLWNvbnRyb2wnO1xuaW1wb3J0IHtTdHlsZWRNYXBDb250YWluZXJ9IGZyb20gJ2NvbXBvbmVudHMvY29tbW9uL3N0eWxlZC1jb21wb25lbnRzJztcblxuaW1wb3J0IEVkaXRvciBmcm9tICcuL2VkaXRvci9lZGl0b3InO1xuXG4vLyB1dGlsc1xuaW1wb3J0IHtnZW5lcmF0ZU1hcGJveExheWVycywgdXBkYXRlTWFwYm94TGF5ZXJzfSBmcm9tICdsYXllcnMvbWFwYm94LXV0aWxzJztcbmltcG9ydCB7T1ZFUkxBWV9UWVBFfSBmcm9tICdsYXllcnMvYmFzZS1sYXllcic7XG5pbXBvcnQge3NldExheWVyQmxlbmRpbmd9IGZyb20gJ3V0aWxzL2dsLXV0aWxzJztcbmltcG9ydCB7dHJhbnNmb3JtUmVxdWVzdH0gZnJvbSAndXRpbHMvbWFwLXN0eWxlLXV0aWxzL21hcGJveC11dGlscyc7XG5cbi8vIGRlZmF1bHQtc2V0dGluZ3NcbmltcG9ydCBUaHJlZURCdWlsZGluZ0xheWVyIGZyb20gJ2RlY2tnbC1sYXllcnMvM2QtYnVpbGRpbmctbGF5ZXIvM2QtYnVpbGRpbmctbGF5ZXInO1xuaW1wb3J0IHtGSUxURVJfVFlQRVN9IGZyb20gJ2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcblxuY29uc3QgTUFQX1NUWUxFID0ge1xuICBjb250YWluZXI6IHtcbiAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyxcbiAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJ1xuICB9LFxuICB0b3A6IHtcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICB0b3A6ICcwcHgnLFxuICAgIHBvaW50ZXJFdmVudHM6ICdub25lJ1xuICB9XG59O1xuXG5jb25zdCBNQVBCT1hHTF9TVFlMRV9VUERBVEUgPSAnc3R5bGUubG9hZCc7XG5jb25zdCBNQVBCT1hHTF9SRU5ERVIgPSAncmVuZGVyJztcbmNvbnN0IFRSQU5TSVRJT05fRFVSQVRJT04gPSAwO1xuXG5NYXBDb250YWluZXJGYWN0b3J5LmRlcHMgPSBbTWFwUG9wb3ZlckZhY3RvcnksIE1hcENvbnRyb2xGYWN0b3J5XTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTWFwQ29udGFpbmVyRmFjdG9yeShNYXBQb3BvdmVyLCBNYXBDb250cm9sKSB7XG4gIGNsYXNzIE1hcENvbnRhaW5lciBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICAgIC8vIHJlcXVpcmVkXG4gICAgICBkYXRhc2V0czogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgIGludGVyYWN0aW9uQ29uZmlnOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBsYXllckJsZW5kaW5nOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICBsYXllck9yZGVyOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuYW55KS5pc1JlcXVpcmVkLFxuICAgICAgbGF5ZXJEYXRhOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuYW55KS5pc1JlcXVpcmVkLFxuICAgICAgbGF5ZXJzOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuYW55KS5pc1JlcXVpcmVkLFxuICAgICAgZmlsdGVyczogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLmFueSkuaXNSZXF1aXJlZCxcbiAgICAgIG1hcFN0YXRlOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBDb250cm9sczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgdWlTdGF0ZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgbWFwU3R5bGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIG1vdXNlUG9zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBib3hBcGlBY2Nlc3NUb2tlbjogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgbWFwYm94QXBpVXJsOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgdmlzU3RhdGVBY3Rpb25zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBtYXBTdGF0ZUFjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIHVpU3RhdGVBY3Rpb25zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG5cbiAgICAgIC8vIG9wdGlvbmFsXG4gICAgICByZWFkT25seTogUHJvcFR5cGVzLmJvb2wsXG4gICAgICBpc0V4cG9ydDogUHJvcFR5cGVzLmJvb2wsXG4gICAgICBjbGlja2VkOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgICAgaG92ZXJJbmZvOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgICAgbWFwTGF5ZXJzOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgICAgb25NYXBUb2dnbGVMYXllcjogUHJvcFR5cGVzLmZ1bmMsXG4gICAgICBvbk1hcFN0eWxlTG9hZGVkOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAgIG9uTWFwUmVuZGVyOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAgIGdldE1hcGJveFJlZjogUHJvcFR5cGVzLmZ1bmMsXG4gICAgICBpbmRleDogUHJvcFR5cGVzLm51bWJlclxuICAgIH07XG5cbiAgICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgICAgTWFwQ29tcG9uZW50OiBNYXBib3hHTE1hcCxcbiAgICAgIGRlY2tHbFByb3BzOiB7fSxcbiAgICAgIGluZGV4OiAwXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAgIHRoaXMucHJldmlvdXNM