kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
311 lines (294 loc) • 50.4 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = PlotContainerFactory;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _reactMapGl = require("react-map-gl");
var _debounce = _interopRequireDefault(require("lodash/debounce"));
var _utils = require("@kepler.gl/utils");
var _reducers = require("@kepler.gl/reducers");
var _mapContainer = _interopRequireDefault(require("./map-container"));
var _mapsLayout = _interopRequireDefault(require("./maps-layout"));
var _mapViewStateContext = require("./map-view-state-context");
var _constants = require("@kepler.gl/constants");
var _templateObject, _templateObject2; // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// libraries
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; }
var CLASS_FILTER = ['maplibregl-control-container', 'mapboxgl-control-container', 'attrition-link', 'attrition-logo', 'map-control__panel-split-viewport-tools'];
var DOM_FILTER_FUNC = function DOM_FILTER_FUNC(node) {
return !CLASS_FILTER.includes(node.className);
};
var OUT_OF_SCREEN_POSITION = -9999;
/**
* Calculates legend zoom based on export height
* Maps export height to a zoom factor between 0.5 and 3
* @param height - export height in pixels
* @returns zoom factor for legend panel
*/
function calculateLegendZoom(height) {
var baseHeight = 1080; // 1x zoom reference height
var minZoom = 0.5;
var maxZoom = 3;
// For initial/invalid heights, avoid shrinking the legend; use no scaling.
if (!Number.isFinite(height) || height <= 0) {
return 1;
}
// Linear mapping: height / baseHeight gives us the scale
var zoomFactor = height / baseHeight;
// Clamp between min and max
return Math.max(minZoom, Math.min(maxZoom, zoomFactor));
}
PlotContainerFactory.deps = [_mapContainer["default"], _mapsLayout["default"]];
// Remove mapbox logo in exported map, because it contains non-ascii characters
// Remove split viewport UI controls from exported images when the legend is shown
var StyledPlotContainer = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n .maplibregl-ctrl-bottom-left,\n .maplibregl-ctrl-bottom-right,\n .maplibre-attribution-container,\n .mapboxgl-ctrl-bottom-left,\n .mapboxgl-ctrl-bottom-right,\n .mapbox-attribution-container,\n .map-control__panel-split-viewport-tools {\n display: none;\n }\n\n position: absolute;\n top: ", "px;\n left: ", "px;\n\n /* Apply zoom to legend panel based on export height */\n .map-control-panel {\n zoom: ", " !important;\n }\n"])), OUT_OF_SCREEN_POSITION, OUT_OF_SCREEN_POSITION, function (props) {
return props.legendZoom || 1;
});
var StyledMapContainer = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n width: ", "px;\n height: ", "px;\n display: flex;\n"])), function (props) {
return props.width;
}, function (props) {
return props.height;
});
function PlotContainerFactory(MapContainer, MapsLayout) {
function PlotContainer(_ref) {
var ratio = _ref.ratio,
resolution = _ref.resolution,
_ref$legend = _ref.legend,
legend = _ref$legend === void 0 ? false : _ref$legend,
center = _ref.center,
imageSize = _ref.imageSize,
escapeXhtmlForWebpack = _ref.escapeXhtmlForWebpack,
mapFields = _ref.mapFields,
_ref$splitMaps = _ref.splitMaps,
splitMaps = _ref$splitMaps === void 0 ? [] : _ref$splitMaps,
setExportImageSetting = _ref.setExportImageSetting,
setExportImageDataUri = _ref.setExportImageDataUri,
setExportImageError = _ref.setExportImageError,
addNotification = _ref.addNotification,
enableErrorNotification = _ref.enableErrorNotification,
logoComponent = _ref.logoComponent;
var plottingAreaRef = (0, _react.useRef)(null);
var _useState = (0, _react.useState)(function () {
return mapFields.visState.effects.map(function (effect) {
return effect.clone();
});
}),
_useState2 = (0, _slicedToArray2["default"])(_useState, 1),
plotEffects = _useState2[0];
var mapState = mapFields.mapState;
var deckLayersLoadingRef = (0, _react.useRef)(true);
var mapStyleLoadedRef = (0, _react.useRef)(false);
var screenshotTakenRef = (0, _react.useRef)(false);
// Memoize the scale calculation
var scale = (0, _react.useMemo)(function () {
if (imageSize.scale) {
return imageSize.scale;
}
var calculatedScale = (0, _utils.getScaleFromImageSize)(imageSize.imageW, imageSize.imageH, mapState.width * (mapState.isSplit ? 2 : 1), mapState.height);
return calculatedScale > 0 ? calculatedScale : 1;
}, [imageSize.scale, imageSize.imageW, imageSize.imageH, mapState.width, mapState.height, mapState.isSplit]);
// Memoize the legend zoom calculation based on export height
var legendZoom = (0, _react.useMemo)(function () {
return calculateLegendZoom(imageSize.imageH);
}, [imageSize.imageH]);
// Memoize the map style
var scaledMapStyle = (0, _react.useMemo)(function () {
var mapStyle = mapFields.mapStyle;
return _objectSpread(_objectSpread({}, mapStyle), {}, {
bottomMapStyle: (0, _utils.scaleMapStyleByResolution)(mapStyle.bottomMapStyle, scale),
topMapStyle: (0, _utils.scaleMapStyleByResolution)(mapStyle.topMapStyle, scale)
});
}, [mapFields.mapStyle, scale]);
// Memoize the retrieveNewScreenshot callback
var debouncedScreenshot = (0, _react.useMemo)(function () {
return (0, _debounce["default"])(function () {
if (plottingAreaRef.current) {
(0, _utils.convertToPng)(plottingAreaRef.current, {
filter: DOM_FILTER_FUNC,
width: imageSize.imageW,
height: imageSize.imageH,
escapeXhtmlForWebpack: escapeXhtmlForWebpack
}).then(setExportImageDataUri)["catch"](function (err) {
setExportImageError(err);
if (enableErrorNotification) {
addNotification((0, _utils.exportImageError)({
err: err
}));
}
});
}
}, 500);
}, [imageSize.imageW, imageSize.imageH, escapeXhtmlForWebpack, setExportImageDataUri, setExportImageError, enableErrorNotification, addNotification]);
var retrieveNewScreenshot = (0, _react.useCallback)(debouncedScreenshot, [debouncedScreenshot]);
var tryScreenshot = (0, _react.useCallback)(function () {
if (mapStyleLoadedRef.current && !deckLayersLoadingRef.current) {
screenshotTakenRef.current = true;
retrieveNewScreenshot();
}
}, [retrieveNewScreenshot]);
// Fallback: if layers never finish loading, capture after timeout
(0, _react.useEffect)(function () {
var timer = setTimeout(function () {
if (!screenshotTakenRef.current) {
deckLayersLoadingRef.current = false;
tryScreenshot();
}
}, 30000);
return function () {
return clearTimeout(timer);
};
}, [tryScreenshot]);
// Memoize the onMapRender callback
var debouncedMapRender = (0, _react.useMemo)(function () {
return (0, _debounce["default"])(function (map) {
if (map.isStyleLoaded()) {
mapStyleLoadedRef.current = true;
tryScreenshot();
}
}, 500);
}, [tryScreenshot]);
var onMapRender = (0, _react.useCallback)(debouncedMapRender, [debouncedMapRender]);
var deckRenderCallbacks = (0, _react.useMemo)(function () {
return {
onDeckAfterRender: function onDeckAfterRender(deckProps) {
var layers = deckProps.layers;
if (!layers) return;
var stillLoading = (0, _reducers.areAnyDeckLayersLoading)(layers);
if (deckLayersLoadingRef.current && !stillLoading) {
deckLayersLoadingRef.current = false;
tryScreenshot();
}
deckLayersLoadingRef.current = stillLoading;
}
};
}, [tryScreenshot]);
// Initial setup effect
(0, _react.useEffect)(function () {
setExportImageSetting({
processing: true
});
}, [setExportImageSetting]);
// Screenshot update effect
(0, _react.useEffect)(function () {
if (ratio !== undefined || resolution !== undefined || legend !== undefined) {
setExportImageSetting({
processing: true
});
tryScreenshot();
}
}, [ratio, resolution, legend, setExportImageSetting, tryScreenshot]);
// Memoize size calculations
var _useMemo = (0, _react.useMemo)(function () {
var size = {
width: imageSize.imageW || 1,
height: imageSize.imageH || 1
};
var isSplit = splitMaps.length > 1;
return {
size: size,
width: size.width / (isSplit ? 2 : 1),
height: size.height
};
}, [imageSize.imageW, imageSize.imageH, splitMaps.length]),
size = _useMemo.size,
width = _useMemo.width,
height = _useMemo.height;
// Memoize map state
var newMapState = (0, _react.useMemo)(function () {
var baseMapState = _objectSpread(_objectSpread({}, mapState), {}, {
width: width,
height: height,
zoom: mapState.zoom + (Math.log2(scale) || 0)
});
if (center) {
var renderedLayers = mapFields.visState.layers.filter(function (layer, idx) {
return layer.id !== _constants.GEOCODER_LAYER_ID && layer.shouldRenderLayer(mapFields.visState.layerData[idx]);
});
var bounds = (0, _reducers.findMapBounds)(renderedLayers);
var centerAndZoom = (0, _utils.getCenterAndZoomFromBounds)(bounds, {
width: width,
height: height
});
if (centerAndZoom) {
var zoom = Number.isFinite(centerAndZoom.zoom) ? centerAndZoom.zoom : mapState.zoom;
return _objectSpread(_objectSpread({}, baseMapState), {}, {
longitude: centerAndZoom.center[0],
latitude: centerAndZoom.center[1],
zoom: zoom + Number(Math.log2(scale) || 0)
});
}
}
return baseMapState;
}, [mapState, width, height, scale, center, mapFields.visState]);
// Memoize map props
var mapProps = (0, _react.useMemo)(function () {
var _mapFields$mapControl;
return _objectSpread(_objectSpread({}, mapFields), {}, {
mapStyle: scaledMapStyle,
mapState: newMapState,
mapControls: {
mapLegend: {
show: Boolean(legend),
active: true,
settings: (_mapFields$mapControl = mapFields.mapControls) === null || _mapFields$mapControl === void 0 || (_mapFields$mapControl = _mapFields$mapControl.mapLegend) === null || _mapFields$mapControl === void 0 ? void 0 : _mapFields$mapControl.settings
}
},
MapComponent: _reactMapGl.Map,
onMapRender: onMapRender,
isExport: true,
deckGlProps: _objectSpread(_objectSpread({}, mapFields.deckGlProps), {}, {
useDevicePixels: false,
deviceProps: {
webgl: {
preserveDrawingBuffer: true
}
}
}),
deckRenderCallbacks: deckRenderCallbacks,
visState: _objectSpread(_objectSpread({}, mapFields.visState), {}, {
effects: plotEffects
}),
// allow overriding the legend panel logo in export
logoComponent: logoComponent
});
}, [mapFields, scaledMapStyle, newMapState, legend, onMapRender, deckRenderCallbacks, plotEffects, logoComponent]);
var isSplit = splitMaps.length > 1;
var mapContainers = !isSplit ? /*#__PURE__*/_react["default"].createElement(MapContainer, (0, _extends2["default"])({
index: 0,
primary: true
}, mapProps)) : /*#__PURE__*/_react["default"].createElement(MapsLayout, {
className: "plot-container-maps",
mapState: newMapState
}, splitMaps.map(function (settings, index) {
return /*#__PURE__*/_react["default"].createElement(MapContainer, (0, _extends2["default"])({
key: index,
index: index,
primary: index === 1
}, mapProps));
}));
return /*#__PURE__*/_react["default"].createElement(StyledPlotContainer, {
className: "export-map-instance",
legendZoom: legendZoom
}, /*#__PURE__*/_react["default"].createElement(StyledMapContainer, {
ref: plottingAreaRef,
width: size.width,
height: size.height
}, /*#__PURE__*/_react["default"].createElement(_mapViewStateContext.MapViewStateContextProvider, {
mapState: newMapState
}, mapContainers)));
}
return /*#__PURE__*/_react["default"].memo(PlotContainer);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc3R5bGVkQ29tcG9uZW50cyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfcmVhY3RNYXBHbCIsIl9kZWJvdW5jZSIsIl91dGlscyIsIl9yZWR1Y2VycyIsIl9tYXBDb250YWluZXIiLCJfbWFwc0xheW91dCIsIl9tYXBWaWV3U3RhdGVDb250ZXh0IiwiX2NvbnN0YW50cyIsIl90ZW1wbGF0ZU9iamVjdCIsIl90ZW1wbGF0ZU9iamVjdDIiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJDTEFTU19GSUxURVIiLCJET01fRklMVEVSX0ZVTkMiLCJub2RlIiwiaW5jbHVkZXMiLCJjbGFzc05hbWUiLCJPVVRfT0ZfU0NSRUVOX1BPU0lUSU9OIiwiY2FsY3VsYXRlTGVnZW5kWm9vbSIsImhlaWdodCIsImJhc2VIZWlnaHQiLCJtaW5ab29tIiwibWF4Wm9vbSIsIk51bWJlciIsImlzRmluaXRlIiwiem9vbUZhY3RvciIsIk1hdGgiLCJtYXgiLCJtaW4iLCJQbG90Q29udGFpbmVyRmFjdG9yeSIsImRlcHMiLCJNYXBDb250YWluZXJGYWN0b3J5IiwiTWFwc0xheW91dEZhY3RvcnkiLCJTdHlsZWRQbG90Q29udGFpbmVyIiwic3R5bGVkIiwiZGl2IiwiX3RhZ2dlZFRlbXBsYXRlTGl0ZXJhbDIiLCJwcm9wcyIsImxlZ2VuZFpvb20iLCJTdHlsZWRNYXBDb250YWluZXIiLCJ3aWR0aCIsIk1hcENvbnRhaW5lciIsIk1hcHNMYXlvdXQiLCJQbG90Q29udGFpbmVyIiwiX3JlZiIsInJhdGlvIiwicmVzb2x1dGlvbiIsIl9yZWYkbGVnZW5kIiwibGVnZW5kIiwiY2VudGVyIiwiaW1hZ2VTaXplIiwiZXNjYXBlWGh0bWxGb3JXZWJwYWNrIiwibWFwRmllbGRzIiwiX3JlZiRzcGxpdE1hcHMiLCJzcGxpdE1hcHMiLCJzZXRFeHBvcnRJbWFnZVNldHRpbmciLCJzZXRFeHBvcnRJbWFnZURhdGFVcmkiLCJzZXRFeHBvcnRJbWFnZUVycm9yIiwiYWRkTm90aWZpY2F0aW9uIiwiZW5hYmxlRXJyb3JOb3RpZmljYXRpb24iLCJsb2dvQ29tcG9uZW50IiwicGxvdHRpbmdBcmVhUmVmIiwidXNlUmVmIiwiX3VzZVN0YXRlIiwidXNlU3RhdGUiLCJ2aXNTdGF0ZSIsImVmZmVjdHMiLCJtYXAiLCJlZmZlY3QiLCJjbG9uZSIsIl91c2VTdGF0ZTIiLCJfc2xpY2VkVG9BcnJheTIiLCJwbG90RWZmZWN0cyIsIm1hcFN0YXRlIiwiZGVja0xheWVyc0xvYWRpbmdSZWYiLCJtYXBTdHlsZUxvYWRlZFJlZiIsInNjcmVlbnNob3RUYWtlblJlZiIsInNjYWxlIiwidXNlTWVtbyIsImNhbGN1bGF0ZWRTY2FsZSIsImdldFNjYWxlRnJvbUltYWdlU2l6ZSIsImltYWdlVyIsImltYWdlSCIsImlzU3BsaXQiLCJzY2FsZWRNYXBTdHlsZSIsIm1hcFN0eWxlIiwiYm90dG9tTWFwU3R5bGUiLCJzY2FsZU1hcFN0eWxlQnlSZXNvbHV0aW9uIiwidG9wTWFwU3R5bGUiLCJkZWJvdW5jZWRTY3JlZW5zaG90IiwiZGVib3VuY2UiLCJjdXJyZW50IiwiY29udmVydFRvUG5nIiwidGhlbiIsImVyciIsImV4cG9ydEltYWdlRXJyb3IiLCJyZXRyaWV2ZU5ld1NjcmVlbnNob3QiLCJ1c2VDYWxsYmFjayIsInRyeVNjcmVlbnNob3QiLCJ1c2VFZmZlY3QiLCJ0aW1lciIsInNldFRpbWVvdXQiLCJjbGVhclRpbWVvdXQiLCJkZWJvdW5jZWRNYXBSZW5kZXIiLCJpc1N0eWxlTG9hZGVkIiwib25NYXBSZW5kZXIiLCJkZWNrUmVuZGVyQ2FsbGJhY2tzIiwib25EZWNrQWZ0ZXJSZW5kZXIiLCJkZWNrUHJvcHMiLCJsYXllcnMiLCJzdGlsbExvYWRpbmciLCJhcmVBbnlEZWNrTGF5ZXJzTG9hZGluZyIsInByb2Nlc3NpbmciLCJ1bmRlZmluZWQiLCJfdXNlTWVtbyIsInNpemUiLCJuZXdNYXBTdGF0ZSIsImJhc2VNYXBTdGF0ZSIsInpvb20iLCJsb2cyIiwicmVuZGVyZWRMYXllcnMiLCJsYXllciIsImlkeCIsImlkIiwiR0VPQ09ERVJfTEFZRVJfSUQiLCJzaG91bGRSZW5kZXJMYXllciIsImxheWVyRGF0YSIsImJvdW5kcyIsImZpbmRNYXBCb3VuZHMiLCJjZW50ZXJBbmRab29tIiwiZ2V0Q2VudGVyQW5kWm9vbUZyb21Cb3VuZHMiLCJsb25naXR1ZGUiLCJsYXRpdHVkZSIsIm1hcFByb3BzIiwiX21hcEZpZWxkcyRtYXBDb250cm9sIiwibWFwQ29udHJvbHMiLCJtYXBMZWdlbmQiLCJzaG93IiwiQm9vbGVhbiIsImFjdGl2ZSIsInNldHRpbmdzIiwiTWFwQ29tcG9uZW50IiwiTWFwIiwiaXNFeHBvcnQiLCJkZWNrR2xQcm9wcyIsInVzZURldmljZVBpeGVscyIsImRldmljZVByb3BzIiwid2ViZ2wiLCJwcmVzZXJ2ZURyYXdpbmdCdWZmZXIiLCJtYXBDb250YWluZXJzIiwiY3JlYXRlRWxlbWVudCIsIl9leHRlbmRzMiIsImluZGV4IiwicHJpbWFyeSIsImtleSIsInJlZiIsIk1hcFZpZXdTdGF0ZUNvbnRleHRQcm92aWRlciIsIlJlYWN0IiwibWVtbyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9wbG90LWNvbnRhaW5lci50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuLy8gbGlicmFyaWVzXG5pbXBvcnQgUmVhY3QsIHt1c2VSZWYsIHVzZUVmZmVjdCwgdXNlU3RhdGUsIHVzZUNhbGxiYWNrLCB1c2VNZW1vfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgc3R5bGVkIGZyb20gJ3N0eWxlZC1jb21wb25lbnRzJztcbmltcG9ydCB7TWFwfSBmcm9tICdyZWFjdC1tYXAtZ2wnO1xuaW1wb3J0IGRlYm91bmNlIGZyb20gJ2xvZGFzaC9kZWJvdW5jZSc7XG5pbXBvcnQge1xuICBleHBvcnRJbWFnZUVycm9yLFxuICBzY2FsZU1hcFN0eWxlQnlSZXNvbHV0aW9uLFxuICBnZXRDZW50ZXJBbmRab29tRnJvbUJvdW5kcyxcbiAgY29udmVydFRvUG5nLFxuICBnZXRTY2FsZUZyb21JbWFnZVNpemVcbn0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQge2ZpbmRNYXBCb3VuZHMsIGFyZUFueURlY2tMYXllcnNMb2FkaW5nfSBmcm9tICdAa2VwbGVyLmdsL3JlZHVjZXJzJztcbmltcG9ydCBNYXBDb250YWluZXJGYWN0b3J5IGZyb20gJy4vbWFwLWNvbnRhaW5lcic7XG5pbXBvcnQgTWFwc0xheW91dEZhY3RvcnkgZnJvbSAnLi9tYXBzLWxheW91dCc7XG5pbXBvcnQge01hcFZpZXdTdGF0ZUNvbnRleHRQcm92aWRlcn0gZnJvbSAnLi9tYXAtdmlldy1zdGF0ZS1jb250ZXh0JztcblxuaW1wb3J0IHtHRU9DT0RFUl9MQVlFUl9JRH0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtFZmZlY3QsIFNwbGl0TWFwLCBFeHBvcnRJbWFnZX0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge1xuICBBY3Rpb25IYW5kbGVyLFxuICBhZGROb3RpZmljYXRpb24sXG4gIHNldEV4cG9ydEltYWdlRGF0YVVyaSxcbiAgc2V0RXhwb3J0SW1hZ2VFcnJvcixcbiAgc2V0RXhwb3J0SW1hZ2VTZXR0aW5nXG59IGZyb20gJ0BrZXBsZXIuZ2wvYWN0aW9ucyc7XG5pbXBvcnQge21hcEZpZWxkc1NlbGVjdG9yfSBmcm9tICcuL2tlcGxlci1nbCc7XG5cbmNvbnN0IENMQVNTX0ZJTFRFUiA9IFtcbiAgJ21hcGxpYnJlZ2wtY29udHJvbC1jb250YWluZXInLFxuICAnbWFwYm94Z2wtY29udHJvbC1jb250YWluZXInLFxuICAnYXR0cml0aW9uLWxpbmsnLFxuICAnYXR0cml0aW9uLWxvZ28nLFxuICAnbWFwLWNvbnRyb2xfX3BhbmVsLXNwbGl0LXZpZXdwb3J0LXRvb2xzJ1xuXTtcbmNvbnN0IERPTV9GSUxURVJfRlVOQyA9IG5vZGUgPT4gIUNMQVNTX0ZJTFRFUi5pbmNsdWRlcyhub2RlLmNsYXNzTmFtZSk7XG5jb25zdCBPVVRfT0ZfU0NSRUVOX1BPU0lUSU9OID0gLTk5OTk7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBsZWdlbmQgem9vbSBiYXNlZCBvbiBleHBvcnQgaGVpZ2h0XG4gKiBNYXBzIGV4cG9ydCBoZWlnaHQgdG8gYSB6b29tIGZhY3RvciBiZXR3ZWVuIDAuNSBhbmQgM1xuICogQHBhcmFtIGhlaWdodCAtIGV4cG9ydCBoZWlnaHQgaW4gcGl4ZWxzXG4gKiBAcmV0dXJucyB6b29tIGZhY3RvciBmb3IgbGVnZW5kIHBhbmVsXG4gKi9cbmZ1bmN0aW9uIGNhbGN1bGF0ZUxlZ2VuZFpvb20oaGVpZ2h0OiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBiYXNlSGVpZ2h0ID0gMTA4MDsgLy8gMXggem9vbSByZWZlcmVuY2UgaGVpZ2h0XG4gIGNvbnN0IG1pblpvb20gPSAwLjU7XG4gIGNvbnN0IG1heFpvb20gPSAzO1xuXG4gIC8vIEZvciBpbml0aWFsL2ludmFsaWQgaGVpZ2h0cywgYXZvaWQgc2hyaW5raW5nIHRoZSBsZWdlbmQ7IHVzZSBubyBzY2FsaW5nLlxuICBpZiAoIU51bWJlci5pc0Zpbml0ZShoZWlnaHQpIHx8IGhlaWdodCA8PSAwKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICAvLyBMaW5lYXIgbWFwcGluZzogaGVpZ2h0IC8gYmFzZUhlaWdodCBnaXZlcyB1cyB0aGUgc2NhbGVcbiAgY29uc3Qgem9vbUZhY3RvciA9IGhlaWdodCAvIGJhc2VIZWlnaHQ7XG4gIC8vIENsYW1wIGJldHdlZW4gbWluIGFuZCBtYXhcbiAgcmV0dXJuIE1hdGgubWF4KG1pblpvb20sIE1hdGgubWluKG1heFpvb20sIHpvb21GYWN0b3IpKTtcbn1cblxuUGxvdENvbnRhaW5lckZhY3RvcnkuZGVwcyA9IFtNYXBDb250YWluZXJGYWN0b3J5LCBNYXBzTGF5b3V0RmFjdG9yeV07XG5cbi8vIFJlbW92ZSBtYXBib3ggbG9nbyBpbiBleHBvcnRlZCBtYXAsIGJlY2F1c2UgaXQgY29udGFpbnMgbm9uLWFzY2lpIGNoYXJhY3RlcnNcbi8vIFJlbW92ZSBzcGxpdCB2aWV3cG9ydCBVSSBjb250cm9scyBmcm9tIGV4cG9ydGVkIGltYWdlcyB3aGVuIHRoZSBsZWdlbmQgaXMgc2hvd25cbmludGVyZmFjZSBTdHlsZWRQbG90Q29udGFpbmVyUHJvcHMge1xuICBsZWdlbmRab29tPzogbnVtYmVyO1xufVxuXG5jb25zdCBTdHlsZWRQbG90Q29udGFpbmVyID0gc3R5bGVkLmRpdjxTdHlsZWRQbG90Q29udGFpbmVyUHJvcHM+YFxuICAubWFwbGlicmVnbC1jdHJsLWJvdHRvbS1sZWZ0LFxuICAubWFwbGlicmVnbC1jdHJsLWJvdHRvbS1yaWdodCxcbiAgLm1hcGxpYnJlLWF0dHJpYnV0aW9uLWNvbnRhaW5lcixcbiAgLm1hcGJveGdsLWN0cmwtYm90dG9tLWxlZnQsXG4gIC5tYXBib3hnbC1jdHJsLWJvdHRvbS1yaWdodCxcbiAgLm1hcGJveC1hdHRyaWJ1dGlvbi1jb250YWluZXIsXG4gIC5tYXAtY29udHJvbF9fcGFuZWwtc3BsaXQtdmlld3BvcnQtdG9vbHMge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogJHtPVVRfT0ZfU0NSRUVOX1BPU0lUSU9OfXB4O1xuICBsZWZ0OiAke09VVF9PRl9TQ1JFRU5fUE9TSVRJT059cHg7XG5cbiAgLyogQXBwbHkgem9vbSB0byBsZWdlbmQgcGFuZWwgYmFzZWQgb24gZXhwb3J0IGhlaWdodCAqL1xuICAubWFwLWNvbnRyb2wtcGFuZWwge1xuICAgIHpvb206ICR7cHJvcHMgPT4gcHJvcHMubGVnZW5kWm9vbSB8fCAxfSAhaW1wb3J0YW50O1xuICB9XG5gO1xuXG5pbnRlcmZhY2UgU3R5bGVkTWFwQ29udGFpbmVyUHJvcHMge1xuICB3aWR0aD86IG51bWJlcjtcbiAgaGVpZ2h0PzogbnVtYmVyO1xufVxuXG5jb25zdCBTdHlsZWRNYXBDb250YWluZXIgPSBzdHlsZWQuZGl2PFN0eWxlZE1hcENvbnRhaW5lclByb3BzPmBcbiAgd2lkdGg6ICR7cHJvcHMgPT4gcHJvcHMud2lkdGh9cHg7XG4gIGhlaWdodDogJHtwcm9wcyA9PiBwcm9wcy5oZWlnaHR9cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG5gO1xuXG5pbnRlcmZhY2UgUGxvdENvbnRhaW5lclByb3BzIHtcbiAgLy8gSW1hZ2UgZXhwb3J0IHNldHRpbmdzXG4gIHJhdGlvPzogc3RyaW5nO1xuICByZXNvbHV0aW9uPzogc3RyaW5nO1xuICBsZWdlbmQ/OiBib29sZWFuO1xuICBjZW50ZXI/OiBib29sZWFuO1xuICBpbWFnZVNpemU6IEV4cG9ydEltYWdlWydpbWFnZVNpemUnXTtcbiAgZXNjYXBlWGh0bWxGb3JXZWJwYWNrPzogYm9vbGVhbjtcblxuICAvLyBNYXAgc2V0dGluZ3NcbiAgbWFwRmllbGRzOiBSZXR1cm5UeXBlPHR5cGVvZiBtYXBGaWVsZHNTZWxlY3Rvcj47XG4gIHNwbGl0TWFwcz86IFNwbGl0TWFwW107XG5cbiAgLy8gQ2FsbGJhY2tzXG4gIHNldEV4cG9ydEltYWdlU2V0dGluZzogdHlwZW9mIHNldEV4cG9ydEltYWdlU2V0dGluZztcbiAgc2V0RXhwb3J0SW1hZ2VEYXRhVXJpOiB0eXBlb2Ygc2V0RXhwb3J0SW1hZ2VEYXRhVXJpO1xuICBzZXRFeHBvcnRJbWFnZUVycm9yOiB0eXBlb2Ygc2V0RXhwb3J0SW1hZ2VFcnJvcjtcbiAgYWRkTm90aWZpY2F0aW9uOiBBY3Rpb25IYW5kbGVyPHR5cGVvZiBhZGROb3RpZmljYXRpb24+O1xuXG4gIC8vIEZsYWdzXG4gIGVuYWJsZUVycm9yTm90aWZpY2F0aW9uPzogYm9vbGVhbjtcblxuICAvLyBPcHRpb25hbDogb3ZlcnJpZGUgbGVnZW5kIGhlYWRlciBsb2dvIGR1cmluZyBleHBvcnRcbiAgbG9nb0NvbXBvbmVudD86IFJlYWN0LlJlYWN0Tm9kZTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUGxvdENvbnRhaW5lckZhY3RvcnkoXG4gIE1hcENvbnRhaW5lcjogUmV0dXJuVHlwZTx0eXBlb2YgTWFwQ29udGFpbmVyRmFjdG9yeT4sXG4gIE1hcHNMYXlvdXQ6IFJldHVyblR5cGU8dHlwZW9mIE1hcHNMYXlvdXRGYWN0b3J5PlxuKTogUmVhY3QuQ29tcG9uZW50VHlwZTxQbG90Q29udGFpbmVyUHJvcHM+IHtcbiAgZnVuY3Rpb24gUGxvdENvbnRhaW5lcih7XG4gICAgLy8gSW1hZ2UgZXhwb3J0IHNldHRpbmdzXG4gICAgcmF0aW8sXG4gICAgcmVzb2x1dGlvbixcbiAgICBsZWdlbmQgPSBmYWxzZSxcbiAgICBjZW50ZXIsXG4gICAgaW1hZ2VTaXplLFxuICAgIGVzY2FwZVhodG1sRm9yV2VicGFjayxcblxuICAgIC8vIE1hcCBzZXR0aW5nc1xuICAgIG1hcEZpZWxkcyxcbiAgICBzcGxpdE1hcHMgPSBbXSxcblxuICAgIC8vIENhbGxiYWNrc1xuICAgIHNldEV4cG9ydEltYWdlU2V0dGluZyxcbiAgICBzZXRFeHBvcnRJbWFnZURhdGFVcmksXG4gICAgc2V0RXhwb3J0SW1hZ2VFcnJvcixcbiAgICBhZGROb3RpZmljYXRpb24sXG5cbiAgICAvLyBGbGFnc1xuICAgIGVuYWJsZUVycm9yTm90aWZpY2F0aW9uLFxuICAgIGxvZ29Db21wb25lbnRcbiAgfTogUGxvdENvbnRhaW5lclByb3BzKSB7XG4gICAgY29uc3QgcGxvdHRpbmdBcmVhUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgICBjb25zdCBbcGxvdEVmZmVjdHNdID0gdXNlU3RhdGU8RWZmZWN0W10+KCgpID0+XG4gICAgICBtYXBGaWVsZHMudmlzU3RhdGUuZWZmZWN0cy5tYXAoZWZmZWN0ID0+IGVmZmVjdC5jbG9uZSgpKVxuICAgICk7XG5cbiAgICBjb25zdCB7bWFwU3RhdGV9ID0gbWFwRmllbGRzO1xuXG4gICAgY29uc3QgZGVja0xheWVyc0xvYWRpbmdSZWYgPSB1c2VSZWYodHJ1ZSk7XG4gICAgY29uc3QgbWFwU3R5bGVMb2FkZWRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICAgIGNvbnN0IHNjcmVlbnNob3RUYWtlblJlZiA9IHVzZVJlZihmYWxzZSk7XG5cbiAgICAvLyBNZW1vaXplIHRoZSBzY2FsZSBjYWxjdWxhdGlvblxuICAgIGNvbnN0IHNjYWxlID0gdXNlTWVtbygoKSA9PiB7XG4gICAgICBpZiAoaW1hZ2VTaXplLnNjYWxlKSB7XG4gICAgICAgIHJldHVybiBpbWFnZVNpemUuc2NhbGU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbGN1bGF0ZWRTY2FsZSA9IGdldFNjYWxlRnJvbUltYWdlU2l6ZShcbiAgICAgICAgaW1hZ2VTaXplLmltYWdlVyxcbiAgICAgICAgaW1hZ2VTaXplLmltYWdlSCxcbiAgICAgICAgbWFwU3RhdGUud2lkdGggKiAobWFwU3RhdGUuaXNTcGxpdCA/IDIgOiAxKSxcbiAgICAgICAgbWFwU3RhdGUuaGVpZ2h0XG4gICAgICApO1xuXG4gICAgICByZXR1cm4gY2FsY3VsYXRlZFNjYWxlID4gMCA/IGNhbGN1bGF0ZWRTY2FsZSA6IDE7XG4gICAgfSwgW1xuICAgICAgaW1hZ2VTaXplLnNjYWxlLFxuICAgICAgaW1hZ2VTaXplLmltYWdlVyxcbiAgICAgIGltYWdlU2l6ZS5pbWFnZUgsXG4gICAgICBtYXBTdGF0ZS53aWR0aCxcbiAgICAgIG1hcFN0YXRlLmhlaWdodCxcbiAgICAgIG1hcFN0YXRlLmlzU3BsaXRcbiAgICBdKTtcblxuICAgIC8vIE1lbW9pemUgdGhlIGxlZ2VuZCB6b29tIGNhbGN1bGF0aW9uIGJhc2VkIG9uIGV4cG9ydCBoZWlnaHRcbiAgICBjb25zdCBsZWdlbmRab29tID0gdXNlTWVtbygoKSA9PiB7XG4gICAgICByZXR1cm4gY2FsY3VsYXRlTGVnZW5kWm9vbShpbWFnZVNpemUuaW1hZ2VIKTtcbiAgICB9LCBbaW1hZ2VTaXplLmltYWdlSF0pO1xuXG4gICAgLy8gTWVtb2l6ZSB0aGUgbWFwIHN0eWxlXG4gICAgY29uc3Qgc2NhbGVkTWFwU3R5bGUgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAgIGNvbnN0IG1hcFN0eWxlID0gbWFwRmllbGRzLm1hcFN0eWxlO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWFwU3R5bGUsXG4gICAgICAgIGJvdHRvbU1hcFN0eWxlOiBzY2FsZU1hcFN0eWxlQnlSZXNvbHV0aW9uKG1hcFN0eWxlLmJvdHRvbU1hcFN0eWxlLCBzY2FsZSksXG4gICAgICAgIHRvcE1hcFN0eWxlOiBzY2FsZU1hcFN0eWxlQnlSZXNvbHV0aW9uKG1hcFN0eWxlLnRvcE1hcFN0eWxlLCBzY2FsZSlcbiAgICAgIH07XG4gICAgfSwgW21hcEZpZWxkcy5tYXBTdHlsZSwgc2NhbGVdKTtcblxuICAgIC8vIE1lbW9pemUgdGhlIHJldHJpZXZlTmV3U2NyZWVuc2hvdCBjYWxsYmFja1xuICAgIGNvbnN0IGRlYm91bmNlZFNjcmVlbnNob3QgPSB1c2VNZW1vKFxuICAgICAgKCkgPT5cbiAgICAgICAgZGVib3VuY2UoKCkgPT4ge1xuICAgICAgICAgIGlmIChwbG90dGluZ0FyZWFSZWYuY3VycmVudCkge1xuICAgICAgICAgICAgY29udmVydFRvUG5nKHBsb3R0aW5nQXJlYVJlZi5jdXJyZW50LCB7XG4gICAgICAgICAgICAgIGZpbHRlcjogRE9NX0ZJTFRFUl9GVU5DLFxuICAgICAgICAgICAgICB3aWR0aDogaW1hZ2VTaXplLmltYWdlVyxcbiAgICAgICAgICAgICAgaGVpZ2h0OiBpbWFnZVNpemUuaW1hZ2VILFxuICAgICAgICAgICAgICBlc2NhcGVYaHRtbEZvcldlYnBhY2tcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC50aGVuKHNldEV4cG9ydEltYWdlRGF0YVVyaSlcbiAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgc2V0RXhwb3J0SW1hZ2VFcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIGlmIChlbmFibGVFcnJvck5vdGlmaWNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgYWRkTm90aWZpY2F0aW9uKGV4cG9ydEltYWdlRXJyb3Ioe2Vycn0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgNTAwKSxcbiAgICAgIFtcbiAgICAgICAgaW1hZ2VTaXplLmltYWdlVyxcbiAgICAgICAgaW1hZ2VTaXplLmltYWdlSCxcbiAgICAgICAgZXNjYXBlWGh0bWxGb3JXZWJwYWNrLFxuICAgICAgICBzZXRFeHBvcnRJbWFnZURhdGFVcmksXG4gICAgICAgIHNldEV4cG9ydEltYWdlRXJyb3IsXG4gICAgICAgIGVuYWJsZUVycm9yTm90aWZpY2F0aW9uLFxuICAgICAgICBhZGROb3RpZmljYXRpb25cbiAgICAgIF1cbiAgICApO1xuXG4gICAgY29uc3QgcmV0cmlldmVOZXdTY3JlZW5zaG90ID0gdXNlQ2FsbGJhY2soZGVib3VuY2VkU2NyZWVuc2hvdCwgW2RlYm91bmNlZFNjcmVlbnNob3RdKTtcblxuICAgIGNvbnN0IHRyeVNjcmVlbnNob3QgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgICBpZiAobWFwU3R5bGVMb2FkZWRSZWYuY3VycmVudCAmJiAhZGVja0xheWVyc0xvYWRpbmdSZWYuY3VycmVudCkge1xuICAgICAgICBzY3JlZW5zaG90VGFrZW5SZWYuY3VycmVudCA9IHRydWU7XG4gICAgICAgIHJldHJpZXZlTmV3U2NyZWVuc2hvdCgpO1xuICAgICAgfVxuICAgIH0sIFtyZXRyaWV2ZU5ld1NjcmVlbnNob3RdKTtcblxuICAgIC8vIEZhbGxiYWNrOiBpZiBsYXllcnMgbmV2ZXIgZmluaXNoIGxvYWRpbmcsIGNhcHR1cmUgYWZ0ZXIgdGltZW91dFxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAoIXNjcmVlbnNob3RUYWtlblJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgZGVja0xheWVyc0xvYWRpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgICAgIHRyeVNjcmVlbnNob3QoKTtcbiAgICAgICAgfVxuICAgICAgfSwgMzAwMDApO1xuICAgICAgcmV0dXJuICgpID0+IGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgfSwgW3RyeVNjcmVlbnNob3RdKTtcblxuICAgIC8vIE1lbW9pemUgdGhlIG9uTWFwUmVuZGVyIGNhbGxiYWNrXG4gICAgY29uc3QgZGVib3VuY2VkTWFwUmVuZGVyID0gdXNlTWVtbyhcbiAgICAgICgpID0+XG4gICAgICAgIGRlYm91bmNlKG1hcCA9PiB7XG4gICAgICAgICAgaWYgKG1hcC5pc1N0eWxlTG9hZGVkKCkpIHtcbiAgICAgICAgICAgIG1hcFN0eWxlTG9hZGVkUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICAgICAgdHJ5U2NyZWVuc2hvdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgNTAwKSxcbiAgICAgIFt0cnlTY3JlZW5zaG90XVxuICAgICk7XG5cbiAgICBjb25zdCBvbk1hcFJlbmRlciA9IHVzZUNhbGxiYWNrKGRlYm91bmNlZE1hcFJlbmRlciwgW2RlYm91bmNlZE1hcFJlbmRlcl0pO1xuXG4gICAgY29uc3QgZGVja1JlbmRlckNhbGxiYWNrcyA9IHVzZU1lbW8oXG4gICAgICAoKSA9PiAoe1xuICAgICAgICBvbkRlY2tBZnRlclJlbmRlcjogKGRlY2tQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgICAgICBjb25zdCBsYXllcnMgPSBkZWNrUHJvcHMubGF5ZXJzIGFzIGFueVtdO1xuICAgICAgICAgIGlmICghbGF5ZXJzKSByZXR1cm47XG4gICAgICAgICAgY29uc3Qgc3RpbGxMb2FkaW5nID0gYXJlQW55RGVja0xheWVyc0xvYWRpbmcobGF5ZXJzKTtcbiAgICAgICAgICBpZiAoZGVja0xheWVyc0xvYWRpbmdSZWYuY3VycmVudCAmJiAhc3RpbGxMb2FkaW5nKSB7XG4gICAgICAgICAgICBkZWNrTGF5ZXJzTG9hZGluZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB0cnlTY3JlZW5zaG90KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlY2tMYXllcnNMb2FkaW5nUmVmLmN1cnJlbnQgPSBzdGlsbExvYWRpbmc7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgW3RyeVNjcmVlbnNob3RdXG4gICAgKTtcblxuICAgIC8vIEluaXRpYWwgc2V0dXAgZWZmZWN0XG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgIHNldEV4cG9ydEltYWdlU2V0dGluZyh7cHJvY2Vzc2luZzogdHJ1ZX0pO1xuICAgIH0sIFtzZXRFeHBvcnRJbWFnZVNldHRpbmddKTtcblxuICAgIC8vIFNjcmVlbnNob3QgdXBkYXRlIGVmZmVjdFxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICBpZiAocmF0aW8gIT09IHVuZGVmaW5lZCB8fCByZXNvbHV0aW9uICE9PSB1bmRlZmluZWQgfHwgbGVnZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2V0RXhwb3J0SW1hZ2VTZXR0aW5nKHtwcm9jZXNzaW5nOiB0cnVlfSk7XG4gICAgICAgIHRyeVNjcmVlbnNob3QoKTtcbiAgICAgIH1cbiAgICB9LCBbcmF0aW8sIHJlc29sdXRpb24sIGxlZ2VuZCwgc2V0RXhwb3J0SW1hZ2VTZXR0aW5nLCB0cnlTY3JlZW5zaG90XSk7XG5cbiAgICAvLyBNZW1vaXplIHNpemUgY2FsY3VsYXRpb25zXG4gICAgY29uc3Qge3NpemUsIHdpZHRoLCBoZWlnaHR9ID0gdXNlTWVtbygoKSA9PiB7XG4gICAgICBjb25zdCBzaXplID0ge1xuICAgICAgICB3aWR0aDogaW1hZ2VTaXplLmltYWdlVyB8fCAxLFxuICAgICAgICBoZWlnaHQ6IGltYWdlU2l6ZS5pbWFnZUggfHwgMVxuICAgICAgfTtcbiAgICAgIGNvbnN0IGlzU3BsaXQgPSBzcGxpdE1hcHMubGVuZ3RoID4gMTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNpemUsXG4gICAgICAgIHdpZHRoOiBzaXplLndpZHRoIC8gKGlzU3BsaXQgPyAyIDogMSksXG4gICAgICAgIGhlaWdodDogc2l6ZS5oZWlnaHRcbiAgICAgIH07XG4gICAgfSwgW2ltYWdlU2l6ZS5pbWFnZVcsIGltYWdlU2l6ZS5pbWFnZUgsIHNwbGl0TWFwcy5sZW5ndGhdKTtcblxuICAgIC8vIE1lbW9pemUgbWFwIHN0YXRlXG4gICAgY29uc3QgbmV3TWFwU3RhdGUgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAgIGNvbnN0IGJhc2VNYXBTdGF0ZSA9IHtcbiAgICAgICAgLi4ubWFwU3RhdGUsXG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIHpvb206IG1hcFN0YXRlLnpvb20gKyAoTWF0aC5sb2cyKHNjYWxlKSB8fCAwKVxuICAgICAgfTtcblxuICAgICAgaWYgKGNlbnRlcikge1xuICAgICAgICBjb25zdCByZW5kZXJlZExheWVycyA9IG1hcEZpZWxkcy52aXNTdGF0ZS5sYXllcnMuZmlsdGVyKFxuICAgICAgICAgIChsYXllciwgaWR4KSA9PlxuICAgICAgICAgICAgbGF5ZXIuaWQgIT09IEdFT0NPREVSX0xBWUVSX0lEICYmXG4gICAgICAgICAgICBsYXllci5zaG91bGRSZW5kZXJMYXllcihtYXBGaWVsZHMudmlzU3RhdGUubGF5ZXJEYXRhW2lkeF0pXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGJvdW5kcyA9IGZpbmRNYXBCb3VuZHMocmVuZGVyZWRMYXllcnMpO1xuICAgICAgICBjb25zdCBjZW50ZXJBbmRab29tID0gZ2V0Q2VudGVyQW5kWm9vbUZyb21Cb3VuZHMoYm91bmRzLCB7d2lkdGgsIGhlaWdodH0pO1xuICAgICAgICBpZiAoY2VudGVyQW5kWm9vbSkge1xuICAgICAgICAgIGNvbnN0IHpvb20gPSBOdW1iZXIuaXNGaW5pdGUoY2VudGVyQW5kWm9vbS56b29tKSA/IGNlbnRlckFuZFpvb20uem9vbSA6IG1hcFN0YXRlLnpvb207XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmJhc2VNYXBTdGF0ZSxcbiAgICAgICAgICAgIGxvbmdpdHVkZTogY2VudGVyQW5kWm9vbS5jZW50ZXJbMF0sXG4gICAgICAgICAgICBsYXRpdHVkZTogY2VudGVyQW5kWm9vbS5jZW50ZXJbMV0sXG4gICAgICAgICAgICB6b29tOiB6b29tICsgTnVtYmVyKE1hdGgubG9nMihzY2FsZSkgfHwgMClcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiYXNlTWFwU3RhdGU7XG4gICAgfSwgW21hcFN0YXRlLCB3aWR0aCwgaGVpZ2h0LCBzY2FsZSwgY2VudGVyLCBtYXBGaWVsZHMudmlzU3RhdGVdKTtcblxuICAgIC8vIE1lbW9pemUgbWFwIHByb3BzXG4gICAgY29uc3QgbWFwUHJvcHMgPSB1c2VNZW1vKFxuICAgICAgKCkgPT4gKHtcbiAgICAgICAgLi4ubWFwRmllbGRzLFxuICAgICAgICBtYXBTdHlsZTogc2NhbGVkTWFwU3R5bGUsXG4gICAgICAgIG1hcFN0YXRlOiBuZXdNYXBTdGF0ZSxcbiAgICAgICAgbWFwQ29udHJvbHM6IHtcbiAgICAgICAgICBtYXBMZWdlbmQ6IHtcbiAgICAgICAgICAgIHNob3c6IEJvb2xlYW4obGVnZW5kKSxcbiAgICAgICAgICAgIGFjdGl2ZTogdHJ1ZSxcbiAgICAgICAgICAgIHNldHRpbmdzOiBtYXBGaWVsZHMubWFwQ29udHJvbHM/Lm1hcExlZ2VuZD8uc2V0dGluZ3NcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIE1hcENvbXBvbmVudDogTWFwLFxuICAgICAgICBvbk1hcFJlbmRlcixcbiAgICAgICAgaXNFeHBvcnQ6IHRydWUsXG4gICAgICAgIGRlY2tHbFByb3BzOiB7XG4gICAgICAgICAgLi4ubWFwRmllbGRzLmRlY2tHbFByb3BzLFxuICAgICAgICAgIHVzZURldmljZVBpeGVsczogZmFsc2UsXG4gICAgICAgICAgZGV2aWNlUHJvcHM6IHtcbiAgICAgICAgICAgIHdlYmdsOiB7XG4gICAgICAgICAgICAgIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZGVja1JlbmRlckNhbGxiYWNrcyxcbiAgICAgICAgdmlzU3RhdGU6IHtcbiAgICAgICAgICAuLi5tYXBGaWVsZHMudmlzU3RhdGUsXG4gICAgICAgICAgZWZmZWN0czogcGxvdEVmZmVjdHNcbiAgICAgICAgfSxcbiAgICAgICAgLy8gYWxsb3cgb3ZlcnJpZGluZyB0aGUgbGVnZW5kIHBhbmVsIGxvZ28gaW4gZXhwb3J0XG4gICAgICAgIGxvZ29Db21wb25lbnRcbiAgICAgIH0pLFxuICAgICAgW1xuICAgICAgICBtYXBGaWVsZHMsXG4gICAgICAgIHNjYWxlZE1hcFN0eWxlLFxuICAgICAgICBuZXdNYXBTdGF0ZSxcbiAgICAgICAgbGVnZW5kLFxuICAgICAgICBvbk1hcFJlbmRlcixcbiAgICAgICAgZGVja1JlbmRlckNhbGxiYWNrcyxcbiAgICAgICAgcGxvdEVmZmVjdHMsXG4gICAgICAgIGxvZ29Db21wb25lbnRcbiAgICAgIF1cbiAgICApO1xuXG4gICAgY29uc3QgaXNTcGxpdCA9IHNwbGl0TWFwcy5sZW5ndGggPiAxO1xuICAgIGNvbnN0IG1hcENvbnRhaW5lcnMgPSAhaXNTcGxpdCA/IChcbiAgICAgIDxNYXBDb250YWluZXIgaW5kZXg9ezB9IHByaW1hcnk9e3RydWV9IHsuLi5tYXBQcm9wc30gLz5cbiAgICApIDogKFxuICAgICAgPE1hcHNMYXlvdXQgY2xhc3NOYW1lPVwicGxvdC1jb250YWluZXItbWFwc1wiIG1hcFN0YXRlPXtuZXdNYXBTdGF0ZX0+XG4gICAgICAgIHtzcGxpdE1hcHMubWFwKChzZXR0aW5ncywgaW5kZXgpID0+IChcbiAgICAgICAgICA8TWFwQ29udGFpbmVyIGtleT17aW5kZXh9IGluZGV4PXtpbmRleH0gcHJpbWFyeT17aW5kZXggPT09IDF9IHsuLi5tYXBQcm9wc30gLz5cbiAgICAgICAgKSl9XG4gICAgICA8L01hcHNMYXlvdXQ+XG4gICAgKTtcblxuICAgIHJldHVybiAoXG4gICAgICA8U3R5bGVkUGxvdENvbnRhaW5lciBjbGFzc05hbWU9XCJleHBvcnQtbWFwLWluc3RhbmNlXCIgbGVnZW5kWm9vbT17bGVnZW5kWm9vbX0+XG4gICAgICAgIDxTdHlsZWRNYXBDb250YWluZXIgcmVmPXtwbG90dGluZ0FyZWFSZWZ9IHdpZHRoPXtzaXplLndpZHRofSBoZWlnaHQ9e3NpemUuaGVpZ2h0fT5cbiAgICAgICAgICA8TWFwVmlld1N0YXRlQ29udGV4dFByb3ZpZGVyIG1hcFN0YXRlPXtuZXdNYXBTdGF0ZX0+XG4gICAgICAgICAgICB7bWFwQ29udGFpbmVyc31cbiAgICAgICAgICA8L01hcFZpZXdTdGF0ZUNvbnRleHRQcm92aWRlcj5cbiAgICAgICAgPC9TdHlsZWRNYXBDb250YWluZXI+XG4gICAgICA8L1N0eWxlZFBsb3RDb250YWluZXI+XG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBSZWFjdC5tZW1vKFBsb3RDb250YWluZXIpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFJQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9B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