kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
23 lines (21 loc) • 37.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.exportMapToHTML = void 0;
var _constants = require("@kepler.gl/constants");
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
/**
* This method is used to create an html file which will inlcude kepler and map data
* @param {Object} options Object that collects all necessary data to create the html file
* @param {string} options.mapboxApiAccessToken Mapbox token used to fetch mapbox tiles
* @param {Array<Object>} options.datasets Data to include in the map
* @param {Object} options.config this object will contain the full kepler.gl instance configuration {mapState, mapStyle, visState}
* @param {string} version which version of Kepler.gl to load.
*/
var exportMapToHTML = exports.exportMapToHTML = function exportMapToHTML(options) {
var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _constants.KEPLER_GL_VERSION;
return "\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"UTF-8\"/>\n <title>Kepler.gl embedded map</title>\n\n <!--Uber Font-->\n <link rel=\"stylesheet\" href=\"https://d1a3f4spazzrp4.cloudfront.net/kepler.gl/uber-fonts/4.0.0/superfine.css\">\n\n <!--Kepler css-->\n <link href=\"https://unpkg.com/kepler.gl@".concat(version, "/umd/keplergl.min.css\" rel=\"stylesheet\">\n\n <!--MapBox css-->\n <link href=\"https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.1/mapbox-gl.css\" rel=\"stylesheet\">\n <link href=\"https://unpkg.com/maplibre-gl@^3/dist/maplibre-gl.css\" rel=\"stylesheet\">\n\n <!-\u2014 facebook open graph tags -->\n <meta property=\"og:url\" content=\"http://kepler.gl/\" />\n <meta property=\"og:title\" content=\"Large-scale WebGL-powered Geospatial Data Visualization Tool\" />\n <meta property=\"og:description\" content=\"Kepler.gl is a powerful web-based geospatial data analysis tool. Built on a high performance rendering engine and designed for large-scale data sets.\" />\n <meta property=\"og:site_name\" content=\"kepler.gl\" />\n <meta property=\"og:image\" content=\"https://d1a3f4spazzrp4.cloudfront.net/kepler.gl/kepler.gl-meta-tag.png\" />\n <meta property=\"og:image:type\" content=\"image/png\" />\n <meta property=\"og:image:width\" content=\"800\" />\n <meta property=\"og:image:height\" content=\"800\" />\n\n <!-\u2014 twitter card tags -->\n <meta name=\"twitter:card\" content=\"summary_large_image\">\n <meta name=\"twitter:site\" content=\"@openjsf\">\n <meta name=\"twitter:creator\" content=\"@openjsf\">\n <meta name=\"twitter:title\" content=\"Large-scale WebGL-powered Geospatial Data Visualization Tool\">\n <meta name=\"twitter:description\" content=\"Kepler.gl is a powerful web-based geospatial data analysis tool. Built on a high performance rendering engine and designed for large-scale data sets.\">\n <meta name=\"twitter:image\" content=\"https://d1a3f4spazzrp4.cloudfront.net/kepler.gl/kepler.gl-meta-tag.png\" />\n\n <!-- Load React/Redux -->\n <script src=\"https://unpkg.com/react@18.3.1/umd/react.production.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/redux@4.2.1/dist/redux.js\" crossorigin></script>\n <script src=\"https://unpkg.com/react-redux@8.1.2/dist/react-redux.min.js\" crossorigin></script>\n <script src=\"https://unpkg.com/styled-components@6.1.8/dist/styled-components.min.js\" crossorigin></script>\n\n <!-- Load Kepler.gl -->\n <script src=\"https://unpkg.com/kepler.gl@").concat(version, "/umd/keplergl.min.js\" crossorigin></script>\n\n <style type=\"text/css\">\n body {margin: 0; padding: 0; overflow: hidden;}\n </style>\n\n <!--MapBox token-->\n <!--\n SECURITY NOTE: Your Mapbox access token is embedded below in plain text.\n Anyone with access to this HTML file can see and use this token.\n Consider using a scoped token with URL restrictions to limit misuse.\n See: https://docs.mapbox.com/accounts/guides/tokens/#url-restrictions\n -->\n <script>\n /**\n * Provide your MapBox Token\n **/\n const MAPBOX_TOKEN = '").concat(options.mapboxApiAccessToken || 'PROVIDE_MAPBOX_TOKEN', "';\n const WARNING_MESSAGE = 'Please Provide a Mapbox Token in order to use Kepler.gl. Edit this file and fill out MAPBOX_TOKEN with your access key';\n </script>\n\n <!-- GA: Delete this as you wish, However to pat ourselves on the back, we only track anonymous pageview to understand how many people are using kepler.gl. -->\n <script>\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');\n ga('create', 'UA-64694404-19', {\n 'storage': 'none',\n 'clientId': localStorage.getItem('ga:clientId')\n });\n ga(function(tracker) {\n localStorage.setItem('ga:clientId', tracker.get('clientId'));\n });\n ga('set', 'checkProtocolTask', null); // Disable file protocol checking.\n ga('set', 'checkStorageTask', null); // Disable cookie storage checking.\n ga('set', 'historyImportTask', null); // Disable history checking (requires reading from cookies).\n ga('set', 'page', 'keplergl-html');\n ga('send', 'pageview');\n </script>\n </head>\n <body>\n <!-- We will put our React component inside this div. -->\n <div id=\"app\">\n <!-- Kepler.gl map will be placed here-->\n </div>\n\n <!-- Load our React component. -->\n <script>\n /* Validate Mapbox Token */\n if ((MAPBOX_TOKEN || '') === '' || MAPBOX_TOKEN === 'PROVIDE_MAPBOX_TOKEN') {\n alert(WARNING_MESSAGE);\n }\n\n /** STORE **/\n const reducers = (function createReducers(redux, keplerGl) {\n return redux.combineReducers({\n // mount keplerGl reducer\n keplerGl: keplerGl.keplerGlReducer.initialState({\n uiState: {\n readOnly: ").concat(options.mode === _constants.EXPORT_HTML_MAP_MODES.READ, ",\n currentModal: null\n }\n })\n });\n }(Redux, KeplerGl));\n\n const middleWares = (function createMiddlewares(keplerGl) {\n return keplerGl.enhanceReduxMiddleware([\n // Add other middlewares here\n ]);\n }(KeplerGl));\n\n const enhancers = (function craeteEnhancers(redux, middles) {\n return redux.applyMiddleware(...middles);\n }(Redux, middleWares));\n\n const store = (function createStore(redux, enhancers) {\n const initialState = {};\n\n return redux.createStore(\n reducers,\n initialState,\n redux.compose(enhancers)\n );\n }(Redux, enhancers));\n /** END STORE **/\n\n /** COMPONENTS **/\n var KeplerElement = (function makeKeplerElement(react, keplerGl, mapboxToken) {\n var LogoSvg = function LogoSvg() {\n return react.createElement(\n \"div\",\n { className: \"logo-container\", style: {position: 'fixed', zIndex: 10000, padding: '4px'} },\n react.createElement(\n \"svg\",\n {\n className: \"kepler_gl__logo\",\n width: \"107px\",\n height: \"21px\",\n viewBox: \"0 0 124 24\"\n },\n react.createElement(\n \"g\",\n { transform: \"translate(13.500000, 13.500000) rotate(45.000000) translate(-13.500000, -13.500000) translate(4.000000, 4.000000)\" },\n react.createElement(\"rect\", { x: \"0\", y: \"6\", transform: \"matrix(2.535181e-06 1 -1 2.535181e-06 18.1107 6.0369)\", fill: \"#535C6C\", width: \"12.1\", height: \"12.1\" }),\n react.createElement(\"rect\", { x: \"6\", y: \"0\", transform: \"matrix(2.535182e-06 1 -1 2.535182e-06 18.1107 -6.0369)\", fill:\"#1FBAD6\", width: \"12.1\", height: \"12.1\" })\n ),\n react.createElement(\n \"g\",\n {},\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M39,8.7h2.2l-2.8,4.2l2.9,5.1H39l-2.4-4.2h-1.3V18h-2V5l2-0.1v7.3h1.3L39,8.7z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M42.4,13.3c0-1.5,0.4-2.7,1.1-3.5s1.8-1.2,3.1-1.2c1.3,0,2.2,0.4,2.8,1.1c0.6,0.7,0.9,1.8,0.9,3.3 c0,0.4,0,0.8,0,1.1h-5.8c0,1.6,0.8,2.4,2.4,2.4c1,0,2-0.2,2.9-0.6l0.2,1.7c-0.4,0.2-0.9,0.4-1.4,0.5s-1.1,0.2-1.7,0.2 c-1.5,0-2.6-0.4-3.3-1.2C42.8,16.1,42.4,14.9,42.4,13.3z M46.6,10.1c-0.7,0-1.2,0.2-1.5,0.5c-0.4,0.4-0.6,0.9-0.6,1.7h4 c0-0.8-0.2-1.4-0.5-1.7S47.2,10.1,46.6,10.1z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M57.1,18.2c-1,0-1.8-0.3-2.3-0.9l0,0l0,1.3v2.5h-2V8.7h1.5l0.3,0.9h0c0.3-0.3,0.7-0.6,1.2-0.7 c0.4-0.2,0.9-0.3,1.4-0.3c1.2,0,2.1,0.4,2.7,1.1c0.6,0.7,0.9,2,0.9,3.7c0,1.6-0.3,2.8-1,3.7C59.2,17.8,58.3,18.2,57.1,18.2z M56.7,10.3c-0.4,0-0.8,0.1-1.1,0.2c-0.3,0.2-0.6,0.4-0.8,0.7v4.3c0.2,0.3,0.4,0.5,0.7,0.7c0.3,0.2,0.7,0.3,1.1,0.3 c0.7,0,1.2-0.2,1.6-0.7c0.4-0.5,0.5-1.3,0.5-2.5c0-0.8-0.1-1.4-0.2-1.8s-0.4-0.7-0.7-0.9C57.6,10.4,57.2,10.3,56.7,10.3z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M63.2,16V5l2-0.1v10.8c0,0.3,0.1,0.5,0.2,0.6c0.1,0.1,0.3,0.2,0.6,0.2c0.3,0,0.6,0,0.9-0.1V18 c-0.4,0.1-1,0.2-1.6,0.2c-0.8,0-1.3-0.2-1.7-0.5S63.2,16.8,63.2,16z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M68.2,13.3c0-1.5,0.4-2.7,1.1-3.5c0.7-0.8,1.8-1.2,3.1-1.2c1.3,0,2.2,0.4,2.8,1.1c0.6,0.7,0.9,1.8,0.9,3.3 c0,0.4,0,0.8,0,1.1h-5.8c0,1.6,0.8,2.4,2.4,2.4c1,0,2-0.2,2.9-0.6l0.2,1.7c-0.4,0.2-0.9,0.4-1.4,0.5s-1.1,0.2-1.7,0.2 c-1.5,0-2.6-0.4-3.3-1.2C68.6,16.1,68.2,14.9,68.2,13.3z M72.4,10.1c-0.7,0-1.2,0.2-1.5,0.5c-0.4,0.4-0.6,0.9-0.6,1.7h4 c0-0.8-0.2-1.4-0.5-1.7S73,10.1,72.4,10.1z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M80.2,8.7l0.1,1.7h0c0.3-0.6,0.7-1.1,1.1-1.4c0.4-0.3,1-0.5,1.6-0.5c0.4,0,0.7,0,1,0.1l-0.1,2 c-0.3-0.1-0.7-0.2-1-0.2c-0.7,0-1.3,0.3-1.7,0.8c-0.4,0.5-0.7,1.2-0.7,2.1V18h-2V8.7H80.2z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M83.8,17c0-0.8,0.4-1.2,1.2-1.2c0.8,0,1.2,0.4,1.2,1.2c0,0.8-0.4,1.1-1.2,1.1C84.2,18.2,83.8,17.8,83.8,17z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M88.5,18.7c0-0.8,0.4-1.4,1.2-1.8c-0.6-0.3-0.9-0.8-0.9-1.5c0-0.7,0.4-1.2,1.1-1.6c-0.3-0.3-0.6-0.6-0.7-0.9 c-0.2-0.4-0.2-0.8-0.2-1.3c0-1,0.3-1.8,0.9-2.3c0.6-0.5,1.6-0.8,2.8-0.8c0.5,0,1,0,1.4,0.1c0.4,0.1,0.8,0.2,1.1,0.4l2.4-0.2v1.5 h-1.5c0.2,0.4,0.2,0.8,0.2,1.3c0,1-0.3,1.7-0.9,2.2s-1.5,0.8-2.7,0.8c-0.7,0-1.2-0.1-1.6-0.2c-0.1,0.1-0.2,0.2-0.3,0.3 c-0.1,0.1-0.1,0.2-0.1,0.4c0,0.2,0.1,0.3,0.2,0.4c0.1,0.1,0.3,0.2,0.6,0.2l2.7,0.2c1,0.1,1.7,0.3,2.2,0.6c0.5,0.3,0.8,0.9,0.8,1.7 c0,0.6-0.2,1.1-0.5,1.5c-0.4,0.4-0.9,0.8-1.5,1c-0.7,0.2-1.5,0.4-2.4,0.4c-1.3,0-2.3-0.2-3-0.6C88.8,20.1,88.5,19.5,88.5,18.7z M95.1,18.4c0-0.3-0.1-0.5-0.3-0.7s-0.6-0.2-1.1-0.3l-2.7-0.3c-0.2,0.1-0.4,0.3-0.5,0.5c-0.1,0.2-0.2,0.4-0.2,0.6 c0,0.4,0.2,0.8,0.5,1c0.4,0.2,1,0.3,1.8,0.3C94.2,19.5,95.1,19.2,95.1,18.4z M94.3,11.5c0-0.6-0.1-1-0.4-1.2 c-0.3-0.2-0.7-0.3-1.3-0.3c-0.7,0-1.1,0.1-1.4,0.3c-0.3,0.2-0.4,0.6-0.4,1.2s0.1,1,0.4,1.2c0.3,0.2,0.7,0.3,1.4,0.3 c0.6,0,1.1-0.1,1.3-0.4S94.3,12,94.3,11.5z\" }),\n react.createElement(\"path\", { fill:\"#1FBAD6\", d: \"M99.4,16V5l2-0.1v10.8c0,0.3,0.1,0.5,0.2,0.6c0.1,0.1,0.3,0.2,0.6,0.2c0.3,0,0.6,0,0.9-0.1V18 c-0.4,0.1-1,0.2-1.6,0.2c-0.8,0-1.3-0.2-1.7-0.5S99.4,16.8,99.4,16z\" })\n )\n )\n );\n };\n\n return function App() {\n var rootElm = react.useRef(null);\n var _useState = react.useState({\n width: window.innerWidth,\n height: window.innerHeight\n });\n var windowDimension = _useState[0];\n var setDimension = _useState[1];\n react.useEffect(function sideEffect(){\n function handleResize() {\n setDimension({width: window.innerWidth, height: window.innerHeight});\n };\n window.addEventListener('resize', handleResize);\n return function() {window.removeEventListener('resize', handleResize);};\n }, []);\n return react.createElement(\n 'div',\n {style: {position: 'absolute', left: 0, width: '100vw', height: '100vh'}},\n ").concat(options.mode === _constants.EXPORT_HTML_MAP_MODES.READ ? 'LogoSvg(),' : '', "\n react.createElement(keplerGl.KeplerGl, {\n mapboxApiAccessToken: mapboxToken,\n id: \"map\",\n width: windowDimension.width,\n height: windowDimension.height\n })\n )\n }\n }(React, KeplerGl, MAPBOX_TOKEN));\n\n const app = (function createReactReduxProvider(react, reactRedux, KeplerElement) {\n return react.createElement(\n reactRedux.Provider,\n {store},\n react.createElement(KeplerElement, null)\n )\n }(React, ReactRedux, KeplerElement));\n /** END COMPONENTS **/\n\n /** Render **/\n (function render(react, reactDOM, app) {\n const container = document.getElementById('app');\n const root = reactDOM.createRoot(container);\n root.render(app);\n }(React, ReactDOM, app));\n </script>\n <!-- The next script will show how to interact directly with Kepler map store -->\n <script>\n /**\n * Customize map.\n * In the following section you can use the store object to dispatch Kepler.gl actions\n * to add new data and customize behavior\n */\n (function customize(keplerGl, store) {\n const datasets = ").concat(JSON.stringify(options.datasets), ";\n const config = ").concat(JSON.stringify(options.config), ";\n\n const loadedData = keplerGl.KeplerGlSchema.load(\n datasets,\n config\n );\n\n // For some reason Kepler overwrites the config without extra wait time\n window.setTimeout(() => {\n store.dispatch(\n keplerGl.addDataToMap({\n datasets: loadedData.datasets,\n config: loadedData.config,\n options: {\n centerMap: false,\n },\n })\n );\n }, 500);\n }(KeplerGl, store))\n </script>\n </body>\n </html>\n ");
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc3RhbnRzIiwicmVxdWlyZSIsImV4cG9ydE1hcFRvSFRNTCIsImV4cG9ydHMiLCJvcHRpb25zIiwidmVyc2lvbiIsImFyZ3VtZW50cyIsImxlbmd0aCIsInVuZGVmaW5lZCIsIktFUExFUl9HTF9WRVJTSU9OIiwiY29uY2F0IiwibWFwYm94QXBpQWNjZXNzVG9rZW4iLCJtb2RlIiwiRVhQT1JUX0hUTUxfTUFQX01PREVTIiwiUkVBRCIsIkpTT04iLCJzdHJpbmdpZnkiLCJkYXRhc2V0cyIsImNvbmZpZyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9leHBvcnQtbWFwLWh0bWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHtFWFBPUlRfSFRNTF9NQVBfTU9ERVMsIEtFUExFUl9HTF9WRVJTSU9OfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBjcmVhdGUgYW4gaHRtbCBmaWxlIHdoaWNoIHdpbGwgaW5sY3VkZSBrZXBsZXIgYW5kIG1hcCBkYXRhXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPYmplY3QgdGhhdCBjb2xsZWN0cyBhbGwgbmVjZXNzYXJ5IGRhdGEgdG8gIGNyZWF0ZSB0aGUgaHRtbCBmaWxlXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5tYXBib3hBcGlBY2Nlc3NUb2tlbiBNYXBib3ggdG9rZW4gdXNlZCB0byBmZXRjaCBtYXBib3ggdGlsZXNcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gb3B0aW9ucy5kYXRhc2V0cyBEYXRhIHRvIGluY2x1ZGUgaW4gdGhlIG1hcFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuY29uZmlnIHRoaXMgb2JqZWN0IHdpbGwgY29udGFpbiB0aGUgZnVsbCBrZXBsZXIuZ2wgaW5zdGFuY2UgY29uZmlndXJhdGlvbiB7bWFwU3RhdGUsIG1hcFN0eWxlLCB2aXNTdGF0ZX1cbiAqIEBwYXJhbSB7c3RyaW5nfSB2ZXJzaW9uIHdoaWNoIHZlcnNpb24gb2YgS2VwbGVyLmdsIHRvIGxvYWQuXG4gKi9cbmV4cG9ydCBjb25zdCBleHBvcnRNYXBUb0hUTUwgPSAob3B0aW9ucywgdmVyc2lvbiA9IEtFUExFUl9HTF9WRVJTSU9OKSA9PiB7XG4gIHJldHVybiBgXG4gICAgPCFET0NUWVBFIGh0bWw+XG4gICAgPGh0bWw+XG4gICAgICA8aGVhZD5cbiAgICAgICAgPG1ldGEgY2hhcnNldD1cIlVURi04XCIvPlxuICAgICAgICA8dGl0bGU+S2VwbGVyLmdsIGVtYmVkZGVkIG1hcDwvdGl0bGU+XG5cbiAgICAgICAgPCEtLVViZXIgRm9udC0tPlxuICAgICAgICA8bGluayByZWw9XCJzdHlsZXNoZWV0XCIgaHJlZj1cImh0dHBzOi8vZDFhM2Y0c3BhenpycDQuY2xvdWRmcm9udC5uZXQva2VwbGVyLmdsL3ViZXItZm9udHMvNC4wLjAvc3VwZXJmaW5lLmNzc1wiPlxuXG4gICAgICAgIDwhLS1LZXBsZXIgY3NzLS0+XG4gICAgICAgIDxsaW5rIGhyZWY9XCJodHRwczovL3VucGtnLmNvbS9rZXBsZXIuZ2xAJHt2ZXJzaW9ufS91bWQva2VwbGVyZ2wubWluLmNzc1wiIHJlbD1cInN0eWxlc2hlZXRcIj5cblxuICAgICAgICA8IS0tTWFwQm94IGNzcy0tPlxuICAgICAgICA8bGluayBocmVmPVwiaHR0cHM6Ly9hcGkudGlsZXMubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvdjEuMS4xL21hcGJveC1nbC5jc3NcIiByZWw9XCJzdHlsZXNoZWV0XCI+XG4gICAgICAgIDxsaW5rIGhyZWY9XCJodHRwczovL3VucGtnLmNvbS9tYXBsaWJyZS1nbEBeMy9kaXN0L21hcGxpYnJlLWdsLmNzc1wiIHJlbD1cInN0eWxlc2hlZXRcIj5cblxuICAgICAgICA8IS3igJQgZmFjZWJvb2sgb3BlbiBncmFwaCB0YWdzIC0tPlxuICAgICAgICA8bWV0YSBwcm9wZXJ0eT1cIm9nOnVybFwiIGNvbnRlbnQ9XCJodHRwOi8va2VwbGVyLmdsL1wiIC8+XG4gICAgICAgIDxtZXRhIHByb3BlcnR5PVwib2c6dGl0bGVcIiBjb250ZW50PVwiTGFyZ2Utc2NhbGUgV2ViR0wtcG93ZXJlZCBHZW9zcGF0aWFsIERhdGEgVmlzdWFsaXphdGlvbiBUb29sXCIgLz5cbiAgICAgICAgPG1ldGEgcHJvcGVydHk9XCJvZzpkZXNjcmlwdGlvblwiIGNvbnRlbnQ9XCJLZXBsZXIuZ2wgaXMgYSBwb3dlcmZ1bCB3ZWItYmFzZWQgZ2Vvc3BhdGlhbCBkYXRhIGFuYWx5c2lzIHRvb2wuIEJ1aWx0IG9uIGEgaGlnaCBwZXJmb3JtYW5jZSByZW5kZXJpbmcgZW5naW5lIGFuZCBkZXNpZ25lZCBmb3IgbGFyZ2Utc2NhbGUgZGF0YSBzZXRzLlwiIC8+XG4gICAgICAgIDxtZXRhIHByb3BlcnR5PVwib2c6c2l0ZV9uYW1lXCIgY29udGVudD1cImtlcGxlci5nbFwiIC8+XG4gICAgICAgIDxtZXRhIHByb3BlcnR5PVwib2c6aW1hZ2VcIiBjb250ZW50PVwiaHR0cHM6Ly9kMWEzZjRzcGF6enJwNC5jbG91ZGZyb250Lm5ldC9rZXBsZXIuZ2wva2VwbGVyLmdsLW1ldGEtdGFnLnBuZ1wiIC8+XG4gICAgICAgIDxtZXRhIHByb3BlcnR5PVwib2c6aW1hZ2U6dHlwZVwiIGNvbnRlbnQ9XCJpbWFnZS9wbmdcIiAvPlxuICAgICAgICA8bWV0YSBwcm9wZXJ0eT1cIm9nOmltYWdlOndpZHRoXCIgY29udGVudD1cIjgwMFwiIC8+XG4gICAgICAgIDxtZXRhIHByb3BlcnR5PVwib2c6aW1hZ2U6aGVpZ2h0XCIgY29udGVudD1cIjgwMFwiIC8+XG5cbiAgICAgICAgPCEt4oCUIHR3aXR0ZXIgY2FyZCB0YWdzIC0tPlxuICAgICAgICA8bWV0YSBuYW1lPVwidHdpdHRlcjpjYXJkXCIgY29udGVudD1cInN1bW1hcnlfbGFyZ2VfaW1hZ2VcIj5cbiAgICAgICAgPG1ldGEgbmFtZT1cInR3aXR0ZXI6c2l0ZVwiIGNvbnRlbnQ9XCJAb3BlbmpzZlwiPlxuICAgICAgICA8bWV0YSBuYW1lPVwidHdpdHRlcjpjcmVhdG9yXCIgY29udGVudD1cIkBvcGVuanNmXCI+XG4gICAgICAgIDxtZXRhIG5hbWU9XCJ0d2l0dGVyOnRpdGxlXCIgY29udGVudD1cIkxhcmdlLXNjYWxlIFdlYkdMLXBvd2VyZWQgR2Vvc3BhdGlhbCBEYXRhIFZpc3VhbGl6YXRpb24gVG9vbFwiPlxuICAgICAgICA8bWV0YSBuYW1lPVwidHdpdHRlcjpkZXNjcmlwdGlvblwiIGNvbnRlbnQ9XCJLZXBsZXIuZ2wgaXMgYSBwb3dlcmZ1bCB3ZWItYmFzZWQgZ2Vvc3BhdGlhbCBkYXRhIGFuYWx5c2lzIHRvb2wuIEJ1aWx0IG9uIGEgaGlnaCBwZXJmb3JtYW5jZSByZW5kZXJpbmcgZW5naW5lIGFuZCBkZXNpZ25lZCBmb3IgbGFyZ2Utc2NhbGUgZGF0YSBzZXRzLlwiPlxuICAgICAgICA8bWV0YSBuYW1lPVwidHdpdHRlcjppbWFnZVwiIGNvbnRlbnQ9XCJodHRwczovL2QxYTNmNHNwYXp6cnA0LmNsb3VkZnJvbnQubmV0L2tlcGxlci5nbC9rZXBsZXIuZ2wtbWV0YS10YWcucG5nXCIgLz5cblxuICAgICAgICA8IS0tIExvYWQgUmVhY3QvUmVkdXggLS0+XG4gICAgICAgIDxzY3JpcHQgc3JjPVwiaHR0cHM6Ly91bnBrZy5jb20vcmVhY3RAMTguMy4xL3VtZC9yZWFjdC5wcm9kdWN0aW9uLm1pbi5qc1wiIGNyb3Nzb3JpZ2luPjwvc2NyaXB0PlxuICAgICAgICA8c2NyaXB0IHNyYz1cImh0dHBzOi8vdW5wa2cuY29tL3JlYWN0LWRvbUAxOC4zLjEvdW1kL3JlYWN0LWRvbS5wcm9kdWN0aW9uLm1pbi5qc1wiIGNyb3Nzb3JpZ2luPjwvc2NyaXB0PlxuICAgICAgICA8c2NyaXB0IHNyYz1cImh0dHBzOi8vdW5wa2cuY29tL3JlZHV4QDQuMi4xL2Rpc3QvcmVkdXguanNcIiBjcm9zc29yaWdpbj48L3NjcmlwdD5cbiAgICAgICAgPHNjcmlwdCBzcmM9XCJodHRwczovL3VucGtnLmNvbS9yZWFjdC1yZWR1eEA4LjEuMi9kaXN0L3JlYWN0LXJlZHV4Lm1pbi5qc1wiIGNyb3Nzb3JpZ2luPjwvc2NyaXB0PlxuICAgICAgICA8c2NyaXB0IHNyYz1cImh0dHBzOi8vdW5wa2cuY29tL3N0eWxlZC1jb21wb25lbnRzQDYuMS44L2Rpc3Qvc3R5bGVkLWNvbXBvbmVudHMubWluLmpzXCIgY3Jvc3NvcmlnaW4+PC9zY3JpcHQ+XG5cbiAgICAgICAgPCEtLSBMb2FkIEtlcGxlci5nbCAtLT5cbiAgICAgICAgPHNjcmlwdCBzcmM9XCJodHRwczovL3VucGtnLmNvbS9rZXBsZXIuZ2xAJHt2ZXJzaW9ufS91bWQva2VwbGVyZ2wubWluLmpzXCIgY3Jvc3NvcmlnaW4+PC9zY3JpcHQ+XG5cbiAgICAgICAgPHN0eWxlIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgIGJvZHkge21hcmdpbjogMDsgcGFkZGluZzogMDsgb3ZlcmZsb3c6IGhpZGRlbjt9XG4gICAgICAgIDwvc3R5bGU+XG5cbiAgICAgICAgPCEtLU1hcEJveCB0b2tlbi0tPlxuICAgICAgICA8IS0tXG4gICAgICAgICAgU0VDVVJJVFkgTk9URTogWW91ciBNYXBib3ggYWNjZXNzIHRva2VuIGlzIGVtYmVkZGVkIGJlbG93IGluIHBsYWluIHRleHQuXG4gICAgICAgICAgQW55b25lIHdpdGggYWNjZXNzIHRvIHRoaXMgSFRNTCBmaWxlIGNhbiBzZWUgYW5kIHVzZSB0aGlzIHRva2VuLlxuICAgICAgICAgIENvbnNpZGVyIHVzaW5nIGEgc2NvcGVkIHRva2VuIHdpdGggVVJMIHJlc3RyaWN0aW9ucyB0byBsaW1pdCBtaXN1c2UuXG4gICAgICAgICAgU2VlOiBodHRwczovL2RvY3MubWFwYm94LmNvbS9hY2NvdW50cy9ndWlkZXMvdG9rZW5zLyN1cmwtcmVzdHJpY3Rpb25zXG4gICAgICAgIC0tPlxuICAgICAgICA8c2NyaXB0PlxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFByb3ZpZGUgeW91ciBNYXBCb3ggVG9rZW5cbiAgICAgICAgICAgKiovXG4gICAgICAgICAgY29uc3QgTUFQQk9YX1RPS0VOID0gJyR7b3B0aW9ucy5tYXBib3hBcGlBY2Nlc3NUb2tlbiB8fCAnUFJPVklERV9NQVBCT1hfVE9LRU4nfSc7XG4gICAgICAgICAgY29uc3QgV0FSTklOR19NRVNTQUdFID0gJ1BsZWFzZSBQcm92aWRlIGEgTWFwYm94IFRva2VuIGluIG9yZGVyIHRvIHVzZSBLZXBsZXIuZ2wuIEVkaXQgdGhpcyBmaWxlIGFuZCBmaWxsIG91dCBNQVBCT1hfVE9LRU4gd2l0aCB5b3VyIGFjY2VzcyBrZXknO1xuICAgICAgICA8L3NjcmlwdD5cblxuICAgICAgICA8IS0tIEdBOiBEZWxldGUgdGhpcyBhcyB5b3Ugd2lzaCwgSG93ZXZlciB0byBwYXQgb3Vyc2VsdmVzIG9uIHRoZSBiYWNrLCB3ZSBvbmx5IHRyYWNrIGFub255bW91cyBwYWdldmlldyB0byB1bmRlcnN0YW5kIGhvdyBtYW55IHBlb3BsZSBhcmUgdXNpbmcga2VwbGVyLmdsLiAtLT5cbiAgICAgICAgPHNjcmlwdD5cbiAgICAgICAgICAoZnVuY3Rpb24oaSxzLG8sZyxyLGEsbSl7aVsnR29vZ2xlQW5hbHl0aWNzT2JqZWN0J109cjtpW3JdPWlbcl18fGZ1bmN0aW9uKCl7XG4gICAgICAgICAgKGlbcl0ucT1pW3JdLnF8fFtdKS5wdXNoKGFyZ3VtZW50cyl9LGlbcl0ubD0xKm5ldyBEYXRlKCk7YT1zLmNyZWF0ZUVsZW1lbnQobyksXG4gICAgICAgICAgbT1zLmdldEVsZW1lbnRzQnlUYWdOYW1lKG8pWzBdO2EuYXN5bmM9MTthLnNyYz1nO20ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoYSxtKVxuICAgICAgICAgIH0pKHdpbmRvdyxkb2N1bWVudCwnc2NyaXB0JywnaHR0cHM6Ly93d3cuZ29vZ2xlLWFuYWx5dGljcy5jb20vYW5hbHl0aWNzLmpzJywnZ2EnKTtcbiAgICAgICAgICBnYSgnY3JlYXRlJywgJ1VBLTY0Njk0NDA0LTE5Jywge1xuICAgICAgICAgICAgJ3N0b3JhZ2UnOiAnbm9uZScsXG4gICAgICAgICAgICAnY2xpZW50SWQnOiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZ2E6Y2xpZW50SWQnKVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGdhKGZ1bmN0aW9uKHRyYWNrZXIpIHtcbiAgICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2dhOmNsaWVudElkJywgdHJhY2tlci5nZXQoJ2NsaWVudElkJykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGdhKCdzZXQnLCAnY2hlY2tQcm90b2NvbFRhc2snLCBudWxsKTsgLy8gRGlzYWJsZSBmaWxlIHByb3RvY29sIGNoZWNraW5nLlxuICAgICAgICAgIGdhKCdzZXQnLCAnY2hlY2tTdG9yYWdlVGFzaycsIG51bGwpOyAvLyBEaXNhYmxlIGNvb2tpZSBzdG9yYWdlIGNoZWNraW5nLlxuICAgICAgICAgIGdhKCdzZXQnLCAnaGlzdG9yeUltcG9ydFRhc2snLCBudWxsKTsgLy8gRGlzYWJsZSBoaXN0b3J5IGNoZWNraW5nIChyZXF1aXJlcyByZWFkaW5nIGZyb20gY29va2llcykuXG4gICAgICAgICAgZ2EoJ3NldCcsICdwYWdlJywgJ2tlcGxlcmdsLWh0bWwnKTtcbiAgICAgICAgICBnYSgnc2VuZCcsICdwYWdldmlldycpO1xuICAgICAgICA8L3NjcmlwdD5cbiAgICAgIDwvaGVhZD5cbiAgICAgIDxib2R5PlxuICAgICAgICA8IS0tIFdlIHdpbGwgcHV0IG91ciBSZWFjdCBjb21wb25lbnQgaW5zaWRlIHRoaXMgZGl2LiAtLT5cbiAgICAgICAgPGRpdiBpZD1cImFwcFwiPlxuICAgICAgICAgIDwhLS0gS2VwbGVyLmdsIG1hcCB3aWxsIGJlIHBsYWNlZCBoZXJlLS0+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gTG9hZCBvdXIgUmVhY3QgY29tcG9uZW50LiAtLT5cbiAgICAgICAgPHNjcmlwdD5cbiAgICAgICAgICAvKiBWYWxpZGF0ZSBNYXBib3ggVG9rZW4gKi9cbiAgICAgICAgICBpZiAoKE1BUEJPWF9UT0tFTiB8fCAnJykgPT09ICcnIHx8IE1BUEJPWF9UT0tFTiA9PT0gJ1BST1ZJREVfTUFQQk9YX1RPS0VOJykge1xuICAgICAgICAgICAgYWxlcnQoV0FSTklOR19NRVNTQUdFKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvKiogU1RPUkUgKiovXG4gICAgICAgICAgY29uc3QgcmVkdWNlcnMgPSAoZnVuY3Rpb24gY3JlYXRlUmVkdWNlcnMocmVkdXgsIGtlcGxlckdsKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVkdXguY29tYmluZVJlZHVjZXJzKHtcbiAgICAgICAgICAgICAgLy8gbW91bnQga2VwbGVyR2wgcmVkdWNlclxuICAgICAgICAgICAgICBrZXBsZXJHbDoga2VwbGVyR2wua2VwbGVyR2xSZWR1Y2VyLmluaXRpYWxTdGF0ZSh7XG4gICAgICAgICAgICAgICAgdWlTdGF0ZToge1xuICAgICAgICAgICAgICAgICAgcmVhZE9ubHk6ICR7b3B0aW9ucy5tb2RlID09PSBFWFBPUlRfSFRNTF9NQVBfTU9ERVMuUkVBRH0sXG4gICAgICAgICAgICAgICAgICBjdXJyZW50TW9kYWw6IG51bGxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KFJlZHV4LCBLZXBsZXJHbCkpO1xuXG4gICAgICAgICAgY29uc3QgbWlkZGxlV2FyZXMgPSAoZnVuY3Rpb24gY3JlYXRlTWlkZGxld2FyZXMoa2VwbGVyR2wpIHtcbiAgICAgICAgICAgIHJldHVybiBrZXBsZXJHbC5lbmhhbmNlUmVkdXhNaWRkbGV3YXJlKFtcbiAgICAgICAgICAgICAgLy8gQWRkIG90aGVyIG1pZGRsZXdhcmVzIGhlcmVcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0oS2VwbGVyR2wpKTtcblxuICAgICAgICAgIGNvbnN0IGVuaGFuY2VycyA9IChmdW5jdGlvbiBjcmFldGVFbmhhbmNlcnMocmVkdXgsIG1pZGRsZXMpIHtcbiAgICAgICAgICAgIHJldHVybiByZWR1eC5hcHBseU1pZGRsZXdhcmUoLi4ubWlkZGxlcyk7XG4gICAgICAgICAgfShSZWR1eCwgbWlkZGxlV2FyZXMpKTtcblxuICAgICAgICAgIGNvbnN0IHN0b3JlID0gKGZ1bmN0aW9uIGNyZWF0ZVN0b3JlKHJlZHV4LCBlbmhhbmNlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluaXRpYWxTdGF0ZSA9IHt9O1xuXG4gICAgICAgICAgICByZXR1cm4gcmVkdXguY3JlYXRlU3RvcmUoXG4gICAgICAgICAgICAgIHJlZHVjZXJzLFxuICAgICAgICAgICAgICBpbml0aWFsU3RhdGUsXG4gICAgICAgICAgICAgIHJlZHV4LmNvbXBvc2UoZW5oYW5jZXJzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KFJlZHV4LCBlbmhhbmNlcnMpKTtcbiAgICAgICAgICAvKiogRU5EIFNUT1JFICoqL1xuXG4gICAgICAgICAgLyoqIENPTVBPTkVOVFMgKiovXG4gICAgICAgICAgdmFyIEtlcGxlckVsZW1lbnQgPSAoZnVuY3Rpb24gbWFrZUtlcGxlckVsZW1lbnQocmVhY3QsIGtlcGxlckdsLCBtYXBib3hUb2tlbikge1xuICAgICAgICAgICAgdmFyIExvZ29TdmcgPSBmdW5jdGlvbiBMb2dvU3ZnKCkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcImxvZ28tY29udGFpbmVyXCIsIHN0eWxlOiB7cG9zaXRpb246ICdmaXhlZCcsIHpJbmRleDogMTAwMDAsIHBhZGRpbmc6ICc0cHgnfSB9LFxuICAgICAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgXCJzdmdcIixcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJrZXBsZXJfZ2xfX2xvZ29cIixcbiAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogXCIxMDdweFwiLFxuICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogXCIyMXB4XCIsXG4gICAgICAgICAgICAgICAgICAgICAgdmlld0JveDogXCIwIDAgMTI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICBcImdcIixcbiAgICAgICAgICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogXCJ0cmFuc2xhdGUoMTMuNTAwMDAwLCAxMy41MDAwMDApIHJvdGF0ZSg0NS4wMDAwMDApIHRyYW5zbGF0ZSgtMTMuNTAwMDAwLCAtMTMuNTAwMDAwKSB0cmFuc2xhdGUoNC4wMDAwMDAsIDQuMDAwMDAwKVwiIH0sXG4gICAgICAgICAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChcInJlY3RcIiwgeyB4OiBcIjBcIiwgeTogXCI2XCIsIHRyYW5zZm9ybTogXCJtYXRyaXgoMi41MzUxODFlLTA2IDEgLTEgMi41MzUxODFlLTA2IDE4LjExMDcgNi4wMzY5KVwiLCBmaWxsOiBcIiM1MzVDNkNcIiwgd2lkdGg6IFwiMTIuMVwiLCBoZWlnaHQ6IFwiMTIuMVwiIH0pLFxuICAgICAgICAgICAgICAgICAgICAgIHJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJyZWN0XCIsIHsgeDogXCI2XCIsIHk6IFwiMFwiLCB0cmFuc2Zvcm06IFwibWF0cml4KDIuNTM1MTgyZS0wNiAxIC0xIDIuNTM1MTgyZS0wNiAxOC4xMTA3IC02LjAzNjkpXCIsIGZpbGw6XCIjMUZCQUQ2XCIsIHdpZHRoOiBcIjEyLjFcIiwgaGVpZ2h0OiBcIjEyLjFcIiB9KVxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICByZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgIFwiZ1wiLFxuICAgICAgICAgICAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgICAgICAgICAgIHJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJwYXRoXCIsIHsgZmlsbDpcIiMxRkJBRDZcIiwgZDogXCJNMzksOC43aDIuMmwtMi44LDQuMmwyLjksNS4xSDM5bC0yLjQtNC4yaC0xLjNWMThoLTJWNWwyLTAuMXY3LjNoMS4zTDM5LDguN3pcIiB9KSxcbiAgICAgICAgICAgICAgICAgICAgICByZWFjdC5jcmVhdGVFbGVtZW50KFwicGF0aFwiLCB7IGZpbGw6XCIjMUZCQUQ2XCIsIGQ6IFwiTTQyLjQsMTMuM2MwLTEuNSwwLjQtMi43LDEuMS0zLjVzMS44LTEuMiwzLjEtMS4yYzEuMywwLDIuMiwwLjQsMi44LDEuMWMwLjYsMC43LDAuOSwxLjgsMC45LDMuMyBjMCwwLjQsMCwwLjgsMCwxLjFoLTUuOGMwLDEuNiwwLjgsMi40LDIuNCwyLjRjMSwwLDItMC4yLDIuOS0wLjZsMC4yLDEuN2MtMC40LDAuMi0wLjksMC40LTEuNCwwLjVzLTEuMSwwLjItMS43LDAuMiBjLTEuNSwwLTIuNi0wLjQtMy4zLTEuMkM0Mi44LDE2LjEsNDIuNCwxNC45LDQyLjQsMTMuM3ogTTQ2LjYsMTAuMWMtMC43LDAtMS4yLDAuMi0xLjUsMC41Yy0wLjQsMC40LTAuNiwwLjktMC42LDEuN2g0IGMwLTAuOC0wLjItMS40LTAuNS0xLjdTNDcuMiwxMC4xLDQ2LjYsMTAuMXpcIiB9KSxcbiAgICAgICAgICAgICAgICAgICAgICByZWFjdC5jcmVhdGVFbGVtZW50KFwicGF0aFwiLCB7IGZpbGw6XCIjMUZCQUQ2XCIsIGQ6IFwiTTU3LjEsMTguMmMtMSwwLTEuOC0wLjMtMi4zLTAuOWwwLDBsMCwxLjN2Mi41aC0yVjguN2gxLjVsMC4zLDAuOWgwYzAuMy0wLjMsMC43LTAuNiwxLjItMC43IGMwLjQtMC4yLDAuOS0wLjMsMS40LTAuM2MxLjIsMCwyLjEsMC40LDIuNywxLjFjMC42LDAuNywwLjksMiwwLjksMy43YzAsMS42LTAuMywyLjgtMSwzLjdDNTkuMiwxNy44LDU4LjMsMTguMiw1Ny4xLDE4LjJ6IE01Ni43LDEwLjNjLTAuNCwwLTAuOCwwLjEtMS4xLDAuMmMtMC4zLDAuMi0wLjYsMC40LTAuOCwwLjd2NC4zYzAuMiwwLjMsMC40LDAuNSwwLjcsMC43YzAuMywwLjIsMC43LDAuMywxLjEsMC4zIGMwLjcsMCwxLjItMC4yLDEuNi0wLjdjMC40LTAuNSwwLjUtMS4zLDAuNS0yLjVjMC0wLjgtMC4xLTEuNC0wLjItMS44cy0wLjQtMC43LTAuNy0wLjlDNTcuNiwxMC40LDU3LjIsMTAuMyw1Ni43LDEwLjN6XCIgfSksXG4gICAgICAgICAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChcInBhdGhcIiwgeyBmaWxsOlwiIzFGQkFENlwiLCBkOiBcIk02My4yLDE2VjVsMi0wLjF2MTAuOGMwLDAuMywwLjEsMC41LDAuMiwwLjZjMC4xLDAuMSwwLjMsMC4yLDAuNiwwLjJjMC4zLDAsMC42LDAsMC45LTAuMVYxOCBjLTAuNCwwLjEtMSwwLjItMS42LDAuMmMtMC44LDAtMS4zLTAuMi0xLjctMC41UzYzLjIsMTYuOCw2My4yLDE2elwiIH0pLFxuICAgICAgICAgICAgICAgICAgICAgIHJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJwYXRoXCIsIHsgZmlsbDpcIiMxRkJBRDZcIiwgZDogXCJNNjguMiwxMy4zYzAtMS41LDAuNC0yLjcsMS4xLTMuNWMwLjctMC44LDEuOC0xLjIsMy4xLTEuMmMxLjMsMCwyLjIsMC40LDIuOCwxLjFjMC42LDAuNywwLjksMS44LDAuOSwzLjMgYzAsMC40LDAsMC44LDAsMS4xaC01LjhjMCwxLjYsMC44LDIuNCwyLjQsMi40YzEsMCwyLTAuMiwyLjktMC42bDAuMiwxLjdjLTAuNCwwLjItMC45LDAuNC0xLjQsMC41cy0xLjEsMC4yLTEuNywwLjIgYy0xLjUsMC0yLjYtMC40LTMuMy0xLjJDNjguNiwxNi4xLDY4LjIsMTQuOSw2OC4yLDEzLjN6IE03Mi40LDEwLjFjLTAuNywwLTEuMiwwLjItMS41LDAuNWMtMC40LDAuNC0wLjYsMC45LTAuNiwxLjdoNCBjMC0wLjgtMC4yLTEuNC0wLjUtMS43UzczLDEwLjEsNzIuNCwxMC4xelwiIH0pLFxuICAgICAgICAgICAgICAgICAgICAgIHJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJwYXRoXCIsIHsgZmlsbDpcIiMxRkJBRDZcIiwgZDogXCJNODAuMiw4LjdsMC4xLDEuN2gwYzAuMy0wLjYsMC43LTEuMSwxLjEtMS40YzAuNC0wLjMsMS0wLjUsMS42LTAuNWMwLjQsMCwwLjcsMCwxLDAuMWwtMC4xLDIgYy0wLjMtMC4xLTAuNy0wLjItMS0wLjJjLTAuNywwLTEuMywwLjMtMS43LDAuOGMtMC40LDAuNS0wLjcsMS4yLTAuNywyLjFWMThoLTJWOC43SDgwLjJ6XCIgfSksXG4gICAgICAgICAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChcInBhdGhcIiwgeyBmaWxsOlwiIzFGQkFENlwiLCBkOiBcIk04My44LDE3YzAtMC44LDAuNC0xLjIsMS4yLTEuMmMwLjgsMCwxLjIsMC40LDEuMiwxLjJjMCwwLjgtMC40LDEuMS0xLjIsMS4xQzg0LjIsMTguMiw4My44LDE3LjgsODMuOCwxN3pcIiB9KSxcbiAgICAgICAgICAgICAgICAgICAgICByZWFjdC5jcmVhdGVFbGVtZW50KFwicGF0aFwiLCB7IGZpbGw6XCIjMUZCQUQ2XCIsIGQ6IFwiTTg4LjUsMTguN2MwLTAuOCwwLjQtMS40LDEuMi0xLjhjLTAuNi0wLjMtMC45LTAuOC0wLjktMS41YzAtMC43LDAuNC0xLjIsMS4xLTEuNmMtMC4zLTAuMy0wLjYtMC42LTAuNy0wLjkgYy0wLjItMC40LTAuMi0wLjgtMC4yLTEuM2MwLTEsMC4zLTEuOCwwLjktMi4zYzAuNi0wLjUsMS42LTAuOCwyLjgtMC44YzAuNSwwLDEsMCwxLjQsMC4xYzAuNCwwLjEsMC44LDAuMiwxLjEsMC40bDIuNC0wLjJ2MS41IGgtMS41YzAuMiwwLjQsMC4yLDAuOCwwLjIsMS4zYzAsMS0wLjMsMS43LTAuOSwyLjJzLTEuNSwwLjgtMi43LDAuOGMtMC43LDAtMS4yLTAuMS0xLjYtMC4yYy0wLjEsMC4xLTAuMiwwLjItMC4zLDAuMyBjLTAuMSwwLjEtMC4xLDAuMi0wLjEsMC40YzAsMC4yLDAuMSwwLjMsMC4yLDAuNGMwLjEsMC4xLDAuMywwLjIsMC42LDAuMmwyLjcsMC4yYzEsMC4xLDEuNywwLjMsMi4yLDAuNmMwLjUsMC4zLDAuOCwwLjksMC44LDEuNyBjMCwwLjYtMC4yLDEuMS0wLjUsMS41Yy0wLjQsMC40LTAuOSwwLjgtMS41LDFjLTAuNywwLjItMS41LDAuNC0yLjQsMC40Yy0xLjMsMC0yLjMtMC4yLTMtMC42Qzg4LjgsMjAuMSw4OC41LDE5LjUsODguNSwxOC43eiBNOTUuMSwxOC40YzAtMC4zLTAuMS0wLjUtMC4zLTAuN3MtMC42LTAuMi0xLjEtMC4zbC0yLjctMC4zYy0wLjIsMC4xLTAuNCwwLjMtMC41LDAuNWMtMC4xLDAuMi0wLjIsMC40LTAuMiwwLjYgYzAsMC40LDAuMiwwLjgsMC41LDFjMC40LDAuMiwxLDAuMywxLjgsMC4zQzk0LjIsMTkuNSw5NS4xLDE5LjIsOTUuMSwxOC40eiBNOTQuMywxMS41YzAtMC42LTAuMS0xLTAuNC0xLjIgYy0wLjMtMC4yLTAuNy0wLjMtMS4zLTAuM2MtMC43LDAtMS4xLDAuMS0xLjQsMC4zYy0wLjMsMC4yLTAuNCwwLjYtMC40LDEuMnMwLjEsMSwwLjQsMS4yYzAuMywwLjIsMC43LDAuMywxLjQsMC4zIGMwLjYsMCwxLjEtMC4xLDEuMy0wLjRTOTQuMywxMiw5NC4zLDExLjV6XCIgfSksXG4gICAgICAgICAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChcInBhdGhcIiwgeyBmaWxsOlwiIzFGQkFENlwiLCBkOiBcIk05OS40LDE2VjVsMi0wLjF2MTAuOGMwLDAuMywwLjEsMC41LDAuMiwwLjZjMC4xLDAuMSwwLjMsMC4yLDAuNiwwLjJjMC4zLDAsMC42LDAsMC45LTAuMVYxOCBjLTAuNCwwLjEtMSwwLjItMS42LDAuMmMtMC44LDAtMS4zLTAuMi0xLjctMC41Uzk5LjQsMTYuOCw5OS40LDE2elwiIH0pXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gQXBwKCkge1xuICAgICAgICAgICAgICB2YXIgcm9vdEVsbSA9IHJlYWN0LnVzZVJlZihudWxsKTtcbiAgICAgICAgICAgICAgdmFyIF91c2VTdGF0ZSA9IHJlYWN0LnVzZVN0YXRlKHtcbiAgICAgICAgICAgICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHZhciB3aW5kb3dEaW1lbnNpb24gPSBfdXNlU3RhdGVbMF07XG4gICAgICAgICAgICAgIHZhciBzZXREaW1lbnNpb24gPSBfdXNlU3RhdGVbMV07XG4gICAgICAgICAgICAgIHJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiBzaWRlRWZmZWN0KCl7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaGFuZGxlUmVzaXplKCkge1xuICAgICAgICAgICAgICAgICAgc2V0RGltZW5zaW9uKHt3aWR0aDogd2luZG93LmlubmVyV2lkdGgsIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0fSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgaGFuZGxlUmVzaXplKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7d2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIGhhbmRsZVJlc2l6ZSk7fTtcbiAgICAgICAgICAgICAgfSwgW10pO1xuICAgICAgICAgICAgICByZXR1cm4gcmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7c3R5bGU6IHtwb3NpdGlvbjogJ2Fic29sdXRlJywgbGVmdDogMCwgd2lkdGg6ICcxMDB2dycsIGhlaWdodDogJzEwMHZoJ319LFxuICAgICAgICAgICAgICAgICR7b3B0aW9ucy5tb2RlID09PSBFWFBPUlRfSFRNTF9NQVBfTU9ERVMuUkVBRCA/ICdMb2dvU3ZnKCksJyA6ICcnfVxuICAgICAgICAgICAgICAgIHJlYWN0LmNyZWF0ZUVsZW1lbnQoa2VwbGVyR2wuS2VwbGVyR2wsIHtcbiAgICAgICAgICAgICAgICAgIG1hcGJveEFwaUFjY2Vzc1Rva2VuOiBtYXBib3hUb2tlbixcbiAgICAgICAgICAgICAgICAgIGlkOiBcIm1hcFwiLFxuICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpbmRvd0RpbWVuc2lvbi53aWR0aCxcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogd2luZG93RGltZW5zaW9uLmhlaWdodFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KFJlYWN0LCBLZXBsZXJHbCwgTUFQQk9YX1RPS0VOKSk7XG5cbiAgICAgICAgICBjb25zdCBhcHAgPSAoZnVuY3Rpb24gY3JlYXRlUmVhY3RSZWR1eFByb3ZpZGVyKHJlYWN0LCByZWFjdFJlZHV4LCBLZXBsZXJFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgcmVhY3RSZWR1eC5Qcm92aWRlcixcbiAgICAgICAgICAgICAge3N0b3JlfSxcbiAgICAgICAgICAgICAgcmVhY3QuY3JlYXRlRWxlbWVudChLZXBsZXJFbGVtZW50LCBudWxsKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIH0oUmVhY3QsIFJlYWN0UmVkdXgsIEtlcGxlckVsZW1lbnQpKTtcbiAgICAgICAgICAvKiogRU5EIENPTVBPTkVOVFMgKiovXG5cbiAgICAgICAgICAvKiogUmVuZGVyICoqL1xuICAgICAgICAgIChmdW5jdGlvbiByZW5kZXIocmVhY3QsIHJlYWN0RE9NLCBhcHApIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcHAnKTtcbiAgICAgICAgICAgIGNvbnN0IHJvb3QgPSByZWFjdERPTS5jcmVhdGVSb290KGNvbnRhaW5lcik7XG4gICAgICAgICAgICByb290LnJlbmRlcihhcHApO1xuICAgICAgICAgIH0oUmVhY3QsIFJlYWN0RE9NLCBhcHApKTtcbiAgICAgICAgPC9zY3JpcHQ+XG4gICAgICAgIDwhLS0gVGhlIG5leHQgc2NyaXB0IHdpbGwgc2hvdyBob3cgdG8gaW50ZXJhY3QgZGlyZWN0bHkgd2l0aCBLZXBsZXIgbWFwIHN0b3JlIC0tPlxuICAgICAgICA8c2NyaXB0PlxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEN1c3RvbWl6ZSBtYXAuXG4gICAgICAgICAgICogSW4gdGhlIGZvbGxvd2luZyBzZWN0aW9uIHlvdSBjYW4gdXNlIHRoZSBzdG9yZSBvYmplY3QgdG8gZGlzcGF0Y2ggS2VwbGVyLmdsIGFjdGlvbnNcbiAgICAgICAgICAgKiB0byBhZGQgbmV3IGRhdGEgYW5kIGN1c3RvbWl6ZSBiZWhhdmlvclxuICAgICAgICAgICAqL1xuICAgICAgICAgIChmdW5jdGlvbiBjdXN0b21pemUoa2VwbGVyR2wsIHN0b3JlKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhc2V0cyA9ICR7SlNPTi5zdHJpbmdpZnkob3B0aW9ucy5kYXRhc2V0cyl9O1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0gJHtKU09OLnN0cmluZ2lmeShvcHRpb25zLmNvbmZpZyl9O1xuXG4gICAgICAgICAgICBjb25zdCBsb2FkZWREYXRhID0ga2VwbGVyR2wuS2VwbGVyR2xTY2hlbWEubG9hZChcbiAgICAgICAgICAgICAgZGF0YXNldHMsXG4gICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gRm9yIHNvbWUgcmVhc29uIEtlcGxlciBvdmVyd3JpdGVzIHRoZSBjb25maWcgd2l0aG91dCBleHRyYSB3YWl0IHRpbWVcbiAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgc3RvcmUuZGlzcGF0Y2goXG4gICAgICAgICAgICAgICAga2VwbGVyR2wuYWRkRGF0YVRvTWFwKHtcbiAgICAgICAgICAgICAgICAgIGRhdGFzZXRzOiBsb2FkZWREYXRhLmRhdGFzZXRzLFxuICAgICAgICAgICAgICAgICAgY29uZmlnOiBsb2FkZWREYXRhLmNvbmZpZyxcbiAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgY2VudGVyTWFwOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgICAgfShLZXBsZXJHbCwgc3RvcmUpKVxuICAgICAgICA8L3NjcmlwdD5cbiAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gIGA7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQSxJQUFBQSxVQUFBLEdBQUFDLE9BQUE7QUFIQTtBQUNBOztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFNQyxlQUFlLEdBQUFDLE9BQUEsQ0FBQUQsZUFBQSxHQUFHLFNBQWxCQSxlQUFlQSxDQUFJRSxPQUFPLEVBQWtDO0VBQUEsSUFBaENDLE9BQU8sR0FBQUMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdHLDRCQUFpQjtFQUNsRSxrWEFBQUMsTUFBQSxDQVdnREwsT0FBTyx5NEVBQUFLLE1BQUEsQ0FnQ05MLE9BQU8sMHBCQUFBSyxNQUFBLENBaUJ4Qk4sT0FBTyxDQUFDTyxvQkFBb0IsSUFBSSxzQkFBc0IscWxFQUFBRCxNQUFBLENBMkMxRE4sT0FBTyxDQUFDUSxJQUFJLEtBQUtDLGdDQUFxQixDQUFDQyxJQUFJLDBvTkFBQUosTUFBQSxDQW1GdkROLE9BQU8sQ0FBQ1EsSUFBSSxLQUFLQyxnQ0FBcUIsQ0FBQ0MsSUFBSSxHQUFHLFlBQVksR0FBRyxFQUFFLDAyQ0FBQUosTUFBQSxDQW1DbERLLElBQUksQ0FBQ0MsU0FBUyxDQUFDWixPQUFPLENBQUNhLFFBQVEsQ0FBQyxvQ0FBQVAsTUFBQSxDQUNsQ0ssSUFBSSxDQUFDQyxTQUFTLENBQUNaLE9BQU8sQ0FBQ2MsTUFBTSxDQUFDO0FBd0IzRCxDQUFDIiwiaWdub3JlTGlzdCI6W119