kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
720 lines (623 loc) • 60.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setLocaleUpdater = exports.toggleSplitMapUpdater = exports.loadFilesErrUpdater = exports.loadFilesSuccessUpdater = exports.loadFilesUpdater = exports.removeNotificationUpdater = exports.addNotificationUpdater = exports.setExportMapHTMLMode = exports.setExportMapFormatUpdater = exports.setUserMapboxAccessTokenUpdater = exports.setExportDataUpdater = exports.setExportFilteredUpdater = exports.setExportDataTypeUpdater = exports.setExportSelectedDatasetUpdater = exports.cleanupExportImage = exports.setExportImageError = exports.setExportImageDataUri = exports.startExportingImage = exports.setExportImageSetting = exports.openDeleteModalUpdater = exports.toggleMapControlUpdater = exports.hideExportDropdownUpdater = exports.showExportDropdownUpdater = exports.toggleModalUpdater = exports.toggleSidePanelUpdater = exports.INITIAL_UI_STATE = exports.DEFAULT_EXPORT_MAP = exports.DEFAULT_EXPORT_JSON = exports.DEFAULT_EXPORT_HTML = exports.DEFAULT_NOTIFICATIONS = exports.DEFAULT_EXPORT_DATA = exports.DEFAULT_LOAD_FILES = exports.DEFAULT_EXPORT_IMAGE = exports.DEFAULT_MAP_CONTROLS = exports.DEFAULT_MODAL = exports.DEFAULT_ACTIVE_SIDE_PANEL = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _defaultSettings = require("../constants/default-settings");
var _notificationsUtils = require("../utils/notifications-utils");
var _exportUtils = require("../utils/export-utils");
var _DEFAULT_EXPORT_MAP;
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 DEFAULT_ACTIVE_SIDE_PANEL = 'layer';
exports.DEFAULT_ACTIVE_SIDE_PANEL = DEFAULT_ACTIVE_SIDE_PANEL;
var DEFAULT_MODAL = _defaultSettings.ADD_DATA_ID;
/**
* Updaters for `uiState` reducer. Can be used in your root reducer to directly modify kepler.gl's state.
* Read more about [Using updaters](../advanced-usage/using-updaters.md)
*
* @public
* @example
*
* import keplerGlReducer, {uiStateUpdaters} from 'kepler.gl/reducers';
* // Root Reducer
* const reducers = combineReducers({
* keplerGl: keplerGlReducer,
* app: appReducer
* });
*
* const composedReducer = (state, action) => {
* switch (action.type) {
* // click button to close side panel
* case 'CLICK_BUTTON':
* return {
* ...state,
* keplerGl: {
* ...state.keplerGl,
* foo: {
* ...state.keplerGl.foo,
* uiState: uiStateUpdaters.toggleSidePanelUpdater(
* uiState, {payload: null}
* )
* }
* }
* };
* }
* return reducers(state, action);
* };
*
* export default composedReducer;
*/
/* eslint-disable no-unused-vars */
exports.DEFAULT_MODAL = DEFAULT_MODAL;
var uiStateUpdaters = null;
/* eslint-enable no-unused-vars */
/**
* A list of map control visibility and whether is it active.
* @memberof uiStateUpdaters
* @constant
* @type {Object}
* @property {Object} visibleLayers Default: `{show: true, active: false}`
* @property {Object} mapLegend Default: `{show: true, active: false}`
* @property {Object} toggle3d Default: `{show: true}`
* @property {Object} splitMap Default: `{show: true}`
* @property {Object} mapDraw Default: `{show: true, active: false}`
* @property {Object} mapLocale Default: `{show: false, active: false}`
* @public
*/
var DEFAULT_MAP_CONTROLS_FEATURES = {
show: true,
active: false,
// defines which map index users are interacting with (through map controls)
activeMapIndex: 0
};
var DEFAULT_MAP_CONTROLS = ['visibleLayers', 'mapLegend', 'toggle3d', 'splitMap', 'mapDraw', 'mapLocale'].reduce(function (_final, current) {
return _objectSpread({}, _final, (0, _defineProperty2["default"])({}, current, DEFAULT_MAP_CONTROLS_FEATURES));
}, {});
/**
* Default image export config
* @memberof uiStateUpdaters
* @constant
* @type {Object}
* @property {string} ratio Default: `'SCREEN'`,
* @property {string} resolution Default: `'ONE_X'`,
* @property {boolean} legend Default: `false`,
* @property {string} imageDataUri Default: `''`,
* @property {boolean} exporting Default: `false`
* @property {boolean} error Default: `false`
* @public
*/
exports.DEFAULT_MAP_CONTROLS = DEFAULT_MAP_CONTROLS;
var DEFAULT_EXPORT_IMAGE = {
// user options
ratio: _defaultSettings.EXPORT_IMG_RATIOS.SCREEN,
resolution: _defaultSettings.RESOLUTIONS.ONE_X,
legend: false,
mapH: 0,
mapW: 0,
imageSize: {
zoomOffset: 0,
scale: 1,
imageW: 0,
imageH: 0
},
// exporting state
imageDataUri: '',
exporting: false,
error: false
};
exports.DEFAULT_EXPORT_IMAGE = DEFAULT_EXPORT_IMAGE;
var DEFAULT_LOAD_FILES = {
fileLoading: false
};
/**
* Default initial `exportData` settings
* @memberof uiStateUpdaters
* @constant
* @type {Object}
* @property {string} selectedDataset Default: `''`,
* @property {string} dataType Default: `'csv'`,
* @property {boolean} filtered Default: `true`,
* @property {boolean} config deprecated
* @property {boolean} data used in modal config export. Default: `false`
* @public
*/
exports.DEFAULT_LOAD_FILES = DEFAULT_LOAD_FILES;
var DEFAULT_EXPORT_DATA = {
selectedDataset: '',
dataType: _defaultSettings.EXPORT_DATA_TYPE.CSV,
filtered: true
};
/**
* @constant
* @type {Array}
*/
exports.DEFAULT_EXPORT_DATA = DEFAULT_EXPORT_DATA;
var DEFAULT_NOTIFICATIONS = [];
/**
* @constant
* @type {Object}
* @property {string} exportMapboxAccessToken - Default: null, this is used when we provide a default mapbox token for users to take advantage of
* @property {string} userMapboxToken - Default: '', mapbox token provided by user through input field
* @public
*/
exports.DEFAULT_NOTIFICATIONS = DEFAULT_NOTIFICATIONS;
var DEFAULT_EXPORT_HTML = {
exportMapboxAccessToken: null,
userMapboxToken: '',
mode: _defaultSettings.EXPORT_HTML_MAP_MODES.READ
};
exports.DEFAULT_EXPORT_HTML = DEFAULT_EXPORT_HTML;
var DEFAULT_EXPORT_JSON = {
hasData: true
};
exports.DEFAULT_EXPORT_JSON = DEFAULT_EXPORT_JSON;
var DEFAULT_EXPORT_MAP = (_DEFAULT_EXPORT_MAP = {}, (0, _defineProperty2["default"])(_DEFAULT_EXPORT_MAP, _defaultSettings.EXPORT_MAP_FORMATS.HTML, DEFAULT_EXPORT_HTML), (0, _defineProperty2["default"])(_DEFAULT_EXPORT_MAP, _defaultSettings.EXPORT_MAP_FORMATS.JSON, DEFAULT_EXPORT_JSON), (0, _defineProperty2["default"])(_DEFAULT_EXPORT_MAP, "format", _defaultSettings.EXPORT_MAP_FORMATS.HTML), _DEFAULT_EXPORT_MAP);
/**
* Default initial `uiState`
* @memberof uiStateUpdaters
* @constant
* @type {Object}
* @property {boolean} readOnly Default: `false`
* @property {string} activeSidePanel Default: `'layer'`
* @property {string|null} currentModal Default: `'addData'`
* @property {string|null} datasetKeyToRemove Default: `null`
* @property {string|null} visibleDropdown Default: `null`
* @property {Object} exportImage Default: [`DEFAULT_EXPORT_IMAGE`](#default_export_image)
* @property {Object} exportData Default: [`DEFAULT_EXPORT_DATA`](#default_export_data)
* @property {Object} mapControls Default: [`DEFAULT_MAP_CONTROLS`](#default_map_controls)
* @property {number} activeMapIndex defines which map the user clicked on. Default: 0
* @public
*/
exports.DEFAULT_EXPORT_MAP = DEFAULT_EXPORT_MAP;
var INITIAL_UI_STATE = {
readOnly: false,
activeSidePanel: DEFAULT_ACTIVE_SIDE_PANEL,
currentModal: DEFAULT_MODAL,
datasetKeyToRemove: null,
visibleDropdown: null,
// export image modal ui
exportImage: DEFAULT_EXPORT_IMAGE,
// export data modal ui
exportData: DEFAULT_EXPORT_DATA,
// html export
exportMap: DEFAULT_EXPORT_MAP,
// map control panels
mapControls: DEFAULT_MAP_CONTROLS,
// ui notifications
notifications: DEFAULT_NOTIFICATIONS,
// load files
loadFiles: DEFAULT_LOAD_FILES,
// Locale of the UI
locale: _defaultSettings.LOCALES.en
};
/* Updaters */
/**
* Toggle active side panel
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string|null} action.payload id of side panel to be shown, one of `layer`, `filter`, `interaction`, `map`. close side panel if `null`
* @returns {Object} nextState
* @public
*/
exports.INITIAL_UI_STATE = INITIAL_UI_STATE;
var toggleSidePanelUpdater = function toggleSidePanelUpdater(state, _ref) {
var id = _ref.payload;
return id === state.activeSidePanel ? state : _objectSpread({}, state, {
activeSidePanel: id
});
};
/**
* Show and hide modal dialog
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string|null} action.payload id of modal to be shown, null to hide modals. One of:
*
* - [`DATA_TABLE_ID`](../constants/default-settings.md#data_table_id)
* - [`DELETE_DATA_ID`](../constants/default-settings.md#delete_data_id)
* - [`ADD_DATA_ID`](../constants/default-settings.md#add_data_id)
* - [`EXPORT_IMAGE_ID`](../constants/default-settings.md#export_image_id)
* - [`EXPORT_DATA_ID`](../constants/default-settings.md#export_data_id)
* - [`ADD_MAP_STYLE_ID`](../constants/default-settings.md#add_map_style_id)
* @returns {Object} nextState
* @public
*/
exports.toggleSidePanelUpdater = toggleSidePanelUpdater;
var toggleModalUpdater = function toggleModalUpdater(state, _ref2) {
var id = _ref2.payload;
return _objectSpread({}, state, {
currentModal: id
});
};
/**
* Hide and show side panel header dropdown, activated by clicking the share link on top of the side panel
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string} action.payload id of the dropdown
* @returns {Object} nextState
* @public
*/
exports.toggleModalUpdater = toggleModalUpdater;
var showExportDropdownUpdater = function showExportDropdownUpdater(state, _ref3) {
var id = _ref3.payload;
return _objectSpread({}, state, {
visibleDropdown: id
});
};
/**
* Hide side panel header dropdown, activated by clicking the share link on top of the side panel
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
* @public
*/
exports.showExportDropdownUpdater = showExportDropdownUpdater;
var hideExportDropdownUpdater = function hideExportDropdownUpdater(state) {
return _objectSpread({}, state, {
visibleDropdown: null
});
};
/**
* Toggle active map control panel
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action action
* @param {string} action.payload map control panel id, one of the keys of: [`DEFAULT_MAP_CONTROLS`](#default_map_controls)
* @returns {Object} nextState
* @public
*/
exports.hideExportDropdownUpdater = hideExportDropdownUpdater;
var toggleMapControlUpdater = function toggleMapControlUpdater(state, _ref4) {
var _ref4$payload = _ref4.payload,
panelId = _ref4$payload.panelId,
_ref4$payload$index = _ref4$payload.index,
index = _ref4$payload$index === void 0 ? 0 : _ref4$payload$index;
return _objectSpread({}, state, {
mapControls: _objectSpread({}, state.mapControls, (0, _defineProperty2["default"])({}, panelId, _objectSpread({}, state.mapControls[panelId], {
// this handles split map interaction
// Toggling from within the same map will simply toggle the active property
// Toggling from within different maps we set the active property to true
active: index === state.mapControls[panelId].activeMapIndex ? !state.mapControls[panelId].active : true,
activeMapIndex: index
})))
});
};
/**
* Toggle active map control panel
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string} action.payload dataset id
* @returns {Object} nextState
* @public
*/
exports.toggleMapControlUpdater = toggleMapControlUpdater;
var openDeleteModalUpdater = function openDeleteModalUpdater(state, _ref5) {
var datasetKeyToRemove = _ref5.payload;
return _objectSpread({}, state, {
currentModal: _defaultSettings.DELETE_DATA_ID,
datasetKeyToRemove: datasetKeyToRemove
});
};
/**
* Set `exportImage.legend` to `true` or `false`
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
* @public
*/
exports.openDeleteModalUpdater = openDeleteModalUpdater;
var setExportImageSetting = function setExportImageSetting(state, _ref6) {
var newSetting = _ref6.payload;
var updated = _objectSpread({}, state.exportImage, {}, newSetting);
var imageSize = (0, _exportUtils.calculateExportImageSize)(updated) || state.exportImage.imageSize;
return _objectSpread({}, state, {
exportImage: _objectSpread({}, updated, {
imageSize: imageSize
})
});
};
/**
* Set `exportImage.exporting` to `true`
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
* @public
*/
exports.setExportImageSetting = setExportImageSetting;
var startExportingImage = function startExportingImage(state) {
return _objectSpread({}, state, {
exportImage: _objectSpread({}, state.exportImage, {
exporting: true,
imageDataUri: ''
})
});
};
/**
* Set `exportImage.setExportImageDataUri` to a image dataUri
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string} action.payload export image data uri
* @returns {Object} nextState
* @public
*/
exports.startExportingImage = startExportingImage;
var setExportImageDataUri = function setExportImageDataUri(state, _ref7) {
var dataUri = _ref7.payload;
return _objectSpread({}, state, {
exportImage: _objectSpread({}, state.exportImage, {
exporting: false,
imageDataUri: dataUri
})
});
};
exports.setExportImageDataUri = setExportImageDataUri;
var setExportImageError = function setExportImageError(state, _ref8) {
var error = _ref8.payload;
return _objectSpread({}, state, {
exportImage: _objectSpread({}, state.exportImage, {
exporting: false,
error: error
})
});
};
/**
* Delete cached export image
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
* @public
*/
exports.setExportImageError = setExportImageError;
var cleanupExportImage = function cleanupExportImage(state) {
return _objectSpread({}, state, {
exportImage: _objectSpread({}, state.exportImage, {
exporting: false,
imageDataUri: '',
error: false
})
});
};
/**
* Set selected dataset for export
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string} action.payload dataset id
* @returns {Object} nextState
* @public
*/
exports.cleanupExportImage = cleanupExportImage;
var setExportSelectedDatasetUpdater = function setExportSelectedDatasetUpdater(state, _ref9) {
var dataset = _ref9.payload;
return _objectSpread({}, state, {
exportData: _objectSpread({}, state.exportData, {
selectedDataset: dataset
})
});
};
/**
* Set data format for exporting data
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {string} action.payload one of `'text/csv'`
* @returns {Object} nextState
* @public
*/
exports.setExportSelectedDatasetUpdater = setExportSelectedDatasetUpdater;
var setExportDataTypeUpdater = function setExportDataTypeUpdater(state, _ref10) {
var dataType = _ref10.payload;
return _objectSpread({}, state, {
exportData: _objectSpread({}, state.exportData, {
dataType: dataType
})
});
};
/**
* Whether to export filtered data, `true` or `false`
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {boolean} action.payload
* @returns {Object} nextState
* @public
*/
exports.setExportDataTypeUpdater = setExportDataTypeUpdater;
var setExportFilteredUpdater = function setExportFilteredUpdater(state, _ref11) {
var filtered = _ref11.payload;
return _objectSpread({}, state, {
exportData: _objectSpread({}, state.exportData, {
filtered: filtered
})
});
};
/**
* Whether to including data in map config, toggle between `true` or `false`
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
* @public
*/
exports.setExportFilteredUpdater = setExportFilteredUpdater;
var setExportDataUpdater = function setExportDataUpdater(state) {
return _objectSpread({}, state, {
exportMap: _objectSpread({}, state.exportMap, (0, _defineProperty2["default"])({}, _defaultSettings.EXPORT_MAP_FORMATS.JSON, _objectSpread({}, state.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.JSON], {
hasData: !state.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.JSON].hasData
})))
});
};
/**
* whether to export a mapbox access to HTML single page
* @param {Object} state - `uiState`
* @param {Object} action
* @param {string} action.payload
* @returns {Object} nextState
* @public
*/
exports.setExportDataUpdater = setExportDataUpdater;
var setUserMapboxAccessTokenUpdater = function setUserMapboxAccessTokenUpdater(state, _ref12) {
var userMapboxToken = _ref12.payload;
return _objectSpread({}, state, {
exportMap: _objectSpread({}, state.exportMap, (0, _defineProperty2["default"])({}, _defaultSettings.EXPORT_MAP_FORMATS.HTML, _objectSpread({}, state.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.HTML], {
userMapboxToken: userMapboxToken
})))
});
};
/**
* Sets the export map format
* @param {Object} state - `uiState`
* @param {string} format to use to export the map onto
* @return {Object} nextState
*/
exports.setUserMapboxAccessTokenUpdater = setUserMapboxAccessTokenUpdater;
var setExportMapFormatUpdater = function setExportMapFormatUpdater(state, _ref13) {
var format = _ref13.payload;
return _objectSpread({}, state, {
exportMap: _objectSpread({}, state.exportMap, {
format: format
})
});
};
/**
* Set the export html map mode
* @param {Object} state - `uiState`
* @param {string} mode to be set (available modes: EXPORT_HTML_MAP_MODES)
* @return {{[p: string]: *}}
*/
exports.setExportMapFormatUpdater = setExportMapFormatUpdater;
var setExportMapHTMLMode = function setExportMapHTMLMode(state, _ref14) {
var mode = _ref14.payload;
return _objectSpread({}, state, {
exportMap: _objectSpread({}, state.exportMap, (0, _defineProperty2["default"])({}, _defaultSettings.EXPORT_MAP_FORMATS.HTML, _objectSpread({}, state.exportMap[_defaultSettings.EXPORT_MAP_FORMATS.HTML], {
mode: mode
})))
});
};
/**
* Add a notification to be displayed
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {Object} action.payload
* @returns {Object} nextState
* @public
*/
exports.setExportMapHTMLMode = setExportMapHTMLMode;
var addNotificationUpdater = function addNotificationUpdater(state, _ref15) {
var payload = _ref15.payload;
return _objectSpread({}, state, {
notifications: [].concat((0, _toConsumableArray2["default"])(state.notifications || []), [(0, _notificationsUtils.createNotification)(payload)])
});
};
/**
* Remove a notification
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {String} action.payload id of the notification to be removed
* @returns {Object} nextState
* @public
*/
exports.addNotificationUpdater = addNotificationUpdater;
var removeNotificationUpdater = function removeNotificationUpdater(state, _ref16) {
var id = _ref16.payload;
return _objectSpread({}, state, {
notifications: state.notifications.filter(function (n) {
return n.id !== id;
})
});
};
/**
* Fired when file loading begin
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
* @public
*/
exports.removeNotificationUpdater = removeNotificationUpdater;
var loadFilesUpdater = function loadFilesUpdater(state) {
return _objectSpread({}, state, {
loadFiles: _objectSpread({}, state.loadFiles, {
fileLoading: true
})
});
};
/**
* Handles loading file success and set fileLoading property to false
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @returns {Object} nextState
*/
exports.loadFilesUpdater = loadFilesUpdater;
var loadFilesSuccessUpdater = function loadFilesSuccessUpdater(state) {
return _objectSpread({}, state, {
loadFiles: _objectSpread({}, state.loadFiles, {
fileLoading: false
})
});
};
/**
* Handles load file error and set fileLoading property to false
* @memberof uiStateUpdaters
* @param state
* @param error
* @returns {Object} nextState
* @public
*/
exports.loadFilesSuccessUpdater = loadFilesSuccessUpdater;
var loadFilesErrUpdater = function loadFilesErrUpdater(state, _ref17) {
var error = _ref17.error;
return addNotificationUpdater(_objectSpread({}, state, {
loadFiles: _objectSpread({}, state.loadFiles, {
fileLoading: false
})
}), {
payload: (0, _notificationsUtils.errorNotification)({
message: (error || {}).message || 'Failed to upload files',
topic: _defaultSettings.DEFAULT_NOTIFICATION_TOPICS.global
})
});
};
/**
* Handles toggle map split and reset all map control index to 0
* @memberof uiStateUpdaters
* @param state
* @returns {Object} nextState
* @public
*/
exports.loadFilesErrUpdater = loadFilesErrUpdater;
var toggleSplitMapUpdater = function toggleSplitMapUpdater(state) {
return _objectSpread({}, state, {
mapControls: Object.entries(state.mapControls).reduce(function (acc, entry) {
return _objectSpread({}, acc, (0, _defineProperty2["default"])({}, entry[0], _objectSpread({}, entry[1], {
activeMapIndex: 0
})));
}, {})
});
};
/**
* Set the locale of the UI
* @memberof uiStateUpdaters
* @param {Object} state `uiState`
* @param {Object} action
* @param {String} action.payload locale
* @returns {Object} nextState
* @public
*/
exports.toggleSplitMapUpdater = toggleSplitMapUpdater;
var setLocaleUpdater = function setLocaleUpdater(state, _ref18) {
var locale = _ref18.payload.locale;
return _objectSpread({}, state, {
locale: locale
});
};
exports.setLocaleUpdater = setLocaleUpdater;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy91aS1zdGF0ZS11cGRhdGVycy5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0FDVElWRV9TSURFX1BBTkVMIiwiREVGQVVMVF9NT0RBTCIsIkFERF9EQVRBX0lEIiwidWlTdGF0ZVVwZGF0ZXJzIiwiREVGQVVMVF9NQVBfQ09OVFJPTFNfRkVBVFVSRVMiLCJzaG93IiwiYWN0aXZlIiwiYWN0aXZlTWFwSW5kZXgiLCJERUZBVUxUX01BUF9DT05UUk9MUyIsInJlZHVjZSIsImZpbmFsIiwiY3VycmVudCIsIkRFRkFVTFRfRVhQT1JUX0lNQUdFIiwicmF0aW8iLCJFWFBPUlRfSU1HX1JBVElPUyIsIlNDUkVFTiIsInJlc29sdXRpb24iLCJSRVNPTFVUSU9OUyIsIk9ORV9YIiwibGVnZW5kIiwibWFwSCIsIm1hcFciLCJpbWFnZVNpemUiLCJ6b29tT2Zmc2V0Iiwic2NhbGUiLCJpbWFnZVciLCJpbWFnZUgiLCJpbWFnZURhdGFVcmkiLCJleHBvcnRpbmciLCJlcnJvciIsIkRFRkFVTFRfTE9BRF9GSUxFUyIsImZpbGVMb2FkaW5nIiwiREVGQVVMVF9FWFBPUlRfREFUQSIsInNlbGVjdGVkRGF0YXNldCIsImRhdGFUeXBlIiwiRVhQT1JUX0RBVEFfVFlQRSIsIkNTViIsImZpbHRlcmVkIiwiREVGQVVMVF9OT1RJRklDQVRJT05TIiwiREVGQVVMVF9FWFBPUlRfSFRNTCIsImV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuIiwidXNlck1hcGJveFRva2VuIiwibW9kZSIsIkVYUE9SVF9IVE1MX01BUF9NT0RFUyIsIlJFQUQiLCJERUZBVUxUX0VYUE9SVF9KU09OIiwiaGFzRGF0YSIsIkRFRkFVTFRfRVhQT1JUX01BUCIsIkVYUE9SVF9NQVBfRk9STUFUUyIsIkhUTUwiLCJKU09OIiwiSU5JVElBTF9VSV9TVEFURSIsInJlYWRPbmx5IiwiYWN0aXZlU2lkZVBhbmVsIiwiY3VycmVudE1vZGFsIiwiZGF0YXNldEtleVRvUmVtb3ZlIiwidmlzaWJsZURyb3Bkb3duIiwiZXhwb3J0SW1hZ2UiLCJleHBvcnREYXRhIiwiZXhwb3J0TWFwIiwibWFwQ29udHJvbHMiLCJub3RpZmljYXRpb25zIiwibG9hZEZpbGVzIiwibG9jYWxlIiwiTE9DQUxFUyIsImVuIiwidG9nZ2xlU2lkZVBhbmVsVXBkYXRlciIsInN0YXRlIiwiaWQiLCJwYXlsb2FkIiwidG9nZ2xlTW9kYWxVcGRhdGVyIiwic2hvd0V4cG9ydERyb3Bkb3duVXBkYXRlciIsImhpZGVFeHBvcnREcm9wZG93blVwZGF0ZXIiLCJ0b2dnbGVNYXBDb250cm9sVXBkYXRlciIsInBhbmVsSWQiLCJpbmRleCIsIm9wZW5EZWxldGVNb2RhbFVwZGF0ZXIiLCJERUxFVEVfREFUQV9JRCIsInNldEV4cG9ydEltYWdlU2V0dGluZyIsIm5ld1NldHRpbmciLCJ1cGRhdGVkIiwic3RhcnRFeHBvcnRpbmdJbWFnZSIsInNldEV4cG9ydEltYWdlRGF0YVVyaSIsImRhdGFVcmkiLCJzZXRFeHBvcnRJbWFnZUVycm9yIiwiY2xlYW51cEV4cG9ydEltYWdlIiwic2V0RXhwb3J0U2VsZWN0ZWREYXRhc2V0VXBkYXRlciIsImRhdGFzZXQiLCJzZXRFeHBvcnREYXRhVHlwZVVwZGF0ZXIiLCJzZXRFeHBvcnRGaWx0ZXJlZFVwZGF0ZXIiLCJzZXRFeHBvcnREYXRhVXBkYXRlciIsInNldFVzZXJNYXBib3hBY2Nlc3NUb2tlblVwZGF0ZXIiLCJzZXRFeHBvcnRNYXBGb3JtYXRVcGRhdGVyIiwiZm9ybWF0Iiwic2V0RXhwb3J0TWFwSFRNTE1vZGUiLCJhZGROb3RpZmljYXRpb25VcGRhdGVyIiwicmVtb3ZlTm90aWZpY2F0aW9uVXBkYXRlciIsImZpbHRlciIsIm4iLCJsb2FkRmlsZXNVcGRhdGVyIiwibG9hZEZpbGVzU3VjY2Vzc1VwZGF0ZXIiLCJsb2FkRmlsZXNFcnJVcGRhdGVyIiwibWVzc2FnZSIsInRvcGljIiwiREVGQVVMVF9OT1RJRklDQVRJT05fVE9QSUNTIiwiZ2xvYmFsIiwidG9nZ2xlU3BsaXRNYXBVcGRhdGVy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TUFBQUEsV0FBVyxFQUFFO0FBRk47QUFIUyxNQVFwQjtBQUNFc0MsSUFBQUEsT0FBTyxFQUFFLDJDQUFrQjtBQUN6QmlDLE1BQUFBLE9BQU8sRUFBRSxDQUFDekUsS0FBSyxJQUFJLEVBQVYsRUFBY3lFLE9BQWQsSUFBeUIsd0JBRFQ7QUFFekJDLE1BQUFBLEtBQUssRUFBRUMsNkNBQTRCQztBQUZWLEtBQWxCO0FBRFgsR0FSb0IsQ0FEVztBQUFBLENBQTVCO0FBaUJQOzs7Ozs7Ozs7OztBQU9PLElBQU1DLHFCQUFxQixHQUFHLFNBQXhCQSxxQkFBd0IsQ0FBQXZDLEtBQUs7QUFBQSwyQkFDckNBLEtBRHFDO0FBRXhDUCxJQUFBQSxXQUFXLEVBQUUrQyxNQUFNLENBQUNDLE9BQVAsQ0FBZXpDLEtBQUssQ0FBQ1AsV0FBckIsRUFBa0NuRCxNQUFsQyxDQUNYLFVBQUNvRyxHQUFELEVBQU1DLEtBQU47QUFBQSwrQkFDS0QsR0FETCx1Q0FFR0MsS0FBSyxDQUFDLENBQUQsQ0FGUixvQkFHT0EsS0FBSyxDQUFDLENBQUQsQ0FIWjtBQUlJdkcsUUFBQUEsY0FBYyxFQUFFO0FBSnBCO0FBQUEsS0FEVyxFQVFYLEVBUlc7QUFGMkI7QUFBQSxDQUFuQztBQWNQOzs7Ozs7Ozs7Ozs7O0FBU08sSUFBTXdHLGdCQUFnQixHQUFHLFNBQW5CQSxnQkFBbUIsQ0FBQzVDLEtBQUQ7QUFBQSxNQUFtQkosTUFBbkIsVUFBU00sT0FBVCxDQUFtQk4sTUFBbkI7QUFBQSwyQkFDM0JJLEtBRDJCO0FBRTlCSixJQUFBQSxNQUFNLEVBQU5BO0FBRjhCO0FBQUEsQ0FBekIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjAgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQge1xuICBBRERfREFUQV9JRCxcbiAgREVGQVVMVF9OT1RJRklDQVRJT05fVE9QSUNTLFxuICBERUxFVEVfREFUQV9JRCxcbiAgRVhQT1JUX0RBVEFfVFlQRSxcbiAgRVhQT1JUX0hUTUxfTUFQX01PREVTLFxuICBFWFBPUlRfSU1HX1JBVElPUyxcbiAgRVhQT1JUX01BUF9GT1JNQVRTLFxuICBSRVNPTFVUSU9OUyxcbiAgTE9DQUxFU1xufSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5pbXBvcnQge2NyZWF0ZU5vdGlmaWNhdGlvbiwgZXJyb3JOb3RpZmljYXRpb259IGZyb20gJ3V0aWxzL25vdGlmaWNhdGlvbnMtdXRpbHMnO1xuaW1wb3J0IHtjYWxjdWxhdGVFeHBvcnRJbWFnZVNpemV9IGZyb20gJ3V0aWxzL2V4cG9ydC11dGlscyc7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FDVElWRV9TSURFX1BBTkVMID0gJ2xheWVyJztcbmV4cG9ydCBjb25zdCBERUZBVUxUX01PREFMID0gQUREX0RBVEFfSUQ7XG5cbi8qKlxuICogVXBkYXRlcnMgZm9yIGB1aVN0YXRlYCByZWR1Y2VyLiBDYW4gYmUgdXNlZCBpbiB5b3VyIHJvb3QgcmVkdWNlciB0byBkaXJlY3RseSBtb2RpZnkga2VwbGVyLmdsJ3Mgc3RhdGUuXG4gKiBSZWFkIG1vcmUgYWJvdXQgW1VzaW5nIHVwZGF0ZXJzXSguLi9hZHZhbmNlZC11c2FnZS91c2luZy11cGRhdGVycy5tZClcbiAqXG4gKiBAcHVibGljXG4gKiBAZXhhbXBsZVxuICpcbiAqIGltcG9ydCBrZXBsZXJHbFJlZHVjZXIsIHt1aVN0YXRlVXBkYXRlcnN9IGZyb20gJ2tlcGxlci5nbC9yZWR1Y2Vycyc7XG4gKiAvLyBSb290IFJlZHVjZXJcbiAqIGNvbnN0IHJlZHVjZXJzID0gY29tYmluZVJlZHVjZXJzKHtcbiAqICBrZXBsZXJHbDoga2VwbGVyR2xSZWR1Y2VyLFxuICogIGFwcDogYXBwUmVkdWNlclxuICogfSk7XG4gKlxuICogY29uc3QgY29tcG9zZWRSZWR1Y2VyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAqICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gKiAgICAvLyBjbGljayBidXR0b24gdG8gY2xvc2Ugc2lkZSBwYW5lbFxuICogICAgY2FzZSAnQ0xJQ0tfQlVUVE9OJzpcbiAqICAgICAgcmV0dXJuIHtcbiAqICAgICAgICAuLi5zdGF0ZSxcbiAqICAgICAgICBrZXBsZXJHbDoge1xuICogICAgICAgICAgLi4uc3RhdGUua2VwbGVyR2wsXG4gKiAgICAgICAgICBmb286IHtcbiAqICAgICAgICAgICAgIC4uLnN0YXRlLmtlcGxlckdsLmZvbyxcbiAqICAgICAgICAgICAgIHVpU3RhdGU6IHVpU3RhdGVVcGRhdGVycy50b2dnbGVTaWRlUGFuZWxVcGRhdGVyKFxuICogICAgICAgICAgICAgICB1aVN0YXRlLCB7cGF5bG9hZDogbnVsbH1cbiAqICAgICAgICAgICAgIClcbiAqICAgICAgICAgIH1cbiAqICAgICAgICB9XG4gKiAgICAgIH07XG4gKiAgfVxuICogIHJldHVybiByZWR1Y2VycyhzdGF0ZSwgYWN0aW9uKTtcbiAqIH07XG4gKlxuICogZXhwb3J0IGRlZmF1bHQgY29tcG9zZWRSZWR1Y2VyO1xuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuY29uc3QgdWlTdGF0ZVVwZGF0ZXJzID0gbnVsbDtcbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuLyoqXG4gKiBBIGxpc3Qgb2YgbWFwIGNvbnRyb2wgdmlzaWJpbGl0eSBhbmQgd2hldGhlciBpcyBpdCBhY3RpdmUuXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAY29uc3RhbnRcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge09iamVjdH0gdmlzaWJsZUxheWVycyBEZWZhdWx0OiBge3Nob3c6IHRydWUsIGFjdGl2ZTogZmFsc2V9YFxuICogQHByb3BlcnR5IHtPYmplY3R9IG1hcExlZ2VuZCBEZWZhdWx0OiBge3Nob3c6IHRydWUsIGFjdGl2ZTogZmFsc2V9YFxuICogQHByb3BlcnR5IHtPYmplY3R9IHRvZ2dsZTNkIERlZmF1bHQ6IGB7c2hvdzogdHJ1ZX1gXG4gKiBAcHJvcGVydHkge09iamVjdH0gc3BsaXRNYXAgRGVmYXVsdDogYHtzaG93OiB0cnVlfWBcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtYXBEcmF3IERlZmF1bHQ6IGB7c2hvdzogdHJ1ZSwgYWN0aXZlOiBmYWxzZX1gXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWFwTG9jYWxlIERlZmF1bHQ6IGB7c2hvdzogZmFsc2UsIGFjdGl2ZTogZmFsc2V9YFxuICogQHB1YmxpY1xuICovXG5jb25zdCBERUZBVUxUX01BUF9DT05UUk9MU19GRUFUVVJFUyA9IHtcbiAgc2hvdzogdHJ1ZSxcbiAgYWN0aXZlOiBmYWxzZSxcbiAgLy8gZGVmaW5lcyB3aGljaCBtYXAgaW5kZXggdXNlcnMgYXJlIGludGVyYWN0aW5nIHdpdGggKHRocm91Z2ggbWFwIGNvbnRyb2xzKVxuICBhY3RpdmVNYXBJbmRleDogMFxufTtcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUFQX0NPTlRST0xTID0gW1xuICAndmlzaWJsZUxheWVycycsXG4gICdtYXBMZWdlbmQnLFxuICAndG9nZ2xlM2QnLFxuICAnc3BsaXRNYXAnLFxuICAnbWFwRHJhdycsXG4gICdtYXBMb2NhbGUnXG5dLnJlZHVjZShcbiAgKGZpbmFsLCBjdXJyZW50KSA9PiAoe1xuICAgIC4uLmZpbmFsLFxuICAgIFtjdXJyZW50XTogREVGQVVMVF9NQVBfQ09OVFJPTFNfRkVBVFVSRVNcbiAgfSksXG4gIHt9XG4pO1xuXG5cbi8qKlxuICogRGVmYXVsdCBpbWFnZSBleHBvcnQgY29uZmlnXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAY29uc3RhbnRcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmF0aW8gRGVmYXVsdDogYCdTQ1JFRU4nYCxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZXNvbHV0aW9uIERlZmF1bHQ6IGAnT05FX1gnYCxcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbGVnZW5kIERlZmF1bHQ6IGBmYWxzZWAsXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaW1hZ2VEYXRhVXJpIERlZmF1bHQ6IGAnJ2AsXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGV4cG9ydGluZyBEZWZhdWx0OiBgZmFsc2VgXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGVycm9yIERlZmF1bHQ6IGBmYWxzZWBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0lNQUdFID0ge1xuICAvLyB1c2VyIG9wdGlvbnNcbiAgcmF0aW86IEVYUE9SVF9JTUdfUkFUSU9TLlNDUkVFTixcbiAgcmVzb2x1dGlvbjogUkVTT0xVVElPTlMuT05FX1gsXG4gIGxlZ2VuZDogZmFsc2UsXG4gIG1hcEg6IDAsXG4gIG1hcFc6IDAsXG4gIGltYWdlU2l6ZToge1xuICAgIHpvb21PZmZzZXQ6IDAsXG4gICAgc2NhbGU6IDEsXG4gICAgaW1hZ2VXOiAwLFxuICAgIGltYWdlSDogMFxuICB9LFxuICAvLyBleHBvcnRpbmcgc3RhdGVcbiAgaW1hZ2VEYXRhVXJpOiAnJyxcbiAgZXhwb3J0aW5nOiBmYWxzZSxcbiAgZXJyb3I6IGZhbHNlXG59O1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9MT0FEX0ZJTEVTID0ge1xuICBmaWxlTG9hZGluZzogZmFsc2Vcbn07XG5cbi8qKlxuICogRGVmYXVsdCBpbml0aWFsIGBleHBvcnREYXRhYCBzZXR0aW5nc1xuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQGNvbnN0YW50XG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNlbGVjdGVkRGF0YXNldCBEZWZhdWx0OiBgJydgLFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGRhdGFUeXBlIERlZmF1bHQ6IGAnY3N2J2AsXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGZpbHRlcmVkIERlZmF1bHQ6IGB0cnVlYCxcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gY29uZmlnIGRlcHJlY2F0ZWRcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGF0YSB1c2VkIGluIG1vZGFsIGNvbmZpZyBleHBvcnQuIERlZmF1bHQ6IGBmYWxzZWBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0RBVEEgPSB7XG4gIHNlbGVjdGVkRGF0YXNldDogJycsXG4gIGRhdGFUeXBlOiBFWFBPUlRfREFUQV9UWVBFLkNTVixcbiAgZmlsdGVyZWQ6IHRydWVcbn07XG5cbi8qKlxuICogQGNvbnN0YW50XG4gKiBAdHlwZSB7QXJyYXl9XG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX05PVElGSUNBVElPTlMgPSBbXTtcblxuLyoqXG4gKiBAY29uc3RhbnRcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge3N0cmluZ30gZXhwb3J0TWFwYm94QWNjZXNzVG9rZW4gLSBEZWZhdWx0OiBudWxsLCB0aGlzIGlzIHVzZWQgd2hlbiB3ZSBwcm92aWRlIGEgZGVmYXVsdCBtYXBib3ggdG9rZW4gZm9yIHVzZXJzIHRvIHRha2UgYWR2YW50YWdlIG9mXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdXNlck1hcGJveFRva2VuIC0gRGVmYXVsdDogJycsIG1hcGJveCB0b2tlbiBwcm92aWRlZCBieSB1c2VyIHRocm91Z2ggaW5wdXQgZmllbGRcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0hUTUwgPSB7XG4gIGV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuOiBudWxsLFxuICB1c2VyTWFwYm94VG9rZW46ICcnLFxuICBtb2RlOiBFWFBPUlRfSFRNTF9NQVBfTU9ERVMuUkVBRFxufTtcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0pTT04gPSB7XG4gIGhhc0RhdGE6IHRydWVcbn07XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0VYUE9SVF9NQVAgPSB7XG4gIFtFWFBPUlRfTUFQX0ZPUk1BVFMuSFRNTF06IERFRkFVTFRfRVhQT1JUX0hUTUwsXG4gIFtFWFBPUlRfTUFQX0ZPUk1BVFMuSlNPTl06IERFRkFVTFRfRVhQT1JUX0pTT04sXG4gIGZvcm1hdDogRVhQT1JUX01BUF9GT1JNQVRTLkhUTUxcbn07XG5cbi8qKlxuICogRGVmYXVsdCBpbml0aWFsIGB1aVN0YXRlYFxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQGNvbnN0YW50XG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtib29sZWFufSByZWFkT25seSBEZWZhdWx0OiBgZmFsc2VgXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYWN0aXZlU2lkZVBhbmVsIERlZmF1bHQ6IGAnbGF5ZXInYFxuICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gY3VycmVudE1vZGFsIERlZmF1bHQ6IGAnYWRkRGF0YSdgXG4gKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBkYXRhc2V0S2V5VG9SZW1vdmUgRGVmYXVsdDogYG51bGxgXG4gKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSB2aXNpYmxlRHJvcGRvd24gRGVmYXVsdDogYG51bGxgXG4gKiBAcHJvcGVydHkge09iamVjdH0gZXhwb3J0SW1hZ2UgRGVmYXVsdDogW2BERUZBVUxUX0VYUE9SVF9JTUFHRWBdKCNkZWZhdWx0X2V4cG9ydF9pbWFnZSlcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBleHBvcnREYXRhIERlZmF1bHQ6IFtgREVGQVVMVF9FWFBPUlRfREFUQWBdKCNkZWZhdWx0X2V4cG9ydF9kYXRhKVxuICogQHByb3BlcnR5IHtPYmplY3R9IG1hcENvbnRyb2xzIERlZmF1bHQ6IFtgREVGQVVMVF9NQVBfQ09OVFJPTFNgXSgjZGVmYXVsdF9tYXBfY29udHJvbHMpXG4gKiBAcHJvcGVydHkge251bWJlcn0gYWN0aXZlTWFwSW5kZXggZGVmaW5lcyB3aGljaCBtYXAgdGhlIHVzZXIgY2xpY2tlZCBvbi4gRGVmYXVsdDogMFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgSU5JVElBTF9VSV9TVEFURSA9IHtcbiAgcmVhZE9ubHk6IGZhbHNlLFxuICBhY3RpdmVTaWRlUGFuZWw6IERFRkFVTFRfQUNUSVZFX1NJREVfUEFORUwsXG4gIGN1cnJlbnRNb2RhbDogREVGQVVMVF9NT0RBTCxcbiAgZGF0YXNldEtleVRvUmVtb3ZlOiBudWxsLFxuICB2aXNpYmxlRHJvcGRvd246IG51bGwsXG4gIC8vIGV4cG9ydCBpbWFnZSBtb2RhbCB1aVxuICBleHBvcnRJbWFnZTogREVGQVVMVF9FWFBPUlRfSU1BR0UsXG4gIC8vIGV4cG9ydCBkYXRhIG1vZGFsIHVpXG4gIGV4cG9ydERhdGE6IERFRkFVTFRfRVhQT1JUX0RBVEEsXG4gIC8vIGh0bWwgZXhwb3J0XG4gIGV4cG9ydE1hcDogREVGQVVMVF9FWFBPUlRfTUFQLFxuICAvLyBtYXAgY29udHJvbCBwYW5lbHNcbiAgbWFwQ29udHJvbHM6IERFRkFVTFRfTUFQX0NPTlRST0xTLFxuICAvLyB1aSBub3RpZmljYXRpb25zXG4gIG5vdGlmaWNhdGlvbnM6IERFRkFVTFRfTk9USUZJQ0FUSU9OUyxcbiAgLy8gbG9hZCBmaWxlc1xuICBsb2FkRmlsZXM6IERFRkFVTFRfTE9BRF9GSUxFUyxcbiAgLy8gTG9jYWxlIG9mIHRoZSBVSVxuICBsb2NhbGU6IExPQ0FMRVMuZW5cbn07XG5cbi8qIFVwZGF0ZXJzICovXG4vKipcbiAqIFRvZ2dsZSBhY3RpdmUgc2lkZSBwYW5lbFxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIGB1aVN0YXRlYFxuICogQHBhcmFtIHtPYmplY3R9IGFjdGlvblxuICogQHBhcmFtIHtzdHJpbmd8bnVsbH0gYWN0aW9uLnBheWxvYWQgaWQgb2Ygc2lkZSBwYW5lbCB0byBiZSBzaG93biwgb25lIG9mIGBsYXllcmAsIGBmaWx0ZXJgLCBgaW50ZXJhY3Rpb25gLCBgbWFwYC4gY2xvc2Ugc2lkZSBwYW5lbCBpZiBgbnVsbGBcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlU2lkZVBhbmVsVXBkYXRlciA9IChzdGF0ZSwge3BheWxvYWQ6IGlkfSkgPT4ge1xuICByZXR1cm4gaWQgPT09IHN0YXRlLmFjdGl2ZVNpZGVQYW5lbFxuICAgID8gc3RhdGVcbiAgICA6IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGFjdGl2ZVNpZGVQYW5lbDogaWRcbiAgICAgIH07XG59O1xuXG4vKipcbiAqIFNob3cgYW5kIGhpZGUgbW9kYWwgZGlhbG9nXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgYHVpU3RhdGVgXG4gKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfSBhY3Rpb24ucGF5bG9hZCBpZCBvZiBtb2RhbCB0byBiZSBzaG93biwgbnVsbCB0byBoaWRlIG1vZGFscy4gT25lIG9mOlxuICpcbiAqICAtIFtgREFUQV9UQUJMRV9JRGBdKC4uL2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzLm1kI2RhdGFfdGFibGVfaWQpXG4gKiAgLSBbYERFTEVURV9EQVRBX0lEYF0oLi4vY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MubWQjZGVsZXRlX2RhdGFfaWQpXG4gKiAgLSBbYEFERF9EQVRBX0lEYF0oLi4vY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MubWQjYWRkX2RhdGFfaWQpXG4gKiAgLSBbYEVYUE9SVF9JTUFHRV9JRGBdKC4uL2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzLm1kI2V4cG9ydF9pbWFnZV9pZClcbiAqICAtIFtgRVhQT1JUX0RBVEFfSURgXSguLi9jb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncy5tZCNleHBvcnRfZGF0YV9pZClcbiAqICAtIFtgQUREX01BUF9TVFlMRV9JRGBdKC4uL2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzLm1kI2FkZF9tYXBfc3R5bGVfaWQpXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBuZXh0U3RhdGVcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHRvZ2dsZU1vZGFsVXBkYXRlciA9IChzdGF0ZSwge3BheWxvYWQ6IGlkfSkgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIGN1cnJlbnRNb2RhbDogaWRcbn0pO1xuXG4vKipcbiAqIEhpZGUgYW5kIHNob3cgc2lkZSBwYW5lbCBoZWFkZXIgZHJvcGRvd24sIGFjdGl2YXRlZCBieSBjbGlja2luZyB0aGUgc2hhcmUgbGluayBvbiB0b3Agb2YgdGhlIHNpZGUgcGFuZWxcbiAqIEBtZW1iZXJvZiB1aVN0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdWlTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24ucGF5bG9hZCBpZCBvZiB0aGUgZHJvcGRvd25cbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3Qgc2hvd0V4cG9ydERyb3Bkb3duVXBkYXRlciA9IChzdGF0ZSwge3BheWxvYWQ6IGlkfSkgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIHZpc2libGVEcm9wZG93bjogaWRcbn0pO1xuXG4vKipcbiAqIEhpZGUgc2lkZSBwYW5lbCBoZWFkZXIgZHJvcGRvd24sIGFjdGl2YXRlZCBieSBjbGlja2luZyB0aGUgc2hhcmUgbGluayBvbiB0b3Agb2YgdGhlIHNpZGUgcGFuZWxcbiAqIEBtZW1iZXJvZiB1aVN0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdWlTdGF0ZWBcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgaGlkZUV4cG9ydERyb3Bkb3duVXBkYXRlciA9IHN0YXRlID0+ICh7XG4gIC4uLnN0YXRlLFxuICB2aXNpYmxlRHJvcGRvd246IG51bGxcbn0pO1xuXG4vKipcbiAqIFRvZ2dsZSBhY3RpdmUgbWFwIGNvbnRyb2wgcGFuZWxcbiAqIEBtZW1iZXJvZiB1aVN0YXRlVXBkYXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBgdWlTdGF0ZWBcbiAqIEBwYXJhbSB7T2JqZWN0fSBhY3Rpb24gYWN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uLnBheWxvYWQgbWFwIGNvbnRyb2wgcGFuZWwgaWQsIG9uZSBvZiB0aGUga2V5cyBvZjogW2BERUZBVUxUX01BUF9DT05UUk9MU2BdKCNkZWZhdWx0X21hcF9jb250cm9scylcbiAqIEByZXR1cm5zIHtPYmplY3R9IG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlTWFwQ29udHJvbFVwZGF0ZXIgPSAoc3RhdGUsIHtwYXlsb2FkOiB7cGFuZWxJZCwgaW5kZXggPSAwfX0pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBtYXBDb250cm9sczoge1xuICAgIC4uLnN0YXRlLm1hcENvbnRyb2xzLFxuICAgIFtwYW5lbElkXToge1xuICAgICAgLi4uc3RhdGUubWFwQ29udHJvbHNbcGFuZWxJZF0sXG4gICAgICAvLyB0aGlzIGhhbmRsZXMgc3BsaXQgbWFwIGludGVyYWN0aW9uXG4gICAgICAvLyBUb2dnbGluZyBmcm9tIHdpdGhpbiB0aGUgc2FtZSBtYXAgd2lsbCBzaW1wbHkgdG9nZ2xlIHRoZSBhY3RpdmUgcHJvcGVydHlcbiAgICAgIC8vIFRvZ2dsaW5nIGZyb20gd2l0aGluIGRpZmZlcmVudCBtYXBzIHdlIHNldCB0aGUgYWN0aXZlIHByb3BlcnR5IHRvIHRydWVcbiAgICAgIGFjdGl2ZTpcbiAgICAgICAgaW5kZXggPT09IHN0YXRlLm1hcENvbnRyb2xzW3BhbmVsSWRdLmFjdGl2ZU1hcEluZGV4XG4gICAgICAgICAgPyAhc3RhdGUubWFwQ29udHJvbHNbcGFuZWxJZF0uYWN0aXZlXG4gICAgICAgICAgOiB0cnVlLFxuICAgICAgYWN0aXZlTWFwSW5kZXg6IGluZGV4XG4gICAgfVxuICB9XG59KTtcblxuXG5cbi8qKlxuICogVG9nZ2xlIGFjdGl2ZSBtYXAgY29udHJvbCBwYW5lbFxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHtPYmplY3