kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
194 lines (181 loc) • 21.3 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.resetMapConfig = exports.receiveMapConfig = exports.keplerGlInit = exports.addDataToMap = void 0;
var _actionTypes = _interopRequireDefault(require("../constants/action-types"));
var _reduxActions = require("redux-actions");
// Copyright (c) 2023 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
/**
* Add data to kepler.gl reducer, prepare map with preset configuration if config is passed.
* Kepler.gl provides a handy set of utils to parse data from different format to the `data` object required in dataset. You rarely need to manually format the data obejct.
*
* Use `KeplerGlSchema.getConfigToSave` to generate a json blob of the currents instance config.
* The config object value will always have higher precedence than the options properties.
*
* Kepler.gl uses `dataId` in the config to match with loaded dataset. If you pass a config object, you need
* to match the `info.id` of your dataset to the `dataId` in each `layer`, `filter` and `interactionConfig.tooltips.fieldsToShow`
*
* @memberof main
* @param {Object} data
* @param {Array<Object>|Object} data.datasets - ***required** datasets can be a dataset or an array of datasets
* Each dataset object needs to have `info` and `data` property.
* @param {Object} data.datasets.info -info of a dataset
* @param {string} data.datasets.info.id - id of this dataset. If config is defined, `id` should matches the `dataId` in config.
* @param {string} data.datasets.info.label - A display name of this dataset
* @param {Object} data.datasets.data - ***required** The data object, in a tabular format with 2 properties `fields` and `rows`
* @param {Array<Object>} data.datasets.data.fields - ***required** Array of fields,
* @param {string} data.datasets.data.fields.name - ***required** Name of the field,
* @param {Array<Array>} data.datasets.data.rows - ***required** Array of rows, in a tabular format with `fields` and `rows`
*
* @param {Object} data.options
* @param {boolean} data.options.centerMap `default: true` if `centerMap` is set to `true` kepler.gl will
* place the map view within the data points boundaries. `options.centerMap` will override `config.mapState` if passed in.
* @param {boolean} data.options.readOnly `default: false` if `readOnly` is set to `true`
* the left setting panel will be hidden
* @param {boolean} data.options.keepExistingConfig whether to keep exiting map data and associated layer filter interaction config `default: false`.
* @param {Object} data.config this object will contain the full kepler.gl instance configuration {mapState, mapStyle, visState}
* @public
* @example
*
* // app.js
* import {addDataToMap} from 'kepler.gl/actions';
*
* const sampleTripData = {
* fields: [
* {name: 'tpep_pickup_datetime', format: 'YYYY-M-D H:m:s', type: 'timestamp'},
* {name: 'pickup_longitude', format: '', type: 'real'},
* {name: 'pickup_latitude', format: '', type: 'real'}
* ],
* rows: [
* ['2015-01-15 19:05:39 +00:00', -73.99389648, 40.75011063],
* ['2015-01-15 19:05:39 +00:00', -73.97642517, 40.73981094],
* ['2015-01-15 19:05:40 +00:00', -73.96870422, 40.75424576],
* ]
* };
*
* const sampleConfig = {
* visState: {
* filters: [
* {
* id: 'me',
* dataId: 'test_trip_data',
* name: 'tpep_pickup_datetime',
* type: 'timeRange',
* enlarged: true
* }
* ]
* }
* }
*
* this.props.dispatch(
* addDataToMap({
* datasets: {
* info: {
* label: 'Sample Taxi Trips in New York City',
* id: 'test_trip_data'
* },
* data: sampleTripData
* },
* option: {
* centerMap: true,
* readOnly: false,
* keepExistingConfig: false
* },
* config: sampleConfig
* })
* );
*/
var addDataToMap = exports.addDataToMap = (0, _reduxActions.createAction)(_actionTypes["default"].ADD_DATA_TO_MAP, function (data) {
return data;
});
/**
* Reset all sub-reducers to its initial state. This can be used to clear out all configuration in the reducer.
* @memberof main
* @public
*/
var resetMapConfig = exports.resetMapConfig = (0, _reduxActions.createAction)(_actionTypes["default"].RESET_MAP_CONFIG);
/**
* Pass config to kepler.gl instance, prepare the state with preset configs.
* Calling `KeplerGlSchema.parseSavedConfig` to convert saved config before passing it in is required.
*
* You can call `receiveMapConfig` before passing in any data. The reducer will store layer and filter config, waiting for
* data to come in. When data arrives, you can call `addDataToMap` without passing any config, and the reducer will try to match
* preloaded configs. This behavior is designed to allow asynchronous data loading.
*
* It is also useful when you want to prepare the kepler.gl instance with some preset layer and filter settings.
* **Note** Sequence is important, `receiveMapConfig` needs to be called __before__ data is loaded. Currently kepler.gl doesn't allow calling `receiveMapConfig` after data is loaded.
* It will reset current configuration first then apply config to it.
* @memberof main
* @param {Object} config - ***required** The Config Object
* @param {Object} options - ***optional** The Option object
* @param {boolean} options.centerMap `default: true` if `centerMap` is set to `true` kepler.gl will
* place the map view within the data points boundaries
* @param {boolean} options.readOnly `default: false` if `readOnly` is set to `true`
* the left setting panel will be hidden
* @param {boolean} options.keepExistingConfig whether to keep exiting layer filter and interaction config `default: false`.
* @public
* @example
* import {receiveMapConfig} from 'kepler.gl/actions';
* import KeplerGlSchema from 'kepler.gl/schemas';
*
* const parsedConfig = KeplerGlSchema.parseSavedConfig(config);
* this.props.dispatch(receiveMapConfig(parsedConfig));
*/
var receiveMapConfig = exports.receiveMapConfig = (0, _reduxActions.createAction)(_actionTypes["default"].RECEIVE_MAP_CONFIG, function (config, options) {
return {
config: config,
options: options
};
});
/**
* Initialize kepler.gl reducer. It is used to pass in `mapboxApiAccessToken` to `mapStyle` reducer.
* @memberof main
* @param {Object} payload
* @param {string} payload.mapboxApiAccessToken - mapboxApiAccessToken to be saved to mapStyle reducer
* @param {string} payload.mapboxApiUrl - mapboxApiUrl to be saved to mapStyle reducer.
* @param {Boolean} payload.mapStylesReplaceDefault - mapStylesReplaceDefault to be saved to mapStyle reducer
* @public
*/
var keplerGlInit = exports.keplerGlInit = (0, _reduxActions.createAction)(_actionTypes["default"].INIT, function () {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
mapboxApiAccessToken = _ref.mapboxApiAccessToken,
mapboxApiUrl = _ref.mapboxApiUrl,
mapStylesReplaceDefault = _ref.mapStylesReplaceDefault;
return {
mapboxApiAccessToken: mapboxApiAccessToken,
mapboxApiUrl: mapboxApiUrl,
mapStylesReplaceDefault: mapStylesReplaceDefault
};
});
/**
* This declaration is needed to group actions in docs
*/
/**
* Main kepler.gl actions, these actions handles loading data and config into kepler.gl reducer. These actions
* is listened by all subreducers,
* @public
*/
/* eslint-disable no-unused-vars */
var main = null;
/* eslint-enable no-unused-vars */
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hY3Rpb25zL2FjdGlvbnMuanMiXSwibmFtZXMiOlsiYWRkRGF0YVRvTWFwIiwiQWN0aW9uVHlwZXMiLCJBRERfREFUQV9UT19NQVAiLCJkYXRhIiwicmVzZXRNYXBDb25maWciLCJSRVNFVF9NQVBfQ09ORklHIiwicmVjZWl2ZU1hcENvbmZpZyIsIlJFQ0VJVkVfTUFQX0NPTkZJRyIsImNvbmZpZyIsIm9wdGlvbnMiLCJrZXBsZXJHbEluaXQiLCJJTklUIiwibWFwYm94QXBpQWNjZXNzVG9rZW4iLCJtYXBib3hBcGlVcmwiLCJtYXBTdHlsZXNSZXBsYWNlRGVmYXVsdCIsIm1haW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBS0U7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0ZLLElBQU1BLFlBQVksMEJBQUcsZ0NBQzFCQyx3QkFBWUMsZUFEYyxFQUUxQixVQUFBQyxJQUFJO0FBQUEsU0FBSUEsSUFBSjtBQUFBLENBRnNCLENBQXJCO0FBS1A7Ozs7OztBQUtPLElBQU1DLGNBQWMsNEJBQUcsZ0NBQzVCSCx3QkFBWUksZ0JBRGdCLENBQXZCO0FBSVA7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEyQk8sSUFBTUMsZ0JBQWdCLDhCQUFHLGdDQUM5Qkwsd0JBQVlNLGtCQURrQixFQUU5QixVQUFDQyxNQUFELEVBQVNDLE9BQVQ7QUFBQSxTQUFzQjtBQUFDRCxJQUFBQSxNQUFNLEVBQU5BLE1BQUQ7QUFBU0MsSUFBQUEsT0FBTyxFQUFQQTtBQUFULEdBQXRCO0FBQUEsQ0FGOEIsQ0FBekI7QUFLUDs7Ozs7Ozs7OztBQVNPLElBQU1DLFlBQVksMEJBQUcsZ0NBQzFCVCx3QkFBWVUsSUFEYyxFQUUxQjtBQUFBLGlGQUFpRSxFQUFqRTtBQUFBLE1BQUVDLG9CQUFGLFFBQUVBLG9CQUFGO0FBQUEsTUFBd0JDLFlBQXhCLFFBQXdCQSxZQUF4QjtBQUFBLE1BQXNDQyx1QkFBdEMsUUFBc0NBLHVCQUF0Qzs7QUFBQSxTQUF5RTtBQUFDRixJQUFBQSxvQkFBb0IsRUFBcEJBLG9CQUFEO0FBQXVCQyxJQUFBQSxZQUFZLEVBQVpBLFlBQXZCO0FBQXFDQyxJQUFBQSx1QkFBdUIsRUFBdkJBO0FBQXJDLEdBQXpFO0FBQUEsQ0FGMEIsQ0FBckI7QUFLUDs7OztBQUdBOzs7Ozs7QUFLQTs7QUFDQSxJQUFNQyxJQUFJLEdBQUcsSUFBYjtBQUNBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIzIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IEFjdGlvblR5cGVzIGZyb20gJ2NvbnN0YW50cy9hY3Rpb24tdHlwZXMnO1xuaW1wb3J0IHtjcmVhdGVBY3Rpb259IGZyb20gJ3JlZHV4LWFjdGlvbnMnO1xuXG4gIC8qKlxuICAgKiBBZGQgZGF0YSB0byBrZXBsZXIuZ2wgcmVkdWNlciwgcHJlcGFyZSBtYXAgd2l0aCBwcmVzZXQgY29uZmlndXJhdGlvbiBpZiBjb25maWcgaXMgcGFzc2VkLlxuICAgKiBLZXBsZXIuZ2wgcHJvdmlkZXMgYSBoYW5keSBzZXQgb2YgdXRpbHMgdG8gcGFyc2UgZGF0YSBmcm9tIGRpZmZlcmVudCBmb3JtYXQgdG8gdGhlIGBkYXRhYCBvYmplY3QgcmVxdWlyZWQgaW4gZGF0YXNldC4gWW91IHJhcmVseSBuZWVkIHRvIG1hbnVhbGx5IGZvcm1hdCB0aGUgZGF0YSBvYmVqY3QuXG4gICAqXG4gICAqIFVzZSBgS2VwbGVyR2xTY2hlbWEuZ2V0Q29uZmlnVG9TYXZlYCB0byBnZW5lcmF0ZSBhIGpzb24gYmxvYiBvZiB0aGUgY3VycmVudHMgaW5zdGFuY2UgY29uZmlnLlxuICAgKiBUaGUgY29uZmlnIG9iamVjdCB2YWx1ZSB3aWxsIGFsd2F5cyBoYXZlIGhpZ2hlciBwcmVjZWRlbmNlIHRoYW4gdGhlIG9wdGlvbnMgcHJvcGVydGllcy5cbiAgICpcbiAgICogS2VwbGVyLmdsIHVzZXMgYGRhdGFJZGAgaW4gdGhlIGNvbmZpZyB0byBtYXRjaCB3aXRoIGxvYWRlZCBkYXRhc2V0LiBJZiB5b3UgcGFzcyBhIGNvbmZpZyBvYmplY3QsIHlvdSBuZWVkXG4gICAqIHRvIG1hdGNoIHRoZSBgaW5mby5pZGAgb2YgeW91ciBkYXRhc2V0IHRvIHRoZSBgZGF0YUlkYCBpbiBlYWNoIGBsYXllcmAsIGBmaWx0ZXJgIGFuZCBgaW50ZXJhY3Rpb25Db25maWcudG9vbHRpcHMuZmllbGRzVG9TaG93YFxuICAgKlxuICAgKiBAbWVtYmVyb2YgbWFpblxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgKiBAcGFyYW0ge0FycmF5PE9iamVjdD58T2JqZWN0fSBkYXRhLmRhdGFzZXRzIC0gKioqcmVxdWlyZWQqKiBkYXRhc2V0cyBjYW4gYmUgYSBkYXRhc2V0IG9yIGFuIGFycmF5IG9mIGRhdGFzZXRzXG4gICAqIEVhY2ggZGF0YXNldCBvYmplY3QgbmVlZHMgdG8gaGF2ZSBgaW5mb2AgYW5kIGBkYXRhYCBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEuZGF0YXNldHMuaW5mbyAtaW5mbyBvZiBhIGRhdGFzZXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEuZGF0YXNldHMuaW5mby5pZCAtIGlkIG9mIHRoaXMgZGF0YXNldC4gSWYgY29uZmlnIGlzIGRlZmluZWQsIGBpZGAgc2hvdWxkIG1hdGNoZXMgdGhlIGBkYXRhSWRgIGluIGNvbmZpZy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEuZGF0YXNldHMuaW5mby5sYWJlbCAtIEEgZGlzcGxheSBuYW1lIG9mIHRoaXMgZGF0YXNldFxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YS5kYXRhc2V0cy5kYXRhIC0gKioqcmVxdWlyZWQqKiBUaGUgZGF0YSBvYmplY3QsIGluIGEgdGFidWxhciBmb3JtYXQgd2l0aCAyIHByb3BlcnRpZXMgYGZpZWxkc2AgYW5kIGByb3dzYFxuICAgKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGRhdGEuZGF0YXNldHMuZGF0YS5maWVsZHMgLSAqKipyZXF1aXJlZCoqIEFycmF5IG9mIGZpZWxkcyxcbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEuZGF0YXNldHMuZGF0YS5maWVsZHMubmFtZSAtICoqKnJlcXVpcmVkKiogTmFtZSBvZiB0aGUgZmllbGQsXG4gICAqIEBwYXJhbSB7QXJyYXk8QXJyYXk+fSBkYXRhLmRhdGFzZXRzLmRhdGEucm93cyAtICoqKnJlcXVpcmVkKiogQXJyYXkgb2Ygcm93cywgaW4gYSB0YWJ1bGFyIGZvcm1hdCB3aXRoIGBmaWVsZHNgIGFuZCBgcm93c2BcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEub3B0aW9uc1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGRhdGEub3B0aW9ucy5jZW50ZXJNYXAgYGRlZmF1bHQ6IHRydWVgIGlmIGBjZW50ZXJNYXBgIGlzIHNldCB0byBgdHJ1ZWAga2VwbGVyLmdsIHdpbGxcbiAgICogcGxhY2UgdGhlIG1hcCB2aWV3IHdpdGhpbiB0aGUgZGF0YSBwb2ludHMgYm91bmRhcmllcy4gIGBvcHRpb25zLmNlbnRlck1hcGAgd2lsbCBvdmVycmlkZSBgY29uZmlnLm1hcFN0YXRlYCBpZiBwYXNzZWQgaW4uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZGF0YS5vcHRpb25zLnJlYWRPbmx5IGBkZWZhdWx0OiBmYWxzZWAgaWYgYHJlYWRPbmx5YCBpcyBzZXQgdG8gYHRydWVgXG4gICAqIHRoZSBsZWZ0IHNldHRpbmcgcGFuZWwgd2lsbCBiZSBoaWRkZW5cbiAgICogQHBhcmFtIHtib29sZWFufSBkYXRhLm9wdGlvbnMua2VlcEV4aXN0aW5nQ29uZmlnIHdoZXRoZXIgdG8ga2VlcCBleGl0aW5nIG1hcCBkYXRhIGFuZCBhc3NvY2lhdGVkIGxheWVyIGZpbHRlciAgaW50ZXJhY3Rpb24gY29uZmlnIGBkZWZhdWx0OiBmYWxzZWAuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhLmNvbmZpZyB0aGlzIG9iamVjdCB3aWxsIGNvbnRhaW4gdGhlIGZ1bGwga2VwbGVyLmdsIGluc3RhbmNlIGNvbmZpZ3VyYXRpb24ge21hcFN0YXRlLCBtYXBTdHlsZSwgdmlzU3RhdGV9XG4gICAqIEBwdWJsaWNcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogLy8gYXBwLmpzXG4gICAqIGltcG9ydCB7YWRkRGF0YVRvTWFwfSBmcm9tICdrZXBsZXIuZ2wvYWN0aW9ucyc7XG4gICAqXG4gICAqIGNvbnN0IHNhbXBsZVRyaXBEYXRhID0ge1xuICAgKiAgZmllbGRzOiBbXG4gICAqICAgIHtuYW1lOiAndHBlcF9waWNrdXBfZGF0ZXRpbWUnLCBmb3JtYXQ6ICdZWVlZLU0tRCBIOm06cycsIHR5cGU6ICd0aW1lc3RhbXAnfSxcbiAgICogICAge25hbWU6ICdwaWNrdXBfbG9uZ2l0dWRlJywgZm9ybWF0OiAnJywgdHlwZTogJ3JlYWwnfSxcbiAgICogICAge25hbWU6ICdwaWNrdXBfbGF0aXR1ZGUnLCBmb3JtYXQ6ICcnLCB0eXBlOiAncmVhbCd9XG4gICAqICBdLFxuICAgKiAgcm93czogW1xuICAgKiAgICBbJzIwMTUtMDEtMTUgMTk6MDU6MzkgKzAwOjAwJywgLTczLjk5Mzg5NjQ4LCA0MC43NTAxMTA2M10sXG4gICAqICAgIFsnMjAxNS0wMS0xNSAxOTowNTozOSArMDA6MDAnLCAtNzMuOTc2NDI1MTcsIDQwLjczOTgxMDk0XSxcbiAgICogICAgWycyMDE1LTAxLTE1IDE5OjA1OjQwICswMDowMCcsIC03My45Njg3MDQyMiwgNDAuNzU0MjQ1NzZdLFxuICAgKiAgXVxuICAgKiB9O1xuICAgKlxuICAgKiBjb25zdCBzYW1wbGVDb25maWcgPSB7XG4gICAqICAgdmlzU3RhdGU6IHtcbiAgICogICAgIGZpbHRlcnM6IFtcbiAgICogICAgICAge1xuICAgKiAgICAgICAgIGlkOiAnbWUnLFxuICAgKiAgICAgICAgIGRhdGFJZDogJ3Rlc3RfdHJpcF9kYXRhJyxcbiAgICogICAgICAgICBuYW1lOiAndHBlcF9waWNrdXBfZGF0ZXRpbWUnLFxuICAgKiAgICAgICAgIHR5cGU6ICd0aW1lUmFuZ2UnLFxuICAgKiAgICAgICAgIGVubGFyZ2VkOiB0cnVlXG4gICAqICAgICAgIH1cbiAgICogICAgIF1cbiAgICogICB9XG4gICAqIH1cbiAgICpcbiAgICogdGhpcy5wcm9wcy5kaXNwYXRjaChcbiAgICogICBhZGREYXRhVG9NYXAoe1xuICAgKiAgICAgZGF0YXNldHM6IHtcbiAgICogICAgICAgaW5mbzoge1xuICAgKiAgICAgICAgIGxhYmVsOiAnU2FtcGxlIFRheGkgVHJpcHMgaW4gTmV3IFlvcmsgQ2l0eScsXG4gICAqICAgICAgICAgaWQ6ICd0ZXN0X3RyaXBfZGF0YSdcbiAgICogICAgICAgfSxcbiAgICogICAgICAgZGF0YTogc2FtcGxlVHJpcERhdGFcbiAgICogICAgIH0sXG4gICAqICAgICBvcHRpb246IHtcbiAgICogICAgICAgY2VudGVyTWFwOiB0cnVlLFxuICAgKiAgICAgICByZWFkT25seTogZmFsc2UsXG4gICAqICAgICAgIGtlZXBFeGlzdGluZ0NvbmZpZzogZmFsc2VcbiAgICogICAgIH0sXG4gICAqICAgICBjb25maWc6IHNhbXBsZUNvbmZpZ1xuICAgKiAgIH0pXG4gICAqICk7XG4gICAqL1xuZXhwb3J0IGNvbnN0IGFkZERhdGFUb01hcCA9IGNyZWF0ZUFjdGlvbihcbiAgQWN0aW9uVHlwZXMuQUREX0RBVEFfVE9fTUFQLFxuICBkYXRhID0+IGRhdGFcbik7XG5cbi8qKlxuICogUmVzZXQgYWxsIHN1Yi1yZWR1Y2VycyB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gVGhpcyBjYW4gYmUgdXNlZCB0byBjbGVhciBvdXQgYWxsIGNvbmZpZ3VyYXRpb24gaW4gdGhlIHJlZHVjZXIuXG4gKiBAbWVtYmVyb2YgbWFpblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgcmVzZXRNYXBDb25maWcgPSBjcmVhdGVBY3Rpb24oXG4gIEFjdGlvblR5cGVzLlJFU0VUX01BUF9DT05GSUdcbik7XG5cbi8qKlxuICogUGFzcyBjb25maWcgdG8ga2VwbGVyLmdsIGluc3RhbmNlLCBwcmVwYXJlIHRoZSBzdGF0ZSB3aXRoIHByZXNldCBjb25maWdzLlxuICogQ2FsbGluZyBgS2VwbGVyR2xTY2hlbWEucGFyc2VTYXZlZENvbmZpZ2AgdG8gY29udmVydCBzYXZlZCBjb25maWcgYmVmb3JlIHBhc3NpbmcgaXQgaW4gaXMgcmVxdWlyZWQuXG4gKlxuICogWW91IGNhbiBjYWxsIGByZWNlaXZlTWFwQ29uZmlnYCBiZWZvcmUgcGFzc2luZyBpbiBhbnkgZGF0YS4gVGhlIHJlZHVjZXIgd2lsbCBzdG9yZSBsYXllciBhbmQgZmlsdGVyIGNvbmZpZywgd2FpdGluZyBmb3JcbiAqIGRhdGEgdG8gY29tZSBpbi4gV2hlbiBkYXRhIGFycml2ZXMsIHlvdSBjYW4gY2FsbCBgYWRkRGF0YVRvTWFwYCB3aXRob3V0IHBhc3NpbmcgYW55IGNvbmZpZywgYW5kIHRoZSByZWR1Y2VyIHdpbGwgdHJ5IHRvIG1hdGNoXG4gKiBwcmVsb2FkZWQgY29uZmlncy4gVGhpcyBiZWhhdmlvciBpcyBkZXNpZ25lZCB0byBhbGxvdyBhc3luY2hyb25vdXMgZGF0YSBsb2FkaW5nLlxuICpcbiAqIEl0IGlzIGFsc28gdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gcHJlcGFyZSB0aGUga2VwbGVyLmdsIGluc3RhbmNlIHdpdGggc29tZSBwcmVzZXQgbGF5ZXIgYW5kIGZpbHRlciBzZXR0aW5ncy5cbiAqICoqTm90ZSoqIFNlcXVlbmNlIGlzIGltcG9ydGFudCwgYHJlY2VpdmVNYXBDb25maWdgIG5lZWRzIHRvIGJlIGNhbGxlZCBfX2JlZm9yZV9fIGRhdGEgaXMgbG9hZGVkLiBDdXJyZW50bHkga2VwbGVyLmdsIGRvZXNuJ3QgYWxsb3cgY2FsbGluZyBgcmVjZWl2ZU1hcENvbmZpZ2AgYWZ0ZXIgZGF0YSBpcyBsb2FkZWQuXG4gKiBJdCB3aWxsIHJlc2V0IGN1cnJlbnQgY29uZmlndXJhdGlvbiBmaXJzdCB0aGVuIGFwcGx5IGNvbmZpZyB0byBpdC5cbiAqIEBtZW1iZXJvZiBtYWluXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gKioqcmVxdWlyZWQqKiBUaGUgQ29uZmlnIE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSAqKipvcHRpb25hbCoqIFRoZSBPcHRpb24gb2JqZWN0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMuY2VudGVyTWFwIGBkZWZhdWx0OiB0cnVlYCBpZiBgY2VudGVyTWFwYCBpcyBzZXQgdG8gYHRydWVgIGtlcGxlci5nbCB3aWxsXG4gKiBwbGFjZSB0aGUgbWFwIHZpZXcgd2l0aGluIHRoZSBkYXRhIHBvaW50cyBib3VuZGFyaWVzXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMucmVhZE9ubHkgYGRlZmF1bHQ6IGZhbHNlYCBpZiBgcmVhZE9ubHlgIGlzIHNldCB0byBgdHJ1ZWBcbiAqIHRoZSBsZWZ0IHNldHRpbmcgcGFuZWwgd2lsbCBiZSBoaWRkZW5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9ucy5rZWVwRXhpc3RpbmdDb25maWcgd2hldGhlciB0byBrZWVwIGV4aXRpbmcgbGF5ZXIgZmlsdGVyIGFuZCBpbnRlcmFjdGlvbiBjb25maWcgYGRlZmF1bHQ6IGZhbHNlYC5cbiAqIEBwdWJsaWNcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQge3JlY2VpdmVNYXBDb25maWd9IGZyb20gJ2tlcGxlci5nbC9hY3Rpb25zJztcbiAqIGltcG9ydCBLZXBsZXJHbFNjaGVtYSBmcm9tICdrZXBsZXIuZ2wvc2NoZW1hcyc7XG4gKlxuICogY29uc3QgcGFyc2VkQ29uZmlnID0gS2VwbGVyR2xTY2hlbWEucGFyc2VTYXZlZENvbmZpZyhjb25maWcpO1xuICogdGhpcy5wcm9wcy5kaXNwYXRjaChyZWNlaXZlTWFwQ29uZmlnKHBhcnNlZENvbmZpZykpO1xuICovXG5leHBvcnQgY29uc3QgcmVjZWl2ZU1hcENvbmZpZyA9IGNyZWF0ZUFjdGlvbihcbiAgQWN0aW9uVHlwZXMuUkVDRUlWRV9NQVBfQ09ORklHLFxuICAoY29uZmlnLCBvcHRpb25zKSA9PiAoe2NvbmZpZywgb3B0aW9uc30pXG4pO1xuXG4vKipcbiAqIEluaXRpYWxpemUga2VwbGVyLmdsIHJlZHVjZXIuIEl0IGlzIHVzZWQgdG8gcGFzcyBpbiBgbWFwYm94QXBpQWNjZXNzVG9rZW5gIHRvIGBtYXBTdHlsZWAgcmVkdWNlci5cbiAqIEBtZW1iZXJvZiBtYWluXG4gKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICogQHBhcmFtIHtzdHJpbmd9IHBheWxvYWQubWFwYm94QXBpQWNjZXNzVG9rZW4gLSBtYXBib3hBcGlBY2Nlc3NUb2tlbiB0byBiZSBzYXZlZCB0byBtYXBTdHlsZSByZWR1Y2VyXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF5bG9hZC5tYXBib3hBcGlVcmwgLSBtYXBib3hBcGlVcmwgdG8gYmUgc2F2ZWQgdG8gbWFwU3R5bGUgcmVkdWNlci5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcGF5bG9hZC5tYXBTdHlsZXNSZXBsYWNlRGVmYXVsdCAtIG1hcFN0eWxlc1JlcGxhY2VEZWZhdWx0IHRvIGJlIHNhdmVkIHRvIG1hcFN0eWxlIHJlZHVjZXJcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGtlcGxlckdsSW5pdCA9IGNyZWF0ZUFjdGlvbihcbiAgQWN0aW9uVHlwZXMuSU5JVCxcbiAgKHttYXBib3hBcGlBY2Nlc3NUb2tlbiwgbWFwYm94QXBpVXJsLCBtYXBTdHlsZXNSZXBsYWNlRGVmYXVsdH0gPSB7fSkgPT4gKHttYXBib3hBcGlBY2Nlc3NUb2tlbiwgbWFwYm94QXBpVXJsLCBtYXBTdHlsZXNSZXBsYWNlRGVmYXVsdH0pXG4pO1xuXG4vKipcbiAqIFRoaXMgZGVjbGFyYXRpb24gaXMgbmVlZGVkIHRvIGdyb3VwIGFjdGlvbnMgaW4gZG9jc1xuICovXG4vKipcbiAqIE1haW4ga2VwbGVyLmdsIGFjdGlvbnMsIHRoZXNlIGFjdGlvbnMgaGFuZGxlcyBsb2FkaW5nIGRhdGEgYW5kIGNvbmZpZyBpbnRvIGtlcGxlci5nbCByZWR1Y2VyLiBUaGVzZSBhY3Rpb25zXG4gKiBpcyBsaXN0ZW5lZCBieSBhbGwgc3VicmVkdWNlcnMsXG4gKiBAcHVibGljXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5jb25zdCBtYWluID0gbnVsbDtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cbiJdfQ==