kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
803 lines (759 loc) • 89.4 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toggleSplitMapUpdater = exports.toggleSidePanelUpdater = exports.toggleSidePanelCloseButtonUpdater = exports.togglePanelListViewUpdater = exports.toggleModalUpdater = exports.toggleMapControlUpdater = exports.startExportingImageUpdater = exports.showExportDropdownUpdater = exports.showDatasetTableUpdater = exports.setUserMapboxAccessTokenUpdater = exports.setMapControlVisibilityUpdater = exports.setMapControlSettingsUpdater = exports.setLocaleUpdater = exports.setExportSelectedDatasetUpdater = exports.setExportMapHTMLModeUpdater = exports.setExportMapFormatUpdater = exports.setExportImageSettingUpdater = exports.setExportImageErrorUpdater = exports.setExportImageDataUriUpdater = exports.setExportFilteredUpdater = exports.setExportDataUpdater = exports.setExportDataTypeUpdater = exports.removeNotificationUpdater = exports.openDeleteModalUpdater = exports.loadFilesUpdater = exports.loadFilesSuccessUpdater = exports.loadFilesErrUpdater = exports.initUiStateUpdater = exports.hideExportDropdownUpdater = exports.cleanupExportImageUpdater = exports.addNotificationUpdater = exports.INITIAL_UI_STATE = exports.DEFAULT_NOTIFICATIONS = exports.DEFAULT_MODAL = exports.DEFAULT_MAP_CONTROLS = exports.DEFAULT_LOAD_FILES = exports.DEFAULT_EXPORT_MAP = exports.DEFAULT_EXPORT_JSON = exports.DEFAULT_EXPORT_IMAGE = exports.DEFAULT_EXPORT_HTML = exports.DEFAULT_EXPORT_DATA = exports.DEFAULT_ACTIVE_SIDE_PANEL = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _src = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/constants/src");
var _src2 = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/localization/src");
var _src3 = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/utils/src");
var _composerHelpers = require("./composer-helpers");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
var DEFAULT_ACTIVE_SIDE_PANEL = exports.DEFAULT_ACTIVE_SIDE_PANEL = 'layer';
var DEFAULT_MODAL = exports.DEFAULT_MODAL = _src.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 @typescript-eslint/no-unused-vars */
// @ts-ignore
var uiStateUpdaters = null;
/* eslint-enable @typescript-eslint/no-unused-vars */
var DEFAULT_MAP_CONTROLS_FEATURES = {
show: true,
active: false,
disableClose: false,
// defines which map index users are interacting with (through map controls)
activeMapIndex: 0
};
var DEFAULT_MAP_LEGEND_CONTROL = _objectSpread(_objectSpread({}, DEFAULT_MAP_CONTROLS_FEATURES), {}, {
disableEdit: false
});
/**
* A list of map control visibility and whether is it active.
* @memberof uiStateUpdaters
* @constant
* @property visibleLayers Default: `{show: true, active: false}`
* @property mapLegend Default: `{show: true, active: false}`
* @property toggle3d Default: `{show: true}`
* @property splitMap Default: `{show: true}`
* @property mapDraw Default: `{show: true, active: false}`
* @property mapLocale Default: `{show: false, active: false}`
* @public
*/
var DEFAULT_MAP_CONTROLS = exports.DEFAULT_MAP_CONTROLS = Object.keys(_src.MAP_CONTROLS).reduce(function (_final, current) {
return _objectSpread(_objectSpread({}, _final), {}, (0, _defineProperty2["default"])({}, current, current === _src.MAP_CONTROLS.mapLegend ? DEFAULT_MAP_LEGEND_CONTROL : DEFAULT_MAP_CONTROLS_FEATURES));
}, {});
/**
* Default image export config
* @memberof uiStateUpdaters
* @constant
* @property ratio Default: `'SCREEN'`,
* @property resolution Default: `'ONE_X'`,
* @property legend Default: `false`,
* @property mapH Default: 0,
* @property mapW Default: 0,
* @property imageSize Default: {zoomOffset: 0, scale: 1, imageW: 0, imageH: 0},
* @property imageDataUri Default: `''`,
* @property exporting Default: `false`
* @property error Default: `false`
* @property escapeXhtmlForWebpack Default: `true`
* @public
*/
var DEFAULT_EXPORT_IMAGE = exports.DEFAULT_EXPORT_IMAGE = {
// user options
ratio: _src.EXPORT_IMG_RATIOS.SCREEN,
resolution: _src.RESOLUTIONS.ONE_X,
legend: false,
mapH: 0,
mapW: 0,
imageSize: {
zoomOffset: 0,
scale: 1,
imageW: 0,
imageH: 0
},
// when this is set to true, the mock map viewport will move to the center of data
center: false,
// exporting state
imageDataUri: '',
// exporting: used to attach plot-container to dom
exporting: false,
// processing: used as loading indicator when export image is being produced
processing: false,
error: false,
// whether to apply fix for uglify error in dom-to-image (should be true for webpack builds)
escapeXhtmlForWebpack: true
};
var DEFAULT_LOAD_FILES = exports.DEFAULT_LOAD_FILES = {
fileLoading: false
};
/**
* Default initial `exportData` settings
* @memberof uiStateUpdaters
* @constant
* @property selectedDataset Default: `''`,
* @property dataType Default: `'csv'`,
* @property filtered Default: `true`,
* @public
*/
var DEFAULT_EXPORT_DATA = exports.DEFAULT_EXPORT_DATA = {
selectedDataset: '',
dataType: _src.EXPORT_DATA_TYPE.CSV,
filtered: true
};
/**
* @constant
*/
var DEFAULT_NOTIFICATIONS = exports.DEFAULT_NOTIFICATIONS = [];
/**
* @constant
* @property exportMapboxAccessToken - Default: null, this is used when we provide a default mapbox token for users to take advantage of
* @property userMapboxToken - Default: '', mapbox token provided by user through input field
* @property mode - Default: 'READ', read only or editable
* @public
*/
var DEFAULT_EXPORT_HTML = exports.DEFAULT_EXPORT_HTML = {
exportMapboxAccessToken: null,
userMapboxToken: '',
mode: _src.EXPORT_HTML_MAP_MODES.READ
};
/**
* @constant
* @property hasData - Default: 'true',
* @public
*/
var DEFAULT_EXPORT_JSON = exports.DEFAULT_EXPORT_JSON = {
hasData: true
};
/**
* Export Map Config
* @constant
* @property HTML - Default: 'DEFAULT_EXPORT_HTML',
* @property JSON - Default: 'DEFAULT_EXPORT_JSON',
* @property format - Default: 'HTML',
* @public
*/
var DEFAULT_EXPORT_MAP = exports.DEFAULT_EXPORT_MAP = (0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])({}, _src.EXPORT_MAP_FORMATS.HTML, DEFAULT_EXPORT_HTML), _src.EXPORT_MAP_FORMATS.JSON, DEFAULT_EXPORT_JSON), "format", _src.EXPORT_MAP_FORMATS.HTML);
/**
* Default initial `uiState`
* @memberof uiStateUpdaters
* @constant
* @property readOnly Default: `false`
* @property activeSidePanel Default: `'layer'`
* @property currentModal Default: `'addData'`
* @property datasetKeyToRemove Default: `null`
* @property visibleDropdown Default: `null`
* @property exportImage Default: [`DEFAULT_EXPORT_IMAGE`](#default_export_image)
* @property exportData Default: [`DEFAULT_EXPORT_DATA`](#default_export_data)
* @property exportMap Default: [`DEFAULT_EXPORT_MAP`](#default_export_map)
* @property mapControls Default: [`DEFAULT_MAP_CONTROLS`](#default_map_controls)
* @property notifications Default: `[]`
* @property notifications Default: `[]`
* @property loadFiles
* @property isSidePanelCloseButtonVisible Default: `true`
* @public
*/
var INITIAL_UI_STATE = exports.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: _src2.LOCALE_CODES.en,
layerPanelListView: 'list',
filterPanelListView: 'list',
isSidePanelCloseButtonVisible: true
};
/* Updaters */
/**
* @memberof uiStateUpdaters
*/
var initUiStateUpdater = exports.initUiStateUpdater = function initUiStateUpdater(state, action) {
return _objectSpread(_objectSpread({}, state), (action.payload || {}).initialUiState);
};
/**
* Toggle active side panel
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload id of side panel to be shown, one of `layer`, `filter`, `interaction`, `map`. close side panel if `null`
* @returns nextState
* @public
*/
var toggleSidePanelUpdater = exports.toggleSidePanelUpdater = function toggleSidePanelUpdater(state, _ref) {
var id = _ref.payload;
return id === state.activeSidePanel ? state : _objectSpread(_objectSpread({}, state), {}, {
activeSidePanel: id
});
};
/**
* Show and hide modal dialog
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @paramaction.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 nextState
* @public
*/
var toggleModalUpdater = exports.toggleModalUpdater = function toggleModalUpdater(state, _ref2) {
var id = _ref2.payload;
return _objectSpread(_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
* @public
*/
var showExportDropdownUpdater = exports.showExportDropdownUpdater = function showExportDropdownUpdater(state, _ref3) {
var id = _ref3.payload;
return _objectSpread(_objectSpread({}, state), {}, {
visibleDropdown: id
});
};
/**
* Hide side panel header dropdown, activated by clicking the share link on top of the side panel
* @memberof uiStateUpdaters
* @public
*/
var hideExportDropdownUpdater = exports.hideExportDropdownUpdater = function hideExportDropdownUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
visibleDropdown: null
});
};
/**
* Toggle side panel close button on top left of the side panel
* @memberof uiStateUpdaters
* @public
*/
var toggleSidePanelCloseButtonUpdater = exports.toggleSidePanelCloseButtonUpdater = function toggleSidePanelCloseButtonUpdater(state, _ref4) {
var show = _ref4.payload.show;
return _objectSpread(_objectSpread({}, state), {}, {
isSidePanelCloseButtonVisible: show
});
};
/**
* Toggle active map control panel
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action action
* @param action.payload map control panel id, one of the keys of: [`DEFAULT_MAP_CONTROLS`](#default_map_controls)
* @returns nextState
* @public
*/
var toggleMapControlUpdater = exports.toggleMapControlUpdater = function toggleMapControlUpdater(state, _ref5) {
var _state$mapControls$pa, _state$mapControls$dr;
var _ref5$payload = _ref5.payload,
panelId = _ref5$payload.panelId,
_ref5$payload$index = _ref5$payload.index,
index = _ref5$payload$index === void 0 ? 0 : _ref5$payload$index;
var updatedState = state;
// The effect panel and ai assistant panel can not be active at the same time
// so we need to deactivate the other panel when one is activated
var panelToDeactivate = panelId === _src.MAP_CONTROLS.effect ? _src.MAP_CONTROLS.aiAssistant : panelId === _src.MAP_CONTROLS.aiAssistant ? _src.MAP_CONTROLS.effect : null;
// To to toggle the mapDraw and mapLocal dropdowns
// We have to deactivate the other active dropdown
var dropdownToDeactivate = panelId === _src.MAP_CONTROLS.mapDraw ? _src.MAP_CONTROLS.mapLocale : panelId === _src.MAP_CONTROLS.mapLocale ? _src.MAP_CONTROLS.mapDraw : null;
// If we need to deactivate a competing panel and it's currently active
if (panelToDeactivate && (_state$mapControls$pa = state.mapControls[panelToDeactivate]) !== null && _state$mapControls$pa !== void 0 && _state$mapControls$pa.active) {
updatedState = _objectSpread(_objectSpread({}, state), {}, {
mapControls: _objectSpread(_objectSpread({}, updatedState.mapControls), {}, (0, _defineProperty2["default"])({}, panelToDeactivate, _objectSpread(_objectSpread({}, updatedState.mapControls[panelToDeactivate]), {}, {
active: false
})))
});
}
// If we need to deactivate a competing dropdown and it's currently active
if (dropdownToDeactivate && (_state$mapControls$dr = state.mapControls[dropdownToDeactivate]) !== null && _state$mapControls$dr !== void 0 && _state$mapControls$dr.active) {
updatedState = _objectSpread(_objectSpread({}, state), {}, {
mapControls: _objectSpread(_objectSpread({}, updatedState.mapControls), {}, (0, _defineProperty2["default"])({}, dropdownToDeactivate, _objectSpread(_objectSpread({}, updatedState.mapControls[dropdownToDeactivate]), {}, {
active: false
})))
});
}
return _objectSpread(_objectSpread({}, updatedState), {}, {
mapControls: _objectSpread(_objectSpread({}, updatedState.mapControls), {}, (0, _defineProperty2["default"])({}, panelId, _objectSpread(_objectSpread({}, updatedState.mapControls[panelId]), {}, {
active: !updatedState.mapControls[panelId].active,
activeMapIndex: index
})))
});
};
/**
* Toggle map control visibility
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action action
* @param action.payload map control panel id, one of the keys of: [`DEFAULT_MAP_CONTROLS`](#default_map_controls)
* @returns nextState
* @public
*/
var setMapControlVisibilityUpdater = exports.setMapControlVisibilityUpdater = function setMapControlVisibilityUpdater(state, _ref6) {
var _state$mapControls;
var _ref6$payload = _ref6.payload,
panelId = _ref6$payload.panelId,
show = _ref6$payload.show;
if (!((_state$mapControls = state.mapControls) !== null && _state$mapControls !== void 0 && _state$mapControls[panelId])) {
return state;
}
return _objectSpread(_objectSpread({}, state), {}, {
mapControls: _objectSpread(_objectSpread({}, state.mapControls), {}, (0, _defineProperty2["default"])({}, panelId, _objectSpread(_objectSpread({}, state.mapControls[panelId]), {}, {
show: Boolean(show)
})))
});
};
/**
* Toggle map control settings
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action action
* @param action.payload map control panel id, one of the keys of: [`DEFAULT_MAP_CONTROLS`](#default_map_controls)
* @returns nextState
* @public
*/
var setMapControlSettingsUpdater = exports.setMapControlSettingsUpdater = function setMapControlSettingsUpdater(state, _ref7) {
var _state$mapControls2;
var _ref7$payload = _ref7.payload,
panelId = _ref7$payload.panelId,
settings = _ref7$payload.settings;
var mapControl = (_state$mapControls2 = state.mapControls) === null || _state$mapControls2 === void 0 ? void 0 : _state$mapControls2[panelId];
if (!mapControl) {
return state;
}
return _objectSpread(_objectSpread({}, state), {}, {
mapControls: _objectSpread(_objectSpread({}, state.mapControls), {}, (0, _defineProperty2["default"])({}, panelId, _objectSpread(_objectSpread({}, mapControl), {}, {
settings: _objectSpread(_objectSpread({}, mapControl.settings), settings)
})))
});
};
/**
* Toggle active map control panel
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload dataset id
* @returns nextState
* @public
*/
var openDeleteModalUpdater = exports.openDeleteModalUpdater = function openDeleteModalUpdater(state, _ref8) {
var datasetKeyToRemove = _ref8.payload;
return _objectSpread(_objectSpread({}, state), {}, {
currentModal: _src.DELETE_DATA_ID,
datasetKeyToRemove: datasetKeyToRemove
});
};
/**
* Set `exportImage.legend` to `true` or `false`
* @memberof uiStateUpdaters
* @param state `uiState`
* @returns nextState
* @public
*/
var setExportImageSettingUpdater = exports.setExportImageSettingUpdater = function setExportImageSettingUpdater(state, _ref9) {
var newSetting = _ref9.payload;
var updated = _objectSpread(_objectSpread({}, state.exportImage), newSetting);
var imageSize = (0, _src3.calculateExportImageSize)(updated) || state.exportImage.imageSize;
return _objectSpread(_objectSpread({}, state), {}, {
exportImage: _objectSpread(_objectSpread({}, updated), {}, {
// @ts-expect-error
// TODO: calculateExportImageSize does not return imageSize.zoomOffset,
// do we need take this value from current state, or return defaul value = 0
imageSize: imageSize
})
});
};
/**
* Set `exportImage.setExportImageDataUri` to a image dataUri
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload export image data uri
* @returns nextState
* @public
*/
var setExportImageDataUriUpdater = exports.setExportImageDataUriUpdater = function setExportImageDataUriUpdater(state, _ref10) {
var dataUri = _ref10.payload;
if (dataUri === state.exportImage.imageDataUri) {
return state;
}
return _objectSpread(_objectSpread({}, state), {}, {
exportImage: _objectSpread(_objectSpread({}, state.exportImage), {}, {
processing: false,
imageDataUri: dataUri
})
});
};
/**
* @memberof uiStateUpdaters
* @public
*/
var setExportImageErrorUpdater = exports.setExportImageErrorUpdater = function setExportImageErrorUpdater(state, _ref11) {
var error = _ref11.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportImage: _objectSpread(_objectSpread({}, state.exportImage), {}, {
processing: false,
error: error
})
});
};
/**
* Delete cached export image
* @memberof uiStateUpdaters
* @public
*/
var cleanupExportImageUpdater = exports.cleanupExportImageUpdater = function cleanupExportImageUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
exportImage: _objectSpread(_objectSpread({}, state.exportImage), {}, {
exporting: false,
imageDataUri: '',
error: false,
processing: false,
center: false
})
});
};
/**
* Start image exporting flow
* @memberof uiStateUpdaters
* @param state
* @param options
* @returns {UiState}
* @public
*/
var startExportingImageUpdater = exports.startExportingImageUpdater = function startExportingImageUpdater(state, _ref12) {
var _ref12$payload = _ref12.payload,
options = _ref12$payload === void 0 ? {} : _ref12$payload;
var imageSettings = _objectSpread(_objectSpread({}, options), {}, {
exporting: true
});
return (0, _composerHelpers.compose_)([cleanupExportImageUpdater, (0, _composerHelpers.apply_)(setExportImageSettingUpdater, (0, _composerHelpers.payload_)(imageSettings))])(state);
};
/**
* Set selected dataset for export
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload dataset id
* @returns nextState
* @public
*/
var setExportSelectedDatasetUpdater = exports.setExportSelectedDatasetUpdater = function setExportSelectedDatasetUpdater(state, _ref13) {
var dataset = _ref13.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportData: _objectSpread(_objectSpread({}, state.exportData), {}, {
selectedDataset: dataset
})
});
};
/**
* Set data format for exporting data
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload one of `'text/csv'`
* @returns nextState
* @public
*/
var setExportDataTypeUpdater = exports.setExportDataTypeUpdater = function setExportDataTypeUpdater(state, _ref14) {
var dataType = _ref14.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportData: _objectSpread(_objectSpread({}, state.exportData), {}, {
dataType: dataType
})
});
};
/**
* Whether to export filtered data, `true` or `false`
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload
* @returns nextState
* @public
*/
var setExportFilteredUpdater = exports.setExportFilteredUpdater = function setExportFilteredUpdater(state, _ref15) {
var filtered = _ref15.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportData: _objectSpread(_objectSpread({}, state.exportData), {}, {
filtered: filtered
})
});
};
/**
* Whether to including data in map config, toggle between `true` or `false`
* @memberof uiStateUpdaters
* @param state `uiState`
* @returns nextState
* @public
*/
var setExportDataUpdater = exports.setExportDataUpdater = function setExportDataUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
exportMap: _objectSpread(_objectSpread({}, state.exportMap), {}, (0, _defineProperty2["default"])({}, _src.EXPORT_MAP_FORMATS.JSON, _objectSpread(_objectSpread({}, state.exportMap[_src.EXPORT_MAP_FORMATS.JSON]), {}, {
hasData: !state.exportMap[_src.EXPORT_MAP_FORMATS.JSON].hasData
})))
});
};
/**
* whether to export a mapbox access to HTML single page
* @param state - `uiState`
* @param action
* @param action.payload
* @returns nextState
* @public
*/
var setUserMapboxAccessTokenUpdater = exports.setUserMapboxAccessTokenUpdater = function setUserMapboxAccessTokenUpdater(state, _ref16) {
var userMapboxToken = _ref16.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportMap: _objectSpread(_objectSpread({}, state.exportMap), {}, (0, _defineProperty2["default"])({}, _src.EXPORT_MAP_FORMATS.HTML, _objectSpread(_objectSpread({}, state.exportMap[_src.EXPORT_MAP_FORMATS.HTML]), {}, {
userMapboxToken: userMapboxToken
})))
});
};
/**
* Sets the export map format
* @param state - `uiState`
* @param action
* @param action.payload format to use to export the map into
* @return nextState
*/
var setExportMapFormatUpdater = exports.setExportMapFormatUpdater = function setExportMapFormatUpdater(state, _ref17) {
var format = _ref17.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportMap: _objectSpread(_objectSpread({}, state.exportMap), {}, {
// @ts-expect-error
format: format
})
});
};
/**
* Set the export html map mode
* @param state - `uiState`
* @param action
* @param action.payload to be set (available modes: EXPORT_HTML_MAP_MODES)
* @return nextState
*/
var setExportMapHTMLModeUpdater = exports.setExportMapHTMLModeUpdater = function setExportMapHTMLModeUpdater(state, _ref18) {
var mode = _ref18.payload;
return _objectSpread(_objectSpread({}, state), {}, {
exportMap: _objectSpread(_objectSpread({}, state.exportMap), {}, (0, _defineProperty2["default"])({}, _src.EXPORT_MAP_FORMATS.HTML, _objectSpread(_objectSpread({}, state.exportMap[_src.EXPORT_MAP_FORMATS.HTML]), {}, {
mode: mode
})))
});
};
/**
* Adds a new notification.
* Updates a notification in case of matching ids.
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload Params of a notification
* @returns nextState
* @public
*/
var addNotificationUpdater = exports.addNotificationUpdater = function addNotificationUpdater(state, _ref19) {
var payload = _ref19.payload;
var oldNotifications = state.notifications || [];
// @ts-expect-error
var payloadId = payload === null || payload === void 0 ? void 0 : payload.id;
var notificationToUpdate = payloadId ? oldNotifications.find(function (n) {
return n.id === payloadId;
}) : null;
var notifications;
if (notificationToUpdate) {
notifications = oldNotifications.map(function (n) {
return n.id === payloadId ? (0, _src3.createNotification)(_objectSpread(_objectSpread({}, payload), {}, {
count: n.count + 1
})) : n;
});
} else {
notifications = [].concat((0, _toConsumableArray2["default"])(oldNotifications), [(0, _src3.createNotification)(payload)]);
}
return _objectSpread(_objectSpread({}, state), {}, {
notifications: notifications
});
};
/**
* Remove a notification
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload id of the notification to be removed
* @returns nextState
* @public
*/
var removeNotificationUpdater = exports.removeNotificationUpdater = function removeNotificationUpdater(state, _ref20) {
var id = _ref20.payload;
return _objectSpread(_objectSpread({}, state), {}, {
notifications: state.notifications.filter(function (n) {
return n.id !== id;
})
});
};
/**
* Fired when file loading begin
* @memberof uiStateUpdaters
* @param state `uiState`
* @returns nextState
* @public
*/
var loadFilesUpdater = exports.loadFilesUpdater = function loadFilesUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
loadFiles: _objectSpread(_objectSpread({}, state.loadFiles), {}, {
fileLoading: true
})
});
};
/**
* Handles loading file success and set fileLoading property to false
* @memberof uiStateUpdaters
* @param state `uiState`
* @returns nextState
*/
var loadFilesSuccessUpdater = exports.loadFilesSuccessUpdater = function loadFilesSuccessUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
loadFiles: _objectSpread(_objectSpread({}, state.loadFiles), {}, {
fileLoading: false
})
});
};
/**
* Handles load file error and set fileLoading property to false
* @memberof uiStateUpdaters
* @param state
* @param action
* @param action.error
* @returns nextState
* @public
*/
var loadFilesErrUpdater = exports.loadFilesErrUpdater = function loadFilesErrUpdater(state, _ref21) {
var error = _ref21.error;
return addNotificationUpdater(_objectSpread(_objectSpread({}, state), {}, {
loadFiles: _objectSpread(_objectSpread({}, state.loadFiles), {}, {
fileLoading: false
})
}), {
payload: (0, _src3.errorNotification)({
message: (error || {}).message || 'Failed to upload files',
topic: _src.DEFAULT_NOTIFICATION_TOPICS.global
})
});
};
/**
* Handles toggle map split and reset all map control index to 0
* @memberof uiStateUpdaters
* @param state
* @returns nextState
* @public
*/
var toggleSplitMapUpdater = exports.toggleSplitMapUpdater = function toggleSplitMapUpdater(state) {
return _objectSpread(_objectSpread({}, state), {}, {
mapControls: Object.entries(state.mapControls).reduce(function (acc, entry) {
return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, entry[0], _objectSpread(_objectSpread({}, entry[1]), {}, {
activeMapIndex: 0
})));
}, {})
});
};
/**
* Toggle modal data
* @memberof uiStateUpdaters
* @param state
* @returns nextState
* @public
*/
var showDatasetTableUpdater = exports.showDatasetTableUpdater = function showDatasetTableUpdater(state) {
return toggleModalUpdater(state, {
payload: _src.DATA_TABLE_ID
});
};
/**
* Set the locale of the UI
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload
* @param action.payload.locale locale
* @returns nextState
* @public
*/
var setLocaleUpdater = exports.setLocaleUpdater = function setLocaleUpdater(state, _ref22) {
var locale = _ref22.payload.locale;
return _objectSpread(_objectSpread({}, state), {}, {
locale: locale
});
};
/**
* Toggle layer panel list view
* @memberof uiStateUpdaters
* @param state `uiState`
* @param action
* @param action.payload layer panel listView value. Can be 'list' or 'sortByDataset'
* @returns nextState
* @public
*/
var togglePanelListViewUpdater = exports.togglePanelListViewUpdater = function togglePanelListViewUpdater(state, _ref23) {
var _ref23$payload = _ref23.payload,
panelId = _ref23$payload.panelId,
listView = _ref23$payload.listView;
var stateProp = panelId === 'layer' ? 'layerPanelListView' : panelId === 'filter' ? 'filterPanelListView' : null;
if (!stateProp || state[stateProp] === listView) {
return state;
}
return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2["default"])({}, stateProp, listView));
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3JjIiwicmVxdWlyZSIsIl9zcmMyIiwiX3NyYzMiLCJfY29tcG9zZXJIZWxwZXJzIiwib3duS2V5cyIsImUiLCJyIiwidCIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJERUZBVUxUX0FDVElWRV9TSURFX1BBTkVMIiwiZXhwb3J0cyIsIkRFRkFVTFRfTU9EQUwiLCJBRERfREFUQV9JRCIsInVpU3RhdGVVcGRhdGVycyIsIkRFRkFVTFRfTUFQX0NPTlRST0xTX0ZFQVRVUkVTIiwic2hvdyIsImFjdGl2ZSIsImRpc2FibGVDbG9zZSIsImFjdGl2ZU1hcEluZGV4IiwiREVGQVVMVF9NQVBfTEVHRU5EX0NPTlRST0wiLCJkaXNhYmxlRWRpdCIsIkRFRkFVTFRfTUFQX0NPTlRST0xTIiwiTUFQX0NPTlRST0xTIiwicmVkdWNlIiwiZmluYWwiLCJjdXJyZW50IiwibWFwTGVnZW5kIiwiREVGQVVMVF9FWFBPUlRfSU1BR0UiLCJyYXRpbyIsIkVYUE9SVF9JTUdfUkFUSU9TIiwiU0NSRUVOIiwicmVzb2x1dGlvbiIsIlJFU09MVVRJT05TIiwiT05FX1giLCJsZWdlbmQiLCJtYXBIIiwibWFwVyIsImltYWdlU2l6ZSIsInpvb21PZmZzZXQiLCJzY2FsZSIsImltYWdlVyIsImltYWdlSCIsImNlbnRlciIsImltYWdlRGF0YVVyaSIsImV4cG9ydGluZyIsInByb2Nlc3NpbmciLCJlcnJvciIsImVzY2FwZVhodG1sRm9yV2VicGFjayIsIkRFRkFVTFRfTE9BRF9GSUxFUyIsImZpbGVMb2FkaW5nIiwiREVGQVVMVF9FWFBPUlRfREFUQSIsInNlbGVjdGVkRGF0YXNldCIsImRhdGFUeXBlIiwiRVhQT1JUX0RBVEFfVFlQRSIsIkNTViIsImZpbHRlcmVkIiwiREVGQVVMVF9OT1RJRklDQVRJT05TIiwiREVGQVVMVF9FWFBPUlRfSFRNTCIsImV4cG9ydE1hcGJveEFjY2Vzc1Rva2VuIiwidXNlck1hcGJveFRva2VuIiwibW9kZSIsIkVYUE9SVF9IVE1MX01BUF9NT0RFUyIsIlJFQUQiLCJERUZBVUxUX0VYUE9SVF9KU09OIiwiaGFzRGF0YSIsIkRFRkFVTFRfRVhQT1JUX01BUCIsIkVYUE9SVF9NQVBfRk9STUFUUyIsIkhUTUwiLCJKU09OIiwiSU5JVElBTF9VSV9TVEFURSIsInJlYWRPbmx5IiwiYWN0aXZlU2lkZVBhbmVsIiwiY3VycmVudE1vZGFsIiwiZGF0YXNldEtleVRvUmVtb3ZlIiwidmlzaWJsZURyb3Bkb3duIiwiZXhwb3J0SW1hZ2UiLCJleHBvcnREYXRhIiwiZXhwb3J0TWFwIiwibWFwQ29udHJvbHMiLCJub3RpZmljYXRpb25zIiwibG9hZEZpbGVzIiwibG9jYWxlIiwiTE9DQUxFX0NPREVTIiwiZW4iLCJsYXllclBhbmVsTGlzdFZpZXciLCJmaWx0ZXJQYW5lbExpc3RWaWV3IiwiaXNTaWRlUGFuZWxDbG9zZUJ1dHRvblZpc2libGUiLCJpbml0VWlTdGF0ZVVwZGF0ZXIiLCJzdGF0ZSIsImFjdGlvbiIsInBheWxvYWQiLCJpbml0aWFsVWlTdGF0ZSIsInRvZ2dsZVNpZGVQYW5lbFVwZGF0ZXIiLCJfcmVmIiwiaWQiLCJ0b2dnbGVNb2RhbFVwZGF0ZXIiLCJfcmVmMiIsInNob3dFeHBvcnREcm9wZG93blVwZGF0ZXIiLCJfcmVmMyIsImhpZGVFeHBvcnREcm9wZG93blVwZGF0ZXIiLCJ0b2dnbGVTaWRlUGFuZWxDbG9zZUJ1dHRvblVwZGF0ZXIiLCJfcmVmNCIsInRvZ2dsZU1hcENvbnRyb2xVcGRhdGVyIiwiX3JlZjUiLCJfc3RhdGUkbWFwQ29udHJvbHMkcGEiLCJfc3RhdGUkbWFwQ29udHJvbHMkZHIiLCJfcmVmNSRwYXlsb2FkIiwicGFuZWxJZCIsIl9yZWY1JHBheWxvYWQkaW5kZXgiLCJpbmRleCIsInVwZGF0ZWRTdGF0ZSIsInBhbmVsVG9EZWFjdGl2YXRlIiwiZWZmZWN0IiwiYWlBc3Npc3RhbnQiLCJkcm9wZG93blRvRGVhY3RpdmF0ZSIsIm1hcERyYXciLCJtYXBMb2NhbGUiLCJzZXRNYXBDb250cm9sVmlzaWJpbGl0eVVwZGF0ZXIiLCJfcmVmNiIsIl9zdGF0ZSRtYXBDb250cm9scyIsIl9yZWY2JHBheWxvYWQiLCJCb29sZWFuIiwic2V0TWFwQ29udHJvbFNldHRpbmdzVXBkYXRlciIsIl9yZWY3IiwiX3N0YXRlJG1hcENvbnRyb2xzMiIsIl9yZWY3JHBheWxvYWQiLCJzZXR0aW5ncyIsIm1hcENvbnRyb2wiLCJvcGVuRGVsZXRlTW9kYWxVcGRhdGVyIiwiX3JlZjgiLCJERUxFVEVfREFUQV9JRCIsInNldEV4cG9ydEltYWdlU2V0dGluZ1VwZGF0ZXIiLCJfcmVmOSIsIm5ld1NldHRpbmciLCJ1cGRhdGVkIiwiY2FsY3VsYXRlRXhwb3J0SW1hZ2VTaXplIiwic2V0RXhwb3J0SW1hZ2VEYXRhVXJpVXBkYXRlciIsIl9yZWYxMCIsImRhdGFVcmkiLCJzZXRFeHBvcnRJbWFnZUVycm9yVXBkYXRlciIsIl9yZWYxMSIsImNsZWFudXBFeHBvcnRJbWFnZVVwZGF0ZXIiLCJzdGFydEV4cG9ydGluZ0ltYWdlVXBkYXRlciIsIl9yZWYxMiIsIl9yZWYxMiRwYXlsb2FkIiwib3B0aW9ucyIsImltYWdlU2V0dGluZ3MiLCJjb21wb3NlXyIsImFwcGx5XyIsInBheWxvYWRfIiwic2V0RXhwb3J0U2VsZWN0ZWREYXRhc2V0VXBkYXRlciIsIl9yZWYxMyIsImRhdGFzZXQiLCJzZXRFeHBvcnREYXRhVHlwZVVwZGF0ZXIiLCJfcmVmMTQiLCJzZXRFeHBvcnRGaWx0ZXJlZFVwZGF0ZXIiLCJfcmVmMTUiLCJzZXRFeHBvcnREYXRhVXBkYXRlciIsInNldFVzZXJNYXBib3hBY2Nlc3NUb2tlblVwZGF0ZXIiLCJfcmVmMTYiLCJzZXRFeHBvcnRNYXBGb3JtYXRVcGRhdGVyIiwiX3JlZjE3IiwiZm9ybWF0Iiwic2V0RXhwb3J0TWFwSFRNTE1vZGVVcGRhdGVyIiwiX3JlZjE4IiwiYWRkTm90aWZpY2F0aW9uVXBkYXRlciIsIl9yZWYxOSIsIm9sZE5vdGlmaWNhdGlvbnMiLCJwYXlsb2FkSWQiLCJub3RpZmljYXRpb25Ub1VwZGF0ZSIsImZpbmQiLCJuIiwibWFwIiwiY3JlYXRlTm90aWZpY2F0aW9uIiwiY291bnQiLCJjb25jYXQiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwicmVtb3ZlTm90aWZpY2F0aW9uVXBkYXRlciIsIl9yZWYyMCIsImxvYWRGaWxlc1VwZGF0ZXIiLCJsb2FkRmlsZXNTdWNjZXNzVXBkYXRlciIsImxvYWRGaWxlc0VyclVwZGF0ZXIiLCJfcmVmMjEiLCJlcnJvck5vdGlmaWNhdGlvbiIsIm1lc3NhZ2UiLCJ0b3BpYyIsIkRFRkFVTFRfTk9USUZJQ0FUSU9OX1RPUElDUyIsImdsb2JhbCIsInRvZ2dsZVNwbGl0TWFwVXBkYXRlciIsImVudHJpZXMiLCJhY2MiLCJlbnRyeSIsInNob3dEYXRhc2V0VGFibGVVcGRhdGVyIiwiREFUQV9UQUJMRV9JRCIsInNldExvY2FsZVVwZGF0ZXIiLCJfcmVmMjIiLCJ0b2dnbGVQYW5lbExpc3RWaWV3VXBkYXRlciIsIl9yZWYyMyIsIl9yZWYyMyRwYXlsb2FkIiwibGlzdFZpZXciLCJzdGF0ZVByb3AiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVkdWNlcnMvc3JjL3VpLXN0YXRlLXVwZGF0ZXJzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7XG4gIEFERF9EQVRBX0lELFxuICBEQVRBX1RBQkxFX0lELFxuICBERUZBVUxUX05PVElGSUNBVElPTl9UT1BJQ1MsXG4gIERFTEVURV9EQVRBX0lELFxuICBFWFBPUlRfREFUQV9UWVBFLFxuICBFWFBPUlRfSFRNTF9NQVBfTU9ERVMsXG4gIEVYUE9SVF9JTUdfUkFUSU9TLFxuICBFWFBPUlRfTUFQX0ZPUk1BVFMsXG4gIFJFU09MVVRJT05TLFxuICBNQVBfQ09OVFJPTFNcbn0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtMT0NBTEVfQ09ERVN9IGZyb20gJ0BrZXBsZXIuZ2wvbG9jYWxpemF0aW9uJztcbmltcG9ydCB7Y3JlYXRlTm90aWZpY2F0aW9uLCBlcnJvck5vdGlmaWNhdGlvbiwgY2FsY3VsYXRlRXhwb3J0SW1hZ2VTaXplfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCB7cGF5bG9hZF8sIGFwcGx5XywgY29tcG9zZV99IGZyb20gJy4vY29tcG9zZXItaGVscGVycyc7XG5cbmltcG9ydCB7XG4gIEFjdGlvblR5cGVzLFxuICBLZXBsZXJHbEluaXRQYXlsb2FkLFxuICBMb2FkRmlsZXNFcnJVcGRhdGVyQWN0aW9uLFxuICBVSVN0YXRlQWN0aW9uc1xufSBmcm9tICdAa2VwbGVyLmdsL2FjdGlvbnMnO1xuaW1wb3J0IHtcbiAgRXhwb3J0RGF0YSxcbiAgRXhwb3J0SHRtbCxcbiAgRXhwb3J0SnNvbixcbiAgRXhwb3J0TWFwLFxuICBFeHBvcnRJbWFnZSxcbiAgTWFwQ29udHJvbEl0ZW0sXG4gIE1hcENvbnRyb2xzLFxuICBVaVN0YXRlXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9BQ1RJVkVfU0lERV9QQU5FTCA9ICdsYXllcic7XG5leHBvcnQgY29uc3QgREVGQVVMVF9NT0RBTCA9IEFERF9EQVRBX0lEO1xuXG4vKipcbiAqIFVwZGF0ZXJzIGZvciBgdWlTdGF0ZWAgcmVkdWNlci4gQ2FuIGJlIHVzZWQgaW4geW91ciByb290IHJlZHVjZXIgdG8gZGlyZWN0bHkgbW9kaWZ5IGtlcGxlci5nbCdzIHN0YXRlLlxuICogUmVhZCBtb3JlIGFib3V0IFtVc2luZyB1cGRhdGVyc10oLi4vYWR2YW5jZWQtdXNhZ2UvdXNpbmctdXBkYXRlcnMubWQpXG4gKlxuICogQHB1YmxpY1xuICogQGV4YW1wbGVcbiAqXG4gKiBpbXBvcnQga2VwbGVyR2xSZWR1Y2VyLCB7dWlTdGF0ZVVwZGF0ZXJzfSBmcm9tICdAa2VwbGVyLmdsL3JlZHVjZXJzJztcbiAqIC8vIFJvb3QgUmVkdWNlclxuICogY29uc3QgcmVkdWNlcnMgPSBjb21iaW5lUmVkdWNlcnMoe1xuICogIGtlcGxlckdsOiBrZXBsZXJHbFJlZHVjZXIsXG4gKiAgYXBwOiBhcHBSZWR1Y2VyXG4gKiB9KTtcbiAqXG4gKiBjb25zdCBjb21wb3NlZFJlZHVjZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICogIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAqICAgIC8vIGNsaWNrIGJ1dHRvbiB0byBjbG9zZSBzaWRlIHBhbmVsXG4gKiAgICBjYXNlICdDTElDS19CVVRUT04nOlxuICogICAgICByZXR1cm4ge1xuICogICAgICAgIC4uLnN0YXRlLFxuICogICAgICAgIGtlcGxlckdsOiB7XG4gKiAgICAgICAgICAuLi5zdGF0ZS5rZXBsZXJHbCxcbiAqICAgICAgICAgIGZvbzoge1xuICogICAgICAgICAgICAgLi4uc3RhdGUua2VwbGVyR2wuZm9vLFxuICogICAgICAgICAgICAgdWlTdGF0ZTogdWlTdGF0ZVVwZGF0ZXJzLnRvZ2dsZVNpZGVQYW5lbFVwZGF0ZXIoXG4gKiAgICAgICAgICAgICAgIHVpU3RhdGUsIHtwYXlsb2FkOiBudWxsfVxuICogICAgICAgICAgICAgKVxuICogICAgICAgICAgfVxuICogICAgICAgIH1cbiAqICAgICAgfTtcbiAqICB9XG4gKiAgcmV0dXJuIHJlZHVjZXJzKHN0YXRlLCBhY3Rpb24pO1xuICogfTtcbiAqXG4gKiBleHBvcnQgZGVmYXVsdCBjb21wb3NlZFJlZHVjZXI7XG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuLy8gQHRzLWlnbm9yZVxuY29uc3QgdWlTdGF0ZVVwZGF0ZXJzID0gbnVsbDtcbi8qIGVzbGludC1lbmFibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXG5cbmNvbnN0IERFRkFVTFRfTUFQX0NPTlRST0xTX0ZFQVRVUkVTOiBNYXBDb250cm9sSXRlbSA9IHtcbiAgc2hvdzogdHJ1ZSxcbiAgYWN0aXZlOiBmYWxzZSxcbiAgZGlzYWJsZUNsb3NlOiBmYWxzZSxcbiAgLy8gZGVmaW5lcyB3aGljaCBtYXAgaW5kZXggdXNlcnMgYXJlIGludGVyYWN0aW5nIHdpdGggKHRocm91Z2ggbWFwIGNvbnRyb2xzKVxuICBhY3RpdmVNYXBJbmRleDogMFxufTtcblxuY29uc3QgREVGQVVMVF9NQVBfTEVHRU5EX0NPTlRST0wgPSB7XG4gIC4uLkRFRkFVTFRfTUFQX0NPTlRST0xTX0ZFQVRVUkVTLFxuICBkaXNhYmxlRWRpdDogZmFsc2Vcbn07XG4vKipcbiAqIEEgbGlzdCBvZiBtYXAgY29udHJvbCB2aXNpYmlsaXR5IGFuZCB3aGV0aGVyIGlzIGl0IGFjdGl2ZS5cbiAqIEBtZW1iZXJvZiB1aVN0YXRlVXBkYXRlcnNcbiAqIEBjb25zdGFudFxuICogQHByb3BlcnR5IHZpc2libGVMYXllcnMgRGVmYXVsdDogYHtzaG93OiB0cnVlLCBhY3RpdmU6IGZhbHNlfWBcbiAqIEBwcm9wZXJ0eSBtYXBMZWdlbmQgRGVmYXVsdDogYHtzaG93OiB0cnVlLCBhY3RpdmU6IGZhbHNlfWBcbiAqIEBwcm9wZXJ0eSB0b2dnbGUzZCBEZWZhdWx0OiBge3Nob3c6IHRydWV9YFxuICogQHByb3BlcnR5IHNwbGl0TWFwIERlZmF1bHQ6IGB7c2hvdzogdHJ1ZX1gXG4gKiBAcHJvcGVydHkgbWFwRHJhdyBEZWZhdWx0OiBge3Nob3c6IHRydWUsIGFjdGl2ZTogZmFsc2V9YFxuICogQHByb3BlcnR5IG1hcExvY2FsZSBEZWZhdWx0OiBge3Nob3c6IGZhbHNlLCBhY3RpdmU6IGZhbHNlfWBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUFQX0NPTlRST0xTOiBNYXBDb250cm9scyA9IChcbiAgT2JqZWN0LmtleXMoTUFQX0NPTlRST0xTKSBhcyBBcnJheTxrZXlvZiB0eXBlb2YgTUFQX0NPTlRST0xTPlxuKS5yZWR1Y2UoXG4gIChmaW5hbCwgY3VycmVudCkgPT4gKHtcbiAgICAuLi5maW5hbCxcbiAgICBbY3VycmVudF06XG4gICAgICBjdXJyZW50ID09PSBNQVBfQ09OVFJPTFMubWFwTGVnZW5kXG4gICAgICAgID8gREVGQVVMVF9NQVBfTEVHRU5EX0NPTlRST0xcbiAgICAgICAgOiBERUZBVUxUX01BUF9DT05UUk9MU19GRUFUVVJFU1xuICB9KSxcbiAge30gYXMgTWFwQ29udHJvbHNcbik7XG5cbi8qKlxuICogRGVmYXVsdCBpbWFnZSBleHBvcnQgY29uZmlnXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAY29uc3RhbnRcbiAqIEBwcm9wZXJ0eSByYXRpbyBEZWZhdWx0OiBgJ1NDUkVFTidgLFxuICogQHByb3BlcnR5IHJlc29sdXRpb24gRGVmYXVsdDogYCdPTkVfWCdgLFxuICogQHByb3BlcnR5IGxlZ2VuZCBEZWZhdWx0OiBgZmFsc2VgLFxuICogQHByb3BlcnR5IG1hcEggRGVmYXVsdDogMCxcbiAqIEBwcm9wZXJ0eSBtYXBXIERlZmF1bHQ6IDAsXG4gKiBAcHJvcGVydHkgaW1hZ2VTaXplIERlZmF1bHQ6IHt6b29tT2Zmc2V0OiAwLCBzY2FsZTogMSwgaW1hZ2VXOiAwLCBpbWFnZUg6IDB9LFxuICogQHByb3BlcnR5IGltYWdlRGF0YVVyaSBEZWZhdWx0OiBgJydgLFxuICogQHByb3BlcnR5IGV4cG9ydGluZyBEZWZhdWx0OiBgZmFsc2VgXG4gKiBAcHJvcGVydHkgZXJyb3IgRGVmYXVsdDogYGZhbHNlYFxuICogQHByb3BlcnR5IGVzY2FwZVhodG1sRm9yV2VicGFjayBEZWZhdWx0OiBgdHJ1ZWBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0lNQUdFOiBFeHBvcnRJbWFnZSA9IHtcbiAgLy8gdXNlciBvcHRpb25zXG4gIHJhdGlvOiBFWFBPUlRfSU1HX1JBVElPUy5TQ1JFRU4sXG4gIHJlc29sdXRpb246IFJFU09MVVRJT05TLk9ORV9YLFxuICBsZWdlbmQ6IGZhbHNlLFxuICBtYXBIOiAwLFxuICBtYXBXOiAwLFxuICBpbWFnZVNpemU6IHtcbiAgICB6b29tT2Zmc2V0OiAwLFxuICAgIHNjYWxlOiAxLFxuICAgIGltYWdlVzogMCxcbiAgICBpbWFnZUg6IDBcbiAgfSxcbiAgLy8gd2hlbiB0aGlzIGlzIHNldCB0byB0cnVlLCB0aGUgbW9jayBtYXAgdmlld3BvcnQgd2lsbCBtb3ZlIHRvIHRoZSBjZW50ZXIgb2YgZGF0YVxuICBjZW50ZXI6IGZhbHNlLFxuICAvLyBleHBvcnRpbmcgc3RhdGVcbiAgaW1hZ2VEYXRhVXJpOiAnJyxcbiAgLy8gZXhwb3J0aW5nOiB1c2VkIHRvIGF0dGFjaCBwbG90LWNvbnRhaW5lciB0byBkb21cbiAgZXhwb3J0aW5nOiBmYWxzZSxcbiAgLy8gcHJvY2Vzc2luZzogdXNlZCBhcyBsb2FkaW5nIGluZGljYXRvciB3aGVuIGV4cG9ydCBpbWFnZSBpcyBiZWluZyBwcm9kdWNlZFxuICBwcm9jZXNzaW5nOiBmYWxzZSxcbiAgZXJyb3I6IGZhbHNlLFxuICAvLyB3aGV0aGVyIHRvIGFwcGx5IGZpeCBmb3IgdWdsaWZ5IGVycm9yIGluIGRvbS10by1pbWFnZSAoc2hvdWxkIGJlIHRydWUgZm9yIHdlYnBhY2sgYnVpbGRzKVxuICBlc2NhcGVYaHRtbEZvcldlYnBhY2s6IHRydWVcbn07XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0xPQURfRklMRVMgPSB7XG4gIGZpbGVMb2FkaW5nOiBmYWxzZVxufTtcblxuLyoqXG4gKiBEZWZhdWx0IGluaXRpYWwgYGV4cG9ydERhdGFgIHNldHRpbmdzXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAY29uc3RhbnRcbiAqIEBwcm9wZXJ0eSBzZWxlY3RlZERhdGFzZXQgRGVmYXVsdDogYCcnYCxcbiAqIEBwcm9wZXJ0eSBkYXRhVHlwZSBEZWZhdWx0OiBgJ2NzdidgLFxuICogQHByb3BlcnR5IGZpbHRlcmVkIERlZmF1bHQ6IGB0cnVlYCxcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0RBVEE6IEV4cG9ydERhdGEgPSB7XG4gIHNlbGVjdGVkRGF0YXNldDogJycsXG4gIGRhdGFUeXBlOiBFWFBPUlRfREFUQV9UWVBFLkNTVixcbiAgZmlsdGVyZWQ6IHRydWVcbn07XG5cbi8qKlxuICogQGNvbnN0YW50XG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX05PVElGSUNBVElPTlMgPSBbXTtcblxuLyoqXG4gKiBAY29uc3RhbnRcbiAqIEBwcm9wZXJ0eSBleHBvcnRNYXBib3hBY2Nlc3NUb2tlbiAtIERlZmF1bHQ6IG51bGwsIHRoaXMgaXMgdXNlZCB3aGVuIHdlIHByb3ZpZGUgYSBkZWZhdWx0IG1hcGJveCB0b2tlbiBmb3IgdXNlcnMgdG8gdGFrZSBhZHZhbnRhZ2Ugb2ZcbiAqIEBwcm9wZXJ0eSB1c2VyTWFwYm94VG9rZW4gLSBEZWZhdWx0OiAnJywgbWFwYm94IHRva2VuIHByb3ZpZGVkIGJ5IHVzZXIgdGhyb3VnaCBpbnB1dCBmaWVsZFxuICogQHByb3BlcnR5IG1vZGUgLSBEZWZhdWx0OiAnUkVBRCcsIHJlYWQgb25seSBvciBlZGl0YWJsZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9FWFBPUlRfSFRNTDogRXhwb3J0SHRtbCA9IHtcbiAgZXhwb3J0TWFwYm94QWNjZXNzVG9rZW46IG51bGwsXG4gIHVzZXJNYXBib3hUb2tlbjogJycsXG4gIG1vZGU6IEVYUE9SVF9IVE1MX01BUF9NT0RFUy5SRUFEXG59O1xuXG4vKipcbiAqIEBjb25zdGFudFxuICogQHByb3BlcnR5IGhhc0RhdGEgLSBEZWZhdWx0OiAndHJ1ZScsXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0VYUE9SVF9KU09OOiBFeHBvcnRKc29uID0ge1xuICBoYXNEYXRhOiB0cnVlXG59O1xuXG4vKipcbiAqIEV4cG9ydCBNYXAgQ29uZmlnXG4gKiBAY29uc3RhbnRcbiAqIEBwcm9wZXJ0eSBIVE1MIC0gRGVmYXVsdDogJ0RFRkFVTFRfRVhQT1JUX0hUTUwnLFxuICogQHByb3BlcnR5IEpTT04gLSBEZWZhdWx0OiAnREVGQVVMVF9FWFBPUlRfSlNPTicsXG4gKiBAcHJvcGVydHkgZm9ybWF0IC0gRGVmYXVsdDogJ0hUTUwnLFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9FWFBPUlRfTUFQOiBFeHBvcnRNYXAgPSB7XG4gIFtFWFBPUlRfTUFQX0ZPUk1BVFMuSFRNTF06IERFRkFVTFRfRVhQT1JUX0hUTUwsXG4gIFtFWFBPUlRfTUFQX0ZPUk1BVFMuSlNPTl06IERFRkFVTFRfRVhQT1JUX0pTT04sXG4gIGZvcm1hdDogRVhQT1JUX01BUF9GT1JNQVRTLkhUTUxcbn07XG5cbi8qKlxuICogRGVmYXVsdCBpbml0aWFsIGB1aVN0YXRlYFxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQGNvbnN0YW50XG4gKiBAcHJvcGVydHkgcmVhZE9ubHkgRGVmYXVsdDogYGZhbHNlYFxuICogQHByb3BlcnR5IGFjdGl2ZVNpZGVQYW5lbCBEZWZhdWx0OiBgJ2xheWVyJ2BcbiAqIEBwcm9wZXJ0eSBjdXJyZW50TW9kYWwgRGVmYXVsdDogYCdhZGREYXRhJ2BcbiAqIEBwcm9wZXJ0eSBkYXRhc2V0S2V5VG9SZW1vdmUgRGVmYXVsdDogYG51bGxgXG4gKiBAcHJvcGVydHkgdmlzaWJsZURyb3Bkb3duIERlZmF1bHQ6IGBudWxsYFxuICogQHByb3BlcnR5IGV4cG9ydEltYWdlIERlZmF1bHQ6IFtgREVGQVVMVF9FWFBPUlRfSU1BR0VgXSgjZGVmYXVsdF9leHBvcnRfaW1hZ2UpXG4gKiBAcHJvcGVydHkgZXhwb3J0RGF0YSBEZWZhdWx0OiBbYERFRkFVTFRfRVhQT1JUX0RBVEFgXSgjZGVmYXVsdF9leHBvcnRfZGF0YSlcbiAqIEBwcm9wZXJ0eSBleHBvcnRNYXAgRGVmYXVsdDogW2BERUZBVUxUX0VYUE9SVF9NQVBgXSgjZGVmYXVsdF9leHBvcnRfbWFwKVxuICogQHByb3BlcnR5IG1hcENvbnRyb2xzIERlZmF1bHQ6IFtgREVGQVVMVF9NQVBfQ09OVFJPTFNgXSgjZGVmYXVsdF9tYXBfY29udHJvbHMpXG4gKiBAcHJvcGVydHkgbm90aWZpY2F0aW9ucyBEZWZhdWx0OiBgW11gXG4gKiBAcHJvcGVydHkgbm90aWZpY2F0aW9ucyBEZWZhdWx0OiBgW11gXG4gKiBAcHJvcGVydHkgbG9hZEZpbGVzXG4gKiBAcHJvcGVydHkgaXNTaWRlUGFuZWxDbG9zZUJ1dHRvblZpc2libGUgRGVmYXVsdDogYHRydWVgXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBJTklUSUFMX1VJX1NUQVRFOiBVaVN0YXRlID0ge1xuICByZWFkT25seTogZmFsc2UsXG4gIGFjdGl2ZVNpZGVQYW5lbDogREVGQVVMVF9BQ1RJVkVfU0lERV9QQU5FTCxcbiAgY3VycmVudE1vZGFsOiBERUZBVUxUX01PREFMLFxuICBkYXRhc2V0S2V5VG9SZW1vdmU6IG51bGwsXG4gIHZpc2libGVEcm9wZG93bjogbnVsbCxcbiAgLy8gZXhwb3J0IGltYWdlIG1vZGFsIHVpXG4gIGV4cG9ydEltYWdlOiBERUZBVUxUX0VYUE9SVF9JTUFHRSxcbiAgLy8gZXhwb3J0IGRhdGEgbW9kYWwgdWlcbiAgZXhwb3J0RGF0YTogREVGQVVMVF9FWFBPUlRfREFUQSxcbiAgLy8gaHRtbCBleHBvcnRcbiAgZXhwb3J0TWFwOiBERUZBVUxUX0VYUE9SVF9NQVAsXG4gIC8vIG1hcCBjb250cm9sIHBhbmVsc1xuICBtYXBDb250cm9sczogREVGQVVMVF9NQVBfQ09OVFJPTFMsXG4gIC8vIHVpIG5vdGlmaWNhdGlvbnNcbiAgbm90aWZpY2F0aW9uczogREVGQVVMVF9OT1RJRklDQVRJT05TLFxuICAvLyBsb2FkIGZpbGVzXG4gIGxvYWRGaWxlczogREVGQVVMVF9MT0FEX0ZJTEVTLFxuICAvLyBMb2NhbGUgb2YgdGhlIFVJXG4gIGxvY2FsZTogTE9DQUxFX0NPREVTLmVuLFxuICBsYXllclBhbmVsTGlzdFZpZXc6ICdsaXN0JyxcbiAgZmlsdGVyUGFuZWxMaXN0VmlldzogJ2xpc3QnLFxuICBpc1NpZGVQYW5lbENsb3NlQnV0dG9uVmlzaWJsZTogdHJ1ZVxufTtcblxuLyogVXBkYXRlcnMgKi9cbi8qKlxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICovXG5leHBvcnQgY29uc3QgaW5pdFVpU3RhdGVVcGRhdGVyID0gKFxuICBzdGF0ZTogVWlTdGF0ZSxcbiAgYWN0aW9uOiB7XG4gICAgdHlwZT86ICh0eXBlb2YgQWN0aW9uVHlwZXMpWydJTklUJ107XG4gICAgcGF5bG9hZDogS2VwbGVyR2xJbml0UGF5bG9hZDtcbiAgfVxuKTogVWlTdGF0ZSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgLi4uKGFjdGlvbi5wYXlsb2FkIHx8IHt9KS5pbml0aWFsVWlTdGF0ZVxufSk7XG5cbi8qKlxuICogVG9nZ2xlIGFjdGl2ZSBzaWRlIHBhbmVsXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0gc3RhdGUgYHVpU3RhdGVgXG4gKiBAcGFyYW0gYWN0aW9uXG4gKiBAcGFyYW0gYWN0aW9uLnBheWxvYWQgaWQgb2Ygc2lkZSBwYW5lbCB0byBiZSBzaG93biwgb25lIG9mIGBsYXllcmAsIGBmaWx0ZXJgLCBgaW50ZXJhY3Rpb25gLCBgbWFwYC4gY2xvc2Ugc2lkZSBwYW5lbCBpZiBgbnVsbGBcbiAqIEByZXR1cm5zIG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlU2lkZVBhbmVsVXBkYXRlciA9IChcbiAgc3RhdGU6IFVpU3RhdGUsXG4gIHtwYXlsb2FkOiBpZH06IFVJU3RhdGVBY3Rpb25zLlRvZ2dsZVNpZGVQYW5lbFVwZGF0ZXJBY3Rpb25cbik6IFVpU3RhdGUgPT4ge1xuICByZXR1cm4gaWQgPT09IHN0YXRlLmFjdGl2ZVNpZGVQYW5lbFxuICAgID8gc3RhdGVcbiAgICA6IHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGFjdGl2ZVNpZGVQYW5lbDogaWRcbiAgICAgIH07XG59O1xuXG4vKipcbiAqIFNob3cgYW5kIGhpZGUgbW9kYWwgZGlhbG9nXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAcGFyYW0gc3RhdGUgYHVpU3RhdGVgXG4gKiBAcGFyYW0gYWN0aW9uXG4gKiBAcGFyYW1hY3Rpb24ucGF5bG9hZCBpZCBvZiBtb2RhbCB0byBiZSBzaG93biwgbnVsbCB0byBoaWRlIG1vZGFscy4gT25lIG9mOlxuICogIC0gW2BEQVRBX1RBQkxFX0lEYF0oLi4vY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MubWQjZGF0YV90YWJsZV9pZClcbiAqICAtIFtgREVMRVRFX0RBVEFfSURgXSguLi9jb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncy5tZCNkZWxldGVfZGF0YV9pZClcbiAqICAtIFtgQUREX0RBVEFfSURgXSguLi9jb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncy5tZCNhZGRfZGF0YV9pZClcbiAqICAtIFtgRVhQT1JUX0lNQUdFX0lEYF0oLi4vY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MubWQjZXhwb3J0X2ltYWdlX2lkKVxuICogIC0gW2BFWFBPUlRfREFUQV9JRGBdKC4uL2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzLm1kI2V4cG9ydF9kYXRhX2lkKVxuICogIC0gW2BBRERfTUFQX1NUWUxFX0lEYF0oLi4vY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MubWQjYWRkX21hcF9zdHlsZV9pZClcbiAqIEByZXR1cm5zIG5leHRTdGF0ZVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlTW9kYWxVcGRhdGVyID0gKFxuICBzdGF0ZTogVWlTdGF0ZSxcbiAge3BheWxvYWQ6IGlkfTogVUlTdGF0ZUFjdGlvbnMuVG9nZ2xlTW9kYWxVcGRhdGVyQWN0aW9uXG4pOiBVaVN0YXRlID0+ICh7XG4gIC4uLnN0YXRlLFxuICBjdXJyZW50TW9kYWw6IGlkXG59KTtcblxuLyoqXG4gKiBIaWRlIGFuZCBzaG93IHNpZGUgcGFuZWwgaGVhZGVyIGRyb3Bkb3duLCBhY3RpdmF0ZWQgYnkgY2xpY2tpbmcgdGhlIHNoYXJlIGxpbmsgb24gdG9wIG9mIHRoZSBzaWRlIHBhbmVsXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBzaG93RXhwb3J0RHJvcGRvd25VcGRhdGVyID0gKFxuICBzdGF0ZTogVWlTdGF0ZSxcbiAge3BheWxvYWQ6IGlkfTogVUlTdGF0ZUFjdGlvbnMuU2hvd0V4cG9ydERyb3Bkb3duVXBkYXRlckFjdGlvblxuKTogVWlTdGF0ZSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgdmlzaWJsZURyb3Bkb3duOiBpZFxufSk7XG5cbi8qKlxuICogSGlkZSBzaWRlIHBhbmVsIGhlYWRlciBkcm9wZG93biwgYWN0aXZhdGVkIGJ5IGNsaWNraW5nIHRoZSBzaGFyZSBsaW5rIG9uIHRvcCBvZiB0aGUgc2lkZSBwYW5lbFxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgaGlkZUV4cG9ydERyb3Bkb3duVXBkYXRlciA9IChzdGF0ZTogVWlTdGF0ZSk6IFVpU3RhdGUgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIHZpc2libGVEcm9wZG93bjogbnVsbFxufSk7XG5cbi8qKlxuICogVG9nZ2xlIHNpZGUgcGFuZWwgY2xvc2UgYnV0dG9uIG9uIHRvcCBsZWZ0IG9mIHRoZSBzaWRlIHBhbmVsXG4gKiBAbWVtYmVyb2YgdWlTdGF0ZVVwZGF0ZXJzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCB0b2dnbGVTaWRlUGFuZWxDbG9zZUJ1dHRvblVwZGF0ZXIgPSAoXG4gIHN0YXRlOiBVaVN0YXRlLFxuICB7cGF5bG9hZDoge3Nob3d9fTogVUlTdGF0ZUFjdGlvbnMuVG9nZ2xlU2lkZVBhbmVsQ2xvc2VCdXR0b25VcGRhdGVyQWN0aW9uXG4pOiBVaVN0YXRlID0+ICh7XG4gIC4uLnN0YXRlLFxuICBpc1NpZGVQYW5lbENsb3NlQnV0dG9uVmlzaWJsZTogc2hvd1xufSk7XG5cbi8qKlxuICogVG9nZ2xlIGFjdGl2ZSBtYXAgY29udHJvbCBwYW5lbFxuICogQG1lbWJlcm9mIHVpU3RhdGVVcGRhdGVyc1xuICogQHBhcmFtIHN0YXRlIGB1aVN0YXRlYFxuICogQHBhcmFtIGFjdGlvbiBhY3Rpb25cbiAqIEBwYXJhbSBhY3Rpb24ucGF5bG9hZCBtYXAgY29udHJvbCBwYW5lbCBpZCwgb25lIG9mIHRoZSBrZXlzIG9mOiBbYERFRkFVTFRfTUFQX0NPTlRST0xTYF0oI2RlZmF1bHRfbWFwX2NvbnRyb2xzKVxuICogQHJldHVybnMgbmV4dFN0YXRlXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCB0b2dnbGVNYXBDb250cm9sVXBkYXRlciA9IChcbiAgc3RhdGU6IFVpU3RhdGUsXG4gIHtwYXlsb2FkOiB7cGFuZWxJZCwgaW5kZXggPSAwfX06IFVJU3RhdGVBY3Rpb25zLlRvZ2dsZU1hcENvbnRyb2xVcGRhdGVyQWN0aW9uXG4pOiBVaVN0YXRlID0+IHtcbiAgbGV0IHVwZGF0ZWRTdGF0ZSA9IHN0YXRlO1xuICAvLyBUaGUgZWZmZWN0IHBhbmVsIGFuZCBhaSBhc3Npc3RhbnQgcGFuZWwgY2FuIG5vdCBiZSBhY3RpdmUgYXQgdGhlIHNhbWUgdGltZVxuICAvLyBzbyB3ZSBuZWVkIHRvIGRlYWN0aXZhdGUgdGhlIG90aGVyIHBhbmVsIHdoZW4gb25lIGlzIGFjdGl2YXRlZFxuICBjb25zdCBwYW5lbFRvRGVhY3RpdmF0ZSA9XG4gICAgcGFuZWxJZCA9PT0gTUFQX0NPTlRST0xTLmVmZmVjdFxuICAgICAgPyBNQVBfQ09OVFJPTFMuYWlBc3Npc3RhbnRcbiAgICAgIDogcGFuZWxJZCA9PT0gTUFQX0NPTlRST0xTLmFpQXNzaXN0YW50XG4gICAgICA/IE1BUF9DT05UUk9MUy5lZmZlY3RcbiAgICAgIDogbnVsbDtcblxuICAvLyBUbyB0byB0b2dnbGUgdGhlIG1hcERyYXcgYW5kIG1hcExvY2FsIGRyb3Bkb3duc1xuICAvLyBXZSBoYXZlIHRvIGRlYWN0aXZhdGUgdGhlIG90aGVyIGFjdGl2ZSBkcm9wZG93blxuICBjb25zdCBkcm9wZG93blRvRGVhY3RpdmF0ZSA9XG4gICAgcGFuZWxJZCA9PT0gTUFQX0NPTlRST0xTLm1hcERyYXdcbiAgICAgID8gTUFQX0NPTlRST0xTLm1hcExvY2FsZVxuICAgICAgOiBwYW5lbElkID09PSBNQVBfQ09OVFJPTFMubWFwTG9jYWxlXG4gICAgICA/IE1BUF9DT05UUk9MUy5tYXBEcmF3XG4gICAgICA6IG51bGw7XG5cbiAgLy8gSWYgd2UgbmVlZCB0byBkZWFjdGl2YXRlIGEgY29tcGV0aW5nIHBhbmVsIGFuZCBpdCdzIGN1cnJlbnRseSBhY3RpdmVcbiAgaWYgKHBhbmVsVG9EZWFjdGl2YXRlICYmIHN0YXRlLm1hcENvbnRyb2xzW3BhbmVsVG9EZWFjdGl2YXRlXT8uYWN0aXZlKSB7XG4gICAgdXBkYXRlZFN0YXRlID0g