UNPKG

kepler.gl.geoiq

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

915 lines 70.2 kB
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.addFilter = addFilter;
exports.addLayer = addLayer;
exports.addWidget = addWidget;
exports.applyCPUFilter = applyCPUFilter;
exports.axiosAPICAll = axiosAPICAll;
exports.deleteFeature = deleteFeature;
exports.enlargeFilter = enlargeFilter;
exports.interactionConfigChange = interactionConfigChange;
exports.layerColorUIChange = layerColorUIChange;
exports.layerConfigChange = layerConfigChange;
exports.layerTextLabelChange = layerTextLabelChange;
exports.layerTypeChange = layerTypeChange;
exports.layerVisConfigChange = layerVisConfigChange;
exports.layerVisualChannelConfigChange = layerVisualChannelConfigChange;
exports.loadEDLinkData = loadEDLinkData;
exports.loadFiles = loadFiles;
exports.loadFilesErr = loadFilesErr;
exports.loadURL = loadURL;
exports.onLayerClick = onLayerClick;
exports.onLayerHover = onLayerHover;
exports.onMapClick = onMapClick;
exports.onMouseMove = onMouseMove;
exports.removeDataset = removeDataset;
exports.removeFilter = removeFilter;
exports.removeLayer = removeLayer;
exports.removeWidget = removeWidget;
exports.reorderLayer = reorderLayer;
exports.reorderWidget = reorderWidget;
exports.setEditorMode = setEditorMode;
exports.setFeatures = setFeatures;
exports.setFilter = setFilter;
exports.setFilterAPI = setFilterAPI;
exports.setFilterPlot = setFilterPlot;
exports.setPolygonFilterLayer = setPolygonFilterLayer;
exports.setSelectedFeature = setSelectedFeature;
exports.showDatasetTable = showDatasetTable;
exports.toggleEditorVisibility = toggleEditorVisibility;
exports.toggleFilterAnimation = toggleFilterAnimation;
exports.toggleLayerForMap = toggleLayerForMap;
exports.updateAnimationTime = updateAnimationTime;
exports.updateDataset = updateDataset;
exports.updateFilterAnimationSpeed = updateFilterAnimationSpeed;
exports.updateLayerAnimationSpeed = updateLayerAnimationSpeed;
exports.updateLayerBlending = updateLayerBlending;
exports.updateLayerData = updateLayerData;
exports.updateVisData = updateVisData;
exports.widgetConfigChange = widgetConfigChange;
exports.widgetTypeChange = widgetTypeChange;
exports.widgetVisConfigChange = widgetVisConfigChange;
exports.widgetVisualChannelConfigChange = widgetVisualChannelConfigChange;

var _actionTypes = _interopRequireDefault(require("../constants/action-types"));

// 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.
// vis-state-reducer

/**
 * Update layer base config: dataId, label, column, isVisible
 * @memberof visStateActions
 * @param {Object} oldLayer - layer to be updated
 * @param {Object} newConfig - new config
 * @returns {{type: ActionTypes.LAYER_CONFIG_CHANGE, oldLayer: oldLayer, newConfig: newConfig}}
 * @public
 */
function layerConfigChange(oldLayer, newConfig) {
  // console.log(
  //   'layerConfigChange',
  //   'oldLayer',
  //   oldLayer,
  //   'newConfig',
  //   newConfig
  // );
  return {
    type: _actionTypes["default"].LAYER_CONFIG_CHANGE,
    oldLayer: oldLayer,
    newConfig: newConfig
  };
}

function updateLayerData(layer, collected) {
  return {
    type: _actionTypes["default"].UPDATE_STATE_LAYER_DATA,
    layer: layer,
    collected: collected
  };
}

function axiosAPICAll(layer) {
  return {
    type: _actionTypes["default"].ASYNC_API_CALL,
    layer: layer
  };
}
/**
 * Update layer text label
 * @memberof visStateActions
 * @param {Object} oldLayer - layer to be updated
 * @param {Number} idx -`idx` of text label to be updated
 * @param {string} prop - `prop` of text label, e,g, `anchor`, `alignment`, `color`, `size`, `field`
 * @param {*} value - new value
 * @returns {{type: ActionTypes.LAYER_TEXT_LABEL_CHANGE, oldLayer: oldLayer, idx: idx, prop: prop, value:}}
 * @public
 */


function layerTextLabelChange(oldLayer, idx, prop, value) {
  return {
    type: _actionTypes["default"].LAYER_TEXT_LABEL_CHANGE,
    oldLayer: oldLayer,
    idx: idx,
    prop: prop,
    value: value
  };
}
/**
 * Update layer type. Previews layer config will be copied if applicable.
 * @memberof visStateActions
 * @param {Object} oldLayer - layer to be updated
 * @param {string} newType - new type
 * @returns {{type: ActionTypes.LAYER_TYPE_CHANGE, oldLayer: oldLayer, newType: newType}}
 * @public
 */


function layerTypeChange(oldLayer, newType) {
  // console.log('layerTypeChange', 'oldLayer', oldLayer, 'newType', newType);
  return {
    type: _actionTypes["default"].LAYER_TYPE_CHANGE,
    oldLayer: oldLayer,
    newType: newType
  };
}
/**
 * Update layer visual channel
 * @memberof visStateActions
 * @param {Object} oldLayer - layer to be updated
 * @param {Object} newConfig - new visual channel config
 * @param {string} channel - channel to be updated
 * @returns {{type: ActionTypes.LAYER_VISUAL_CHANNEL_CHANGE, oldLayer: oldLayer, newConfig: newConfig, channel: channel}}
 * @public
 */


function layerVisualChannelConfigChange(oldLayer, newConfig, channel) {
  // console.log(
  //   'layerVisualChannelConfigChange',
  //   'oldLayer',
  //   oldLayer,
  //   'newConfig',
  //   newConfig,
  //   channel
  // );
  return {
    type: _actionTypes["default"].LAYER_VISUAL_CHANNEL_CHANGE,
    oldLayer: oldLayer,
    newConfig: newConfig,
    channel: channel
  };
}
/**
 * Update layer `visConfig`
 * @memberof visStateActions
 * @param {Object} oldLayer - layer to be updated
 * @param {Object} newVisConfig - new visConfig as a key value map: e.g. `{opacity: 0.8}`
 * @returns {{type: ActionTypes.LAYER_VIS_CONFIG_CHANGE, oldLayer: oldLayer, newVisConfig: newVisConfig}}
 * @public
 */


function layerVisConfigChange(oldLayer, newVisConfig) {
  // console.log(
  //   'layerVisConfigChange',
  //   'oldLayer',
  //   oldLayer,
  //   'newVisConfig',
  //   newVisConfig
  // );
  return {
    type: _actionTypes["default"].LAYER_VIS_CONFIG_CHANGE,
    oldLayer: oldLayer,
    newVisConfig: newVisConfig
  };
}

function widgetConfigChange(oldWidget, newConfig, auth, project) {
  return {
    type: _actionTypes["default"].WIDGET_CONFIG_CHANGE,
    oldWidget: oldWidget,
    newConfig: newConfig,
    auth: auth,
    project: project
  };
}

function widgetTypeChange(oldWidget, newType) {
  // console.log('widgetTypeChange', 'oldWidget', oldWidget, 'newType', newType);
  return {
    type: _actionTypes["default"].WIDGET_TYPE_CHANGE,
    oldWidget: oldWidget,
    newType: newType
  };
}

function widgetVisualChannelConfigChange(oldWidget, newConfig, channel) {
  // console.log(
  //   'widgetVisualChannelConfigChange',
  //   'oldWidget',
  //   oldWidget,
  //   'newConfig',
  //   newConfig,
  //   'channel',
  //   channel
  // );
  return {
    type: _actionTypes["default"].WIDGET_VISUAL_CHANNEL_CHANGE,
    oldWidget: oldWidget,
    newConfig: newConfig,
    channel: channel
  };
}

function widgetVisConfigChange(oldWidget, newVisConfig) {
  // console.log(
  //   'widgetVisConfigChange',
  //   'oldWidget',
  //   oldWidget,
  //   'newVisConfig',
  //   newVisConfig
  // );
  return {
    type: _actionTypes["default"].WIDGET_VIS_CONFIG_CHANGE,
    oldWidget: oldWidget,
    newVisConfig: newVisConfig
  };
}
/**
 * Set the color palette ui for layer color
 * @memberOf visStateActions
 * @param {Object} oldLayer - layer to be updated
 * @param {String} prop - which color prop
 * @param {object} newConfig - to be merged
 * @public
 */


function layerColorUIChange(oldLayer, prop, newConfig) {
  return {
    type: _actionTypes["default"].LAYER_COLOR_UI_CHANGE,
    oldLayer: oldLayer,
    prop: prop,
    newConfig: newConfig
  };
}
/**
 * Update layer blending mode
 * @memberof visStateActions
 * @param {string} mode one of `additive`, `normal` and `subtractive`
 * @returns {{type: ActionTypes.UPDATE_LAYER_BLENDING, mode: mode}}
 * @public
 */


function updateLayerBlending(mode) {
  // console.log('updateLayerBlending', 'mode', mode);
  return {
    type: _actionTypes["default"].UPDATE_LAYER_BLENDING,
    mode: mode
  };
}
/**
 * Update `interactionConfig`
 * @memberof visStateActions
 * @param {Object} config - new config as key value map: `{tooltip: {enabled: true}}`
 * @returns {{type: ActionTypes.INTERACTION_CONFIG_CHANGE, config: config}}
 * @public
 */


function interactionConfigChange(config) {
  // console.log('interactionConfigChange', 'config', config);
  return {
    type: _actionTypes["default"].INTERACTION_CONFIG_CHANGE,
    config: config
  };
}
/**
 * Update filter property
 * @memberof visStateActions
 * @param {Number} idx -`idx` of filter to be updated
 * @param {string} prop - `prop` of filter, e,g, `dataId`, `name`, `value`
 * @param {*} value - new value
 * @param {Number} valueIndex - array properties like dataset require index in order to improve performance
 * @returns {{type: ActionTypes.SET_FILTER, idx: idx, prop: prop, value: value}}
 * @public
 */


function setFilter(idx, prop, value, valueIndex, mapState, auth, project) {
  return {
    type: _actionTypes["default"].SET_FILTER,
    idx: idx,
    prop: prop,
    value: value,
    valueIndex: valueIndex,
    mapState: mapState,
    auth: auth,
    project: project
  };
}
/**
 * update filter property
 * @memberof visStateActions
 * @param {Number} idx - `idx` of filter to be updated
 * @param {string} prop - `prop` of filter, e,g, `dataId`, `name`, `value`
 * @param {*} value - new value
 * @param {string} dataId - `dataId` of filter with which the filter is associated
 * @param {string} range - `range` of filter
 * @param {object} histogram - `histogram` of filter
 * @returns {{type: ActionTypes.SET_FILTER_API, idx:idx, dataId:dataId,range:range, histogram:histogram }}
 */


function setFilterAPI(idx, prop, value, valueIndex, dataId, domain, histogram) {
  return {
    type: _actionTypes["default"].SET_FILTER_API,
    idx: idx,
    prop: prop,
    value: value,
    valueIndex: valueIndex,
    dataId: dataId,
    domain: domain,
    histogram: histogram
  };
}
/**
 * Add a new filter
 * @memberof visStateActions
 * @param {string} dataId - dataset `id` this new filter is associated with
 * @returns {{type: ActionTypes.ADD_FILTER, dataId: dataId}}
 * @public
 */


function addFilter(dataId) {
  // console.log('addFilter', 'dataID', dataId);
  return {
    type: _actionTypes["default"].ADD_FILTER,
    dataId: dataId
  };
}
/**
 * Add a new layer
 * @memberof visStateActions
 * @param {Object} props - new layer props
 * @returns {{type: ActionTypes.ADD_LAYER, props: props}}
 * @public
 */


function addLayer(props) {
  // console.log('addLayer', 'props', props);
  return {
    type: _actionTypes["default"].ADD_LAYER,
    props: props
  };
}

function addWidget(props) {
  // console.log('addWidget', 'props', props);
  return {
    type: _actionTypes["default"].ADD_WIDGET,
    props: props
  };
}

function reorderWidget(order) {
  // console.log('reorderWidget', 'order', order);
  return {
    type: _actionTypes["default"].REORDER_WIDGET,
    order: order
  };
}
/**
 * Reorder layer, order is an array of layer indexes, index 0 will be the one at the bottom
 * @memberof visStateActions
 * @param {Array<Number>} order an array of layer indexes
 * @returns {{type: ActionTypes.REORDER_LAYER, order: order}}
 * @public
 * @example
 *
 * // bring `layers[1]` below `layers[0]`, the sequence layers will be rendered is `1`, `0`, `2`, `3`.
 * // `1` will be at the bottom, `3` will be at the top.
 * this.props.dispatch(reorderLayer([1, 0, 2, 3]));
 */


function reorderLayer(order) {
  // console.log('reorderLayer', 'order', order);
  return {
    type: _actionTypes["default"].REORDER_LAYER,
    order: order
  };
}
/**
 * Remove a filter from `visState.filters`, once a filter is removed, data will be re-filtered and layer will be updated
 * @memberof visStateActions
 * @param {Number} idx idx of filter to be removed
 * @returns {{type: ActionTypes.REMOVE_FILTER, idx: idx}}
 * @public
 */


function removeFilter(idx, mapState, auth, project) {
  // console.log('removeFilter', 'idx', idx);
  return {
    type: _actionTypes["default"].REMOVE_FILTER,
    idx: idx,
    mapState: mapState,
    auth: auth,
    project: project
  };
}
/**
 * Remove a layer
 * @memberof visStateActions
 * @param {Number} idx idx of layer to be removed
 * @returns {{type: ActionTypes.REMOVE_LAYER, idx: idx}}
 * @public
 */


function removeLayer(idx) {
  // console.log('removeLayer', 'idx', idx);
  return {
    type: _actionTypes["default"].REMOVE_LAYER,
    idx: idx
  };
}

function removeWidget(idx) {
  // console.log('removeWidget', 'idx', idx);
  return {
    type: _actionTypes["default"].REMOVE_WIDGET,
    idx: idx
  };
}
/**
 * Remove a dataset and all layers, filters, tooltip configs that based on it
 * @memberof visStateActions
 * @param {string} key dataset id
 * @returns {{type: ActionTypes.REMOVE_DATASET, key: key}}
 * @public
 */


function removeDataset(key) {
  // console.log('removeDataset', 'key', key);
  return {
    type: _actionTypes["default"].REMOVE_DATASET,
    key: key
  };
}
/**
 * Display dataset table in a modal
 * @memberof visStateActions
 * @param {string} dataId dataset id to show in table
 * @returns {{type: ActionTypes.SHOW_DATASET_TABLE, dataId: dataId}}
 * @public
 */


function showDatasetTable(dataId) {
  // console.log('showDatasetTable', 'dataId', dataId);
  return {
    type: _actionTypes["default"].SHOW_DATASET_TABLE,
    dataId: dataId
  };
}
/**
 * Add new dataset to `visState`, with option to load a map config along with the datasets
 * @memberof visStateActions
 * @param {Array<Object>|Object} datasets - ***required** datasets can be a dataset or an array of datasets
 * Each dataset object needs to have `info` and `data` property.
 * @param {Object} datasets.info -info of a dataset
 * @param {string} datasets.info.id - id of this dataset. If config is defined, `id` should matches the `dataId` in config.
 * @param {string} datasets.info.label - A display name of this dataset
 * @param {Object} datasets.data - ***required** The data object, in a tabular format with 2 properties `fields` and `rows`
 * @param {Array<Object>} datasets.data.fields - ***required** Array of fields,
 * @param {string} datasets.data.fields.name - ***required** Name of the field,
 * @param {Array<Array>} datasets.data.rows - ***required** Array of rows, in a tabular format with `fields` and `rows`

 * @param {Object} options
 * @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 {Object} config this object will contain the full kepler.gl instance configuration {mapState, mapStyle, visState}
 * @returns {{type: ActionTypes.UPDATE_VIS_DATA, datasets: datasets, options: options, config: config}}
 * @public
 */


function updateVisData(datasets, options, config) {
  // console.log(
  //   'updateVisData',
  //   'datasets',
  //   datasets,
  //   'options',
  //   options,
  //   'config',
  //   config
  // );
  return {
    type: _actionTypes["default"].UPDATE_VIS_DATA,
    datasets: datasets,
    options: options,
    config: config
  };
}
/**
 * Start and end filter animation
 * @memberof visStateActions
 * @param {Number} idx - idx of filter
 * @returns {{type: ActionTypes.TOGGLE_FILTER_ANIMATION, idx: idx}}
 * @public
 */


function toggleFilterAnimation(idx) {
  return {
    type: _actionTypes["default"].TOGGLE_FILTER_ANIMATION,
    idx: idx
  };
}
/**
 * Change filter animation speed
 * @memberof visStateActions
 * @param {Number} idx -  `idx` of filter
 * @param {Number} speed - `speed` to change it to. `speed` is a multiplier
 * @returns {{type: ActionTypes.UPDATE_FILTER_ANIMATION_SPEED, idx: idx, speed: speed}}
 * @public
 */


function updateFilterAnimationSpeed(idx, speed) {
  return {
    type: _actionTypes["default"].UPDATE_FILTER_ANIMATION_SPEED,
    idx: idx,
    speed: speed
  };
}
/**
 * Reset animation
 * @memberof visStateActions
 * @param {Number} value -  Current value of the slider
 * @returns {{type: ActionTypes.RESET_ANIMATION, value: value}}
 * @public
 */


function updateAnimationTime(value) {
  return {
    type: _actionTypes["default"].UPDATE_ANIMATION_TIME,
    value: value
  };
}
/**
 * update trip layer animation speed
 * @memberof visStateActions
 * @param {Number} speed - `speed` to change it to. `speed` is a multiplier
 * @returns {{type: ActionTypes.UPDATE_LAYER_ANIMATION_SPEED, speed: speed}}
 * @public
 */


function updateLayerAnimationSpeed(speed) {
  return {
    type: _actionTypes["default"].UPDATE_LAYER_ANIMATION_SPEED,
    speed: speed
  };
}
/**
 * Show larger time filter at bottom for time playback (apply to time filter only)
 * @memberof visStateActions
 * @param {Number} idx - index of filter to enlarge
 * @returns {{type: ActionTypes.ENLARGE_FILTER, idx: idx}}
 * @public
 */


function enlargeFilter(idx) {
  // console.log('enlargeFilter', 'idx', idx);
  return {
    type: _actionTypes["default"].ENLARGE_FILTER,
    idx: idx
  };
}
/**
 * Trigger layer hover event with hovered object
 * @memberof visStateActions
 * @param {Object} info - Object hovered, returned by deck.gl
 * @returns {{type: ActionTypes.LAYER_HOVER, info: info}}
 * @public
 */


function onLayerHover(info) {
  // console.log('onLayerHover', info);
  return {
    type: _actionTypes["default"].LAYER_HOVER,
    info: info
  };
}
/**
 * Trigger layer click event with clicked object
 * @memberof visStateActions
 * @param {Object} info - Object clicked, returned by deck.gl
 * @returns {{type: ActionTypes.LAYER_CLICK, info: info}}
 * @public
 */


function onLayerClick(info) {
  // console.log('onLayerClick', info);
  return {
    type: _actionTypes["default"].LAYER_CLICK,
    info: info
  };
}
/**
 * Trigger map click event, unselect clicked object
 * @memberof visStateActions
 * @returns {{type: ActionTypes.MAP_CLICK}}
 * @public
 */


function onMapClick() {
  // console.log('onMapClick');
  return {
    type: _actionTypes["default"].MAP_CLICK
  };
}
/**
 * Trigger map mouse moveevent, payload would be
 * React-map-gl PointerEvent
 * https://uber.github.io/react-map-gl/#/documentation/api-reference/pointer-event
 *
 * @memberof visStateActions
 * @param {Object} evt - PointerEvent
 * @returns {{type: ActionTypes.MAP_CLICK}}
 * @public
 */


function onMouseMove(evt) {
  return {
    type: _actionTypes["default"].MOUSE_MOVE,
    evt: evt
  };
}
/**
 * Toggle visibility of a layer in a split map
 * @memberof visStateActions
 * @param {Number} mapIndex - index of the split map
 * @param {string} layerId - id of the layer
 * @returns {{type: ActionTypes.TOGGLE_LAYER_FOR_MAP, mapIndex: *, layerId: *}}
 * @public
 */


function toggleLayerForMap(mapIndex, layerId) {
  return {
    type: _actionTypes["default"].TOGGLE_LAYER_FOR_MAP,
    mapIndex: mapIndex,
    layerId: layerId
  };
}
/**
 * Set the property of a filter plot
 * @memberof visStateActions
 * @param {Number} idx
 * @param {Object} newProp key value mapping of new prop `{yAxis: 'histogram'}`
 * @returns {{type: ActionTypes.SET_FILTER_PLOT, idx: *, newProp: *}}
 * @public
 */


function setFilterPlot(idx, newProp) {
  // console.log('setFilterPlot', idx, newProp);
  return {
    type: _actionTypes["default"].SET_FILTER_PLOT,
    idx: idx,
    newProp: newProp
  };
}
/**
 * Trigger file loading dispatch `addDataToMap` if succeed, or `loadFilesErr` if failed
 * @memberof visStateActions
 * @param {Array<Object>} files array of fileblob
 * @returns {{type: ActionTypes.LOAD_FILES, files: *}}
 * @public
 */


function loadFiles(files) {
  // console.log('loadFiles', files);
  return {
    type: _actionTypes["default"].LOAD_FILES,
    files: files
  };
}
/**
 * Trigger loading file error
 * @memberof visStateActions
 * @param {*} error
 * @returns {{type: ActionTypes.LOAD_FILES_ERR, error: Object}}
 * @public
 */


function loadFilesErr(error) {
  // console.log('loadFilesErr', error);
  return {
    type: _actionTypes["default"].LOAD_FILES_ERR,
    error: error
  };
}
/**
 * Store features to state
 * @memberof visStateActions
 * @param {Array<Object>} features
 * @returns {{type: ActionTypes.SET_FEATURES, features: Object}}
 */


function setFeatures(features, auth, project, mapState) {
  return {
    type: _actionTypes["default"].SET_FEATURES,
    features: features,
    auth: auth,
    project: project,
    mapState: mapState
  };
}
/**
 * It will apply the provide feature as filter to the given layer.
 * If the given feature is already applied as filter to the layer, it will remove the layer from the filter
 * @memberof visStateActions
 * @param {Object} layer
 * @param {Object} feature
 * @return {{feature: *, type: ActionTypes.SET_POLYGON_FILTER_LAYER, layer: *}}
 */


function setPolygonFilterLayer(layer, feature, auth, project, mapState) {
  return {
    type: _actionTypes["default"].SET_POLYGON_FILTER_LAYER,
    layer: layer,
    feature: feature,
    auth: auth,
    project: project,
    mapState: mapState
  };
}
/**
 * Set the current feature to be edited/deleted
 * @memberof visStateActions
 * @param {Object} feature
 * @param {string} feature.selectedFeatureId
 * @return {{selectedFeatureId: *, type: ActionTypes.SET_SELECTED_FEATURE}}
 */


function setSelectedFeature(feature) {
  return {
    type: _actionTypes["default"].SET_SELECTED_FEATURE,
    feature: feature
  };
}
/**
 * Delete the given feature
 * @memberof visStateActions
 * @param {string} featureId if of the feature
 * @return {{type: ActionTypes.DELETE_FEATURE, featureId: *}}
 */


function deleteFeature(feature) {
  return {
    type: _actionTypes["default"].DELETE_FEATURE,
    feature: feature
  };
}
/** Set the map mode
 * @memberof visStateActions
 * @param {string} mode one of EDITOR_MODES
 * @return {{type: ActionTypes. SET_EDITOR_MODE, mode: *}}
 * @public
 * @example
 * import {setMapMode} from 'kepler.gl/actions';
 * import {EDITOR_MODES} from 'kepler.gl/constants';
 *
 * this.props.dispatch(setMapMode(EDITOR_MODES.DRAW_POLYGON));
 */


function setEditorMode(mode) {
  return {
    type: _actionTypes["default"].SET_EDITOR_MODE,
    mode: mode
  };
}
/**
 * Trigger CPU filter of selected dataset
 * @memberof visStateActions
 * @param {string | Arrary<string>} dataId - single dataId or an array of dataIds
 * @returns {{type: ActionTypes.APPLY_CPU_FILTER, dataId: string}}
 * @public
 */


function applyCPUFilter(dataId) {
  return {
    type: _actionTypes["default"].APPLY_CPU_FILTER,
    dataId: dataId
  };
}
/**
 * Toggle editor layer visibility
 * @memberof visStateActions
 * @return {{type: ActionTypes.TOGGLE_EDITOR_VISIBILITY}}
 */


function toggleEditorVisibility() {
  return {
    type: _actionTypes["default"].TOGGLE_EDITOR_VISIBILITY
  };
}
/**
 * This declaration is needed to group actions in docs
 */

/**
 * Actions handled mostly by `visState` reducer.
 * They manage how data is processed, filtered and displayed on the map by operates on layers,
 * filters and interaction settings.
 *
 * @public
 */

/* eslint-disable no-unused-vars */


var visStateActions = null;
/* eslint-enable no-unused-vars */

function loadURL(URL, range) {
  return {
    type: _actionTypes["default"].LOAD_URL,
    URL: URL,
    range: range
  };
}

function loadEDLinkData(data, dataId) {
  return {
    type: _actionTypes["default"].LOAD_ED_LINK,
    data: data,
    dataId: dataId
  };
}
/**
 * Update dataset info
 * @memberof visStateActions
 * @param {Object} dataId
 * @param {string} updatedAt
 * @return {{type:ActionTypes.UPDATE_DATASET_INFO,dataId:Object, updatedAt:*}}
 */


function updateDataset(dataId, updatedAt) {
  return {
    type: _actionTypes["default"].UPDATE_DATASET_INFO,
    dataId: dataId,
    updatedAt: updatedAt
  };
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hY3Rpb25zL3Zpcy1zdGF0ZS1hY3Rpb25zLmpzIl0sIm5hbWVzIjpbImxheWVyQ29uZmlnQ2hhbmdlIiwib2xkTGF5ZXIiLCJuZXdDb25maWciLCJ0eXBlIiwiQWN0aW9uVHlwZXMiLCJMQVlFUl9DT05GSUdfQ0hBTkdFIiwidXBkYXRlTGF5ZXJEYXRhIiwibGF5ZXIiLCJjb2xsZWN0ZWQiLCJVUERBVEVfU1RBVEVfTEFZRVJfREFUQSIsImF4aW9zQVBJQ0FsbCIsIkFTWU5DX0FQSV9DQUxMIiwibGF5ZXJUZXh0TGFiZWxDaGFuZ2UiLCJpZHgiLCJwcm9wIiwidmFsdWUiLCJMQVlFUl9URVhUX0xBQkVMX0NIQU5HRSIsImxheWVyVHlwZUNoYW5nZSIsIm5ld1R5cGUiLCJMQVlFUl9UWVBFX0NIQU5HRSIsImxheWVyVmlzdWFsQ2hhbm5lbENvbmZpZ0NoYW5nZSIsImNoYW5uZWwiLCJMQVlFUl9WSVNVQUxfQ0hBTk5FTF9DSEFOR0UiLCJsYXllclZpc0NvbmZpZ0NoYW5nZSIsIm5ld1Zpc0NvbmZpZyIsIkxBWUVSX1ZJU19DT05GSUdfQ0hBTkdFIiwid2lkZ2V0Q29uZmlnQ2hhbmdlIiwib2xkV2lkZ2V0IiwiYXV0aCIsInByb2plY3QiLCJXSURHRVRfQ09ORklHX0NIQU5HRSIsIndpZGdldFR5cGVDaGFuZ2UiLCJXSURHRVRfVFlQRV9DSEFOR0UiLCJ3aWRnZXRWaXN1YWxDaGFubmVsQ29uZmlnQ2hhbmdlIiwiV0lER0VUX1ZJU1VBTF9DSEFOTkVMX0NIQU5HRSIsIndpZGdldFZpc0NvbmZpZ0NoYW5nZSIsIldJREdFVF9WSVNfQ09ORklHX0NIQU5HRSIsImxheWVyQ29sb3JVSUNoYW5nZSIsIkxBWUVSX0NPTE9SX1VJX0NIQU5HRSIsInVwZGF0ZUxheWVyQmxlbmRpbmciLCJtb2RlIiwiVVBEQVRFX0xBWUVSX0JMRU5ESU5HIiwiaW50ZXJhY3Rpb25Db25maWdDaGFuZ2UiLCJjb25maWciLCJJTlRFUkFDVElPTl9DT05GSUdfQ0hBTkdFIiwic2V0RmlsdGVyIiwidmFsdWVJbmRleCIsIm1hcFN0YXRlIiwiU0VUX0ZJTFRFUiIsInNldEZpbHRlckFQSSIsImRhdGFJZCIsImRvbWFpbiIsImhpc3RvZ3JhbSIsIlNFVF9GSUxURVJfQVBJIiwiYWRkRmlsdGVyIiwiQUREX0ZJTFRFUiIsImFkZExheWVyIiwicHJvcHMiLCJBRERfTEFZRVIiLCJhZGRXaWRnZXQiLCJBRERfV0lER0VUIiwicmVvcmRlcldpZGdldCIsIm9yZGVyIiwiUkVPUkRFUl9XSURHRVQiLCJyZW9yZGVyTGF5ZXIiLCJSRU9SREVSX0xBWUVSIiwicmVtb3ZlRmlsdGVyIiwiUkVNT1ZFX0ZJTFRFUiIsInJlbW92ZUxheWVyIiwiUkVNT1ZFX0xBWUVSIiwicmVtb3ZlV2lkZ2V0IiwiUkVNT1ZFX1dJREdFVCIsInJlbW92ZURhdGFzZXQiLCJrZXkiLCJSRU1PVkVfREFUQVNFVCIsInNob3dEYXRhc2V0VGFibGUiLCJTSE9XX0RBVEFTRVRfVEFCTEUiLCJ1cGRhdGVWaXNEYXRhIiwiZGF0YXNldHMiLCJvcHRpb25zIiwiVVBEQVRFX1ZJU19EQVRBIiwidG9nZ2xlRmlsdGVyQW5pbWF0aW9uIiwiVE9HR0xFX0ZJTFRFUl9BTklNQVRJT04iLCJ1cGRhdGVGaWx0ZXJBbmltYXRpb25TcGVlZCIsInNwZWVkIiwiVVBEQVRFX0ZJTFRFUl9BTklNQVRJT05fU1BFRUQiLCJ1cGRhdGVBbmltYXRpb25UaW1lIiwiVVBEQVRFX0FOSU1BVElPTl9USU1FIiwidXBkYXRlTGF5ZXJBbmltYXRpb25TcGVlZCIsIlVQREFURV9MQVlFUl9BTklNQVRJT05fU1BFRUQiLCJlbmxhcmdlRmlsdGVyIiwiRU5MQVJHRV9GSUxURVIiLCJvbkxheWVySG92ZXIiLCJpbmZvIiwiTEFZRVJfSE9WRVIiLCJvbkxheWVyQ2xpY2siLCJMQVlFUl9DTElDSyIsIm9uTWFwQ2xpY2siLCJNQVBfQ0xJQ0siLCJvbk1vdXNlTW92ZSIsImV2dCIsIk1PVVNFX01PVkUiLCJ0b2dnbGVMYXllckZvck1hcCIsIm1hcEluZGV4IiwibGF5ZXJJZCIsIlRPR0dMRV9MQVlFUl9GT1JfTUFQIiwic2V0RmlsdGVyUGxvdCIsIm5ld1Byb3AiLCJTRVRfRklMVEVSX1BMT1QiLCJsb2FkRmlsZXMiLCJmaWxlcyIsIkxPQURfRklMRVMiLCJsb2FkRmlsZXNFcnIiLCJlcnJvciIsIkxPQURfRklMRVNfRVJSIiwic2V0RmVhdHVyZXMiLCJmZWF0dXJlcyIsIlNFVF9GRUFUVVJFUyIsInNldFBvbHlnb25GaWx0ZXJMYXllciIsImZlYXR1cmUiLCJTRVRfUE9MWUdPTl9GSUxURVJfTEFZRVIiLCJzZXRTZWxlY3RlZEZlYXR1cmUiLCJTRVRfU0VMRUNURURfRkVBVFVSRSIsImRlbGV0ZUZlYXR1cmUiLCJERUxFVEVfRkVBVFVSRSIsInNldEVkaXRvck1vZGUiLCJTRVRfRURJVE9SX01PREUiLCJhcHBseUNQVUZpbHRlciIsIkFQUExZX0NQVV9GSUxURVIiLCJ0b2dnbGVFZGl0b3JWaXNpYmlsaXR5IiwiVE9HR0xFX0VESVRPUl9WSVNJQklMSVRZIiwidmlzU3RhdGVBY3Rpb25zIiwibG9hZFVSTCIsIlVSTCIsInJhbmdlIiwiTE9BRF9VUkwiLCJsb2FkRURMaW5rRGF0YSIsImRhdGEiLCJMT0FEX0VEX0xJTksiLCJ1cGRhdGVEYXRhc2V0IiwidXBkYXRlZEF0IiwiVVBEQVRFX0RBVEFTRVRfSU5GTyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFCQTs7QUFyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFHQTs7Ozs7Ozs7QUFRTyxTQUFTQSxpQkFBVCxDQUEyQkMsUUFBM0IsRUFBcUNDLFNBQXJDLEVBQWdEO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBTztBQUNMQyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZQyxtQkFEYjtBQUVMSixJQUFBQSxRQUFRLEVBQVJBLFFBRks7QUFHTEMsSUFBQUEsU0FBUyxFQUFUQTtBQUhLLEdBQVA7QUFLRDs7QUFFTSxTQUFTSSxlQUFULENBQXlCQyxLQUF6QixFQUFnQ0MsU0FBaEMsRUFBMkM7QUFDaEQsU0FBTztBQUNMTCxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZSyx1QkFEYjtBQUVMRixJQUFBQSxLQUFLLEVBQUxBLEtBRks7QUFHTEMsSUFBQUEsU0FBUyxFQUFUQTtBQUhLLEdBQVA7QUFLRDs7QUFDTSxTQUFTRSxZQUFULENBQXNCSCxLQUF0QixFQUE2QjtBQUNsQyxTQUFPO0FBQUNKLElBQUFBLElBQUksRUFBRUMsd0JBQVlPLGNBQW5CO0FBQW1DSixJQUFBQSxLQUFLLEVBQUxBO0FBQW5DLEdBQVA7QUFDRDtBQUNEOzs7Ozs7Ozs7Ozs7QUFVTyxTQUFTSyxvQkFBVCxDQUE4QlgsUUFBOUIsRUFBd0NZLEdBQXhDLEVBQTZDQyxJQUE3QyxFQUFtREMsS0FBbkQsRUFBMEQ7QUFDL0QsU0FBTztBQUNMWixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZWSx1QkFEYjtBQUVMZixJQUFBQSxRQUFRLEVBQVJBLFFBRks7QUFHTFksSUFBQUEsR0FBRyxFQUFIQSxHQUhLO0FBSUxDLElBQUFBLElBQUksRUFBSkEsSUFKSztBQUtMQyxJQUFBQSxLQUFLLEVBQUxBO0FBTEssR0FBUDtBQU9EO0FBRUQ7Ozs7Ozs7Ozs7QUFRTyxTQUFTRSxlQUFULENBQXlCaEIsUUFBekIsRUFBbUNpQixPQUFuQyxFQUE0QztBQUNqRDtBQUNBLFNBQU87QUFDTGYsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWWUsaUJBRGI7QUFFTGxCLElBQUFBLFFBQVEsRUFBUkEsUUFGSztBQUdMaUIsSUFBQUEsT0FBTyxFQUFQQTtBQUhLLEdBQVA7QUFLRDtBQUVEOzs7Ozs7Ozs7OztBQVNPLFNBQVNFLDhCQUFULENBQXdDbkIsUUFBeEMsRUFBa0RDLFNBQWxELEVBQTZEbUIsT0FBN0QsRUFBc0U7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQU87QUFDTGxCLElBQUFBLElBQUksRUFBRUMsd0JBQVlrQiwyQkFEYjtBQUVMckIsSUFBQUEsUUFBUSxFQUFSQSxRQUZLO0FBR0xDLElBQUFBLFNBQVMsRUFBVEEsU0FISztBQUlMbUIsSUFBQUEsT0FBTyxFQUFQQTtBQUpLLEdBQVA7QUFNRDtBQUVEOzs7Ozs7Ozs7O0FBUU8sU0FBU0Usb0JBQVQsQ0FBOEJ0QixRQUE5QixFQUF3Q3VCLFlBQXhDLEVBQXNEO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBTztBQUNMckIsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWXFCLHVCQURiO0FBRUx4QixJQUFBQSxRQUFRLEVBQVJBLFFBRks7QUFHTHVCLElBQUFBLFlBQVksRUFBWkE7QUFISyxHQUFQO0FBS0Q7O0FBRU0sU0FBU0Usa0JBQVQsQ0FBNEJDLFNBQTVCLEVBQXVDekIsU0FBdkMsRUFBa0QwQixJQUFsRCxFQUF3REMsT0FBeEQsRUFBaUU7QUFDdEUsU0FBTztBQUNMMUIsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWTBCLG9CQURiO0FBRUxILElBQUFBLFNBQVMsRUFBVEEsU0FGSztBQUdMekIsSUFBQUEsU0FBUyxFQUFUQSxTQUhLO0FBSUwwQixJQUFBQSxJQUFJLEVBQUpBLElBSks7QUFLTEMsSUFBQUEsT0FBTyxFQUFQQTtBQUxLLEdBQVA7QUFPRDs7QUFFTSxTQUFTRSxnQkFBVCxDQUEwQkosU0FBMUIsRUFBcUNULE9BQXJDLEVBQThDO0FBQ25EO0FBQ0EsU0FBTztBQUNMZixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZNEIsa0JBRGI7QUFFTEwsSUFBQUEsU0FBUyxFQUFUQSxTQUZLO0FBR0xULElBQUFBLE9BQU8sRUFBUEE7QUFISyxHQUFQO0FBS0Q7O0FBRU0sU0FBU2UsK0JBQVQsQ0FBeUNOLFNBQXpDLEVBQW9EekIsU0FBcEQsRUFBK0RtQixPQUEvRCxFQUF3RTtBQUM3RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFPO0FBQ0xsQixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZOEIsNEJBRGI7QUFFTFAsSUFBQUEsU0FBUyxFQUFUQSxTQUZLO0FBR0x6QixJQUFBQSxTQUFTLEVBQVRBLFNBSEs7QUFJTG1CLElBQUFBLE9BQU8sRUFBUEE7QUFKSyxHQUFQO0FBTUQ7O0FBRU0sU0FBU2MscUJBQVQsQ0FBK0JSLFNBQS9CLEVBQTBDSCxZQUExQyxFQUF3RDtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQU87QUFDTHJCLElBQUFBLElBQUksRUFBRUMsd0JBQVlnQyx3QkFEYjtBQUVMVCxJQUFBQSxTQUFTLEVBQVRBLFNBRks7QUFHTEgsSUFBQUEsWUFBWSxFQUFaQTtBQUhLLEdBQVA7QUFLRDtBQUVEOzs7Ozs7Ozs7O0FBUU8sU0FBU2Esa0JBQVQsQ0FBNEJwQyxRQUE1QixFQUFzQ2EsSUFBdEMsRUFBNENaLFNBQTVDLEVBQXVEO0FBQzVELFNBQU87QUFDTEMsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWWtDLHFCQURiO0FBRUxyQyxJQUFBQSxRQUFRLEVBQVJBLFFBRks7QUFHTGEsSUFBQUEsSUFBSSxFQUFKQSxJQUhLO0FBSUxaLElBQUFBLFNBQVMsRUFBVEE7QUFKSyxHQUFQO0FBTUQ7QUFFRDs7Ozs7Ozs7O0FBT08sU0FBU3FDLG1CQUFULENBQTZCQyxJQUE3QixFQUFtQztBQUN4QztBQUNBLFNBQU87QUFDTHJDLElBQUFBLElBQUksRUFBRUMsd0JBQVlxQyxxQkFEYjtBQUVMRCxJQUFBQSxJQUFJLEVBQUpBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNFLHVCQUFULENBQWlDQyxNQUFqQyxFQUF5QztBQUM5QztBQUNBLFNBQU87QUFDTHhDLElBQUFBLElBQUksRUFBRUMsd0JBQVl3Qyx5QkFEYjtBQUVMRCxJQUFBQSxNQUFNLEVBQU5BO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7Ozs7OztBQVVPLFNBQVNFLFNBQVQsQ0FDTGhDLEdBREssRUFFTEMsSUFGSyxFQUdMQyxLQUhLLEVBSUwrQixVQUpLLEVBS0xDLFFBTEssRUFNTG5CLElBTkssRUFPTEMsT0FQSyxFQVFMO0FBQ0EsU0FBTztBQUNMMUIsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWTRDLFVBRGI7QUFFTG5DLElBQUFBLEdBQUcsRUFBSEEsR0FGSztBQUdMQyxJQUFBQSxJQUFJLEVBQUpBLElBSEs7QUFJTEMsSUFBQUEsS0FBSyxFQUFMQSxLQUpLO0FBS0wrQixJQUFBQSxVQUFVLEVBQVZBLFVBTEs7QUFNTEMsSUFBQUEsUUFBUSxFQUFSQSxRQU5LO0FBT0xuQixJQUFBQSxJQUFJLEVBQUpBLElBUEs7QUFRTEMsSUFBQUEsT0FBTyxFQUFQQTtBQVJLLEdBQVA7QUFVRDtBQUVEOzs7Ozs7Ozs7Ozs7O0FBV08sU0FBU29CLFlBQVQsQ0FDTHBDLEdBREssRUFFTEMsSUFGSyxFQUdMQyxLQUhLLEVBSUwrQixVQUpLLEVBS0xJLE1BTEssRUFNTEMsTUFOSyxFQU9MQyxTQVBLLEVBUUw7QUFDQSxTQUFPO0FBQ0xqRCxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZaUQsY0FEYjtBQUVMeEMsSUFBQUEsR0FBRyxFQUFIQSxHQUZLO0FBR0xDLElBQUFBLElBQUksRUFBSkEsSUFISztBQUlMQyxJQUFBQSxLQUFLLEVBQUxBLEtBSks7QUFLTCtCLElBQUFBLFVBQVUsRUFBVkEsVUFMSztBQU1MSSxJQUFBQSxNQUFNLEVBQU5BLE1BTks7QUFPTEMsSUFBQUEsTUFBTSxFQUFOQSxNQVBLO0FBUUxDLElBQUFBLFNBQVMsRUFBVEE7QUFSSyxHQUFQO0FBVUQ7QUFDRDs7Ozs7Ozs7O0FBT08sU0FBU0UsU0FBVCxDQUFtQkosTUFBbkIsRUFBMkI7QUFDaEM7QUFDQSxTQUFPO0FBQ0wvQyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZbUQsVUFEYjtBQUVMTCxJQUFBQSxNQUFNLEVBQU5BO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNNLFFBQVQsQ0FBa0JDLEtBQWxCLEVBQXlCO0FBQzlCO0FBQ0EsU0FBTztBQUNMdEQsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWXNELFNBRGI7QUFFTEQsSUFBQUEsS0FBSyxFQUFMQTtBQUZLLEdBQVA7QUFJRDs7QUFFTSxTQUFTRSxTQUFULENBQW1CRixLQUFuQixFQUEwQjtBQUMvQjtBQUNBLFNBQU87QUFDTHRELElBQUFBLElBQUksRUFBRUMsd0JBQVl3RCxVQURiO0FBRUxILElBQUFBLEtBQUssRUFBTEE7QUFGSyxHQUFQO0FBSUQ7O0FBRU0sU0FBU0ksYUFBVCxDQUF1QkMsS0FBdkIsRUFBOEI7QUFDbkM7QUFDQSxTQUFPO0FBQ0wzRCxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZMkQsY0FEYjtBQUVMRCxJQUFBQSxLQUFLLEVBQUxBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0FBWU8sU0FBU0UsWUFBVCxDQUFzQkYsS0FBdEIsRUFBNkI7QUFDbEM7QUFDQSxTQUFPO0FBQ0wzRCxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZNkQsYUFEYjtBQUVMSCxJQUFBQSxLQUFLLEVBQUxBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNJLFlBQVQsQ0FBc0JyRCxHQUF0QixFQUEyQmtDLFFBQTNCLEVBQXFDbkIsSUFBckMsRUFBMkNDLE9BQTNDLEVBQW9EO0FBQ3pEO0FBQ0EsU0FBTztBQUNMMUIsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWStELGFBRGI7QUFFTHRELElBQUFBLEdBQUcsRUFBSEEsR0FGSztBQUdMa0MsSUFBQUEsUUFBUSxFQUFSQSxRQUhLO0FBSUxuQixJQUFBQSxJQUFJLEVBQUpBLElBSks7QUFLTEMsSUFBQUEsT0FBTyxFQUFQQTtBQUxLLEdBQVA7QUFPRDtBQUVEOzs7Ozs7Ozs7QUFPTyxTQUFTdUMsV0FBVCxDQUFxQnZELEdBQXJCLEVBQTBCO0FBQy9CO0FBQ0EsU0FBTztBQUNMVixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZaUUsWUFEYjtBQUVMeEQsSUFBQUEsR0FBRyxFQUFIQTtBQUZLLEdBQVA7QUFJRDs7QUFFTSxTQUFTeUQsWUFBVCxDQUFzQnpELEdBQXRCLEVBQTJCO0FBQ2hDO0FBQ0EsU0FBTztBQUNMVixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZbUUsYUFEYjtBQUVMMUQsSUFBQUEsR0FBRyxFQUFIQTtBQUZLLEdBQVA7QUFJRDtBQUVEOzs7Ozs7Ozs7QUFPTyxTQUFTMkQsYUFBVCxDQUF1QkMsR0FBdkIsRUFBNEI7QUFDakM7QUFDQSxTQUFPO0FBQ0x0RSxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZc0UsY0FEYjtBQUVMRCxJQUFBQSxHQUFHLEVBQUhBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNFLGdCQUFULENBQTBCekIsTUFBMUIsRUFBa0M7QUFDdkM7QUFDQSxTQUFPO0FBQ0wvQyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZd0Usa0JBRGI7QUFFTDFCLElBQUFBLE1BQU0sRUFBTkE7QUFGSyxHQUFQO0FBSUQ7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBc0JPLFNBQVMyQixhQUFULENBQXVCQyxRQUF2QixFQUFpQ0MsT0FBakMsRUFBMENwQyxNQUExQyxFQUFrRDtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFPO0FBQ0x4QyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZNEUsZUFEYjtBQUVMRixJQUFBQSxRQUFRLEVBQVJBLFFBRks7QUFHTEMsSUFBQUEsT0FBTyxFQUFQQSxPQUhLO0FBSUxwQyxJQUFBQSxNQUFNLEVBQU5BO0FBSkssR0FBUDtBQU1EO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNzQyxxQkFBVCxDQUErQnBFLEdBQS9CLEVBQW9DO0FBQ3pDLFNBQU87QUFDTFYsSUFBQUEsSUFBSSxFQUFFQyx3QkFBWThFLHVCQURiO0FBRUxyRSxJQUFBQSxHQUFHLEVBQUhBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7Ozs7QUFRTyxTQUFTc0UsMEJBQVQsQ0FBb0N0RSxHQUFwQyxFQUF5Q3VFLEtBQXpDLEVBQWdEO0FBQ3JELFNBQU87QUFDTGpGLElBQUFBLElBQUksRUFBRUMsd0JBQVlpRiw2QkFEYjtBQUVMeEUsSUFBQUEsR0FBRyxFQUFIQSxHQUZLO0FBR0x1RSxJQUFBQSxLQUFLLEVBQUxBO0FBSEssR0FBUDtBQUtEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNFLG1CQUFULENBQTZCdkUsS0FBN0IsRUFBb0M7QUFDekMsU0FBTztBQUNMWixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZbUYscUJBRGI7QUFFTHhFLElBQUFBLEtBQUssRUFBTEE7QUFGSyxHQUFQO0FBSUQ7QUFFRDs7Ozs7Ozs7O0FBT08sU0FBU3lFLHlCQUFULENBQW1DSixLQUFuQyxFQUEwQztBQUMvQyxTQUFPO0FBQ0xqRixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZcUYsNEJBRGI7QUFFTEwsSUFBQUEsS0FBSyxFQUFMQTtBQUZLLEdBQVA7QUFJRDtBQUVEOzs7Ozs7Ozs7QUFPTyxTQUFTTSxhQUFULENBQXVCN0UsR0FBdkIsRUFBNEI7QUFDakM7QUFDQSxTQUFPO0FBQ0xWLElBQUFBLElBQUksRUFBRUMsd0JBQVl1RixjQURiO0FBRUw5RSxJQUFBQSxHQUFHLEVBQUhBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVMrRSxZQUFULENBQXNCQyxJQUF0QixFQUE0QjtBQUNqQztBQUNBLFNBQU87QUFDTDFGLElBQUFBLElBQUksRUFBRUMsd0JBQVkwRixXQURiO0FBRUxELElBQUFBLElBQUksRUFBSkE7QUFGSyxHQUFQO0FBSUQ7QUFFRDs7Ozs7Ozs7O0FBT08sU0FBU0UsWUFBVCxDQUFzQkYsSUFBdEIsRUFBNEI7QUFDakM7QUFDQSxTQUFPO0FBQ0wxRixJQUFBQSxJQUFJLEVBQUVDLHdCQUFZNEYsV0FEYjtBQUVMSCxJQUFBQSxJQUFJLEVBQUpBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7O0FBTU8sU0FBU0ksVUFBVCxHQUFzQjtBQUMzQjtBQUNBLFNBQU87QUFDTDlGLElBQUFBLElBQUksRUFBRUMsd0JBQVk4RjtBQURiLEdBQVA7QUFHRDtBQUVEOzs7Ozs7Ozs7Ozs7QUFVTyxTQUFTQyxXQUFULENBQXFCQyxHQUFyQixFQUEwQjtBQUMvQixTQUFPO0FBQ0xqRyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZaUcsVUFEYjtBQUVMRCxJQUFBQSxHQUFHLEVBQUhBO0FBRkssR0FBUDtBQUlEO0FBRUQ7Ozs7Ozs7Ozs7QUFRTyxTQUFTRSxpQkFBVCxDQUEyQkMsUUFBM0IsRUFBcUNDLE9BQXJDLEVBQThDO0FBQ25ELFNBQU87QUFDTHJHLElBQUFBLElBQUksRUFBRUMsd0JBQVlxRyxvQkFEYjtBQUVMRixJQUFBQSxRQUFRLEVBQVJBLFFBRks7QUFHTEMsSUFBQUEsT0FBTyxFQUFQQTtBQUhLLEdBQVA7QUFLRDtBQUVEOzs7Ozs7Ozs7O0FBUU8sU0FBU0UsYUFBVCxDQUF1QjdGLEdBQXZCLEVBQTRCOEYsT0FBNUIsRUFBcUM7QUFDMUM7QUFDQSxTQUFPO0FBQ0x4RyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZd0csZUFEYjtBQUVML0YsSUFBQUEsR0FBRyxFQUFIQSxHQUZLO0FBR0w4RixJQUFBQSxPQUFPLEVBQVBBO0FBSEssR0FBUDtBQUtEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNFLFNBQVQsQ0FBbUJDLEtBQW5CLEVBQTBCO0FBQy9CO0FBQ0EsU0FBTztBQUNMM0csSUFBQUEsSUFBSSxFQUFFQyx3QkFBWTJHLFVBRGI7QUFFTEQsSUFBQUEsS0FBSyxFQUFMQTtBQUZLLEdBQVA7QUFJRDtBQUVEOzs7Ozs7Ozs7QUFPTyxTQUFTRSxZQUFULENBQXNCQyxLQUF0QixFQUE2QjtBQUNsQztBQUNBLFNBQU87QUFDTDlHLElBQUFBLElBQUksRUFBRUMsd0JBQVk4RyxjQURiO0FBRUxELElBQUFBLEtBQUssRUFBTEE7QUFGSyxHQUFQO0FBSUQ7QUFFRDs7Ozs7Ozs7QUFNTyxTQUFTRSxXQUFULENBQXFCQyxRQUFyQixFQUErQnhGLElBQS9CLEVBQXFDQyxPQUFyQyxFQUE4Q2tCLFFBQTlDLEVBQXdEO0FBQzdELFNBQU87QUFDTDVDLElBQUFBLElBQUksRUFBRUMsd0JBQVlpSCxZQURiO0FBRUxELElBQUFBLFFBQVEsRUFBUkEsUUFGSztBQUdMeEYsSUFBQUEsSUFBSSxFQUFKQSxJQUhLO0FBSUxDLElBQUFBLE9BQU8sRUFBUEEsT0FKSztBQUtMa0IsSUFBQUEsUUFBUSxFQUFSQTtBQUxLLEdBQVA7QUFPRDtBQUVEOzs7Ozs7Ozs7O0FBUU8sU0FBU3VFLHFCQUFULENBQStCL0csS0FBL0IsRUFBc0NnSCxPQUF0QyxFQUErQzNGLElBQS9DLEVBQXFEQyxPQUFyRCxFQUE4RGtCLFFBQTlELEVBQXdFO0FBQzdFLFNBQU87QUFDTDVDLElBQUFBLElBQUksRUFBRUMsd0JBQVlvSCx3QkFEYjtBQUVMakgsSUFBQUEsS0FBSyxFQUFMQSxLQUZLO0FBR0xnSCxJQUFBQSxPQUFPLEVBQVBBLE9BSEs7QUFJTDNGLElBQUFBLElBQUksRUFBSkEsSUFKSztBQUtMQyxJQUFBQSxPQUFPLEVBQVBBLE9BTEs7QUFNTGtCLElBQUFBLFFBQVEsRUFBUkE7QUFOSyxHQUFQO0FBUUQ7QUFFRDs7Ozs7Ozs7O0FBT08sU0FBUzBFLGtCQUFULENBQTRCRixPQUE1QixFQUFxQztBQUMxQyxTQUFPO0FBQ0xwSCxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZc0gsb0JBRGI7QUFFTEgsSUFBQUEsT0FBTyxFQUFQQTtBQUZLLEdBQVA7QUFJRDtBQUVEOzs7Ozs7OztBQU1PLFNBQVNJLGFBQVQsQ0FBdUJKLE9BQXZCLEVBQWdDO0FBQ3JDLFNBQU87QUFDTHBILElBQUFBLElBQUksRUFBRUMsd0JBQVl3SCxjQURiO0FBRUxMLElBQUFBLE9BQU8sRUFBUEE7QUFGSyxHQUFQO0FBSUQ7QUFFRDs7Ozs7Ozs7Ozs7OztBQVdPLFNBQVNNLGFBQVQsQ0FBdUJyRixJQUF2QixFQUE2QjtBQUNsQyxTQUFPO0FBQ0xyQyxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZMEgsZUFEYjtBQUVMdEYsSUFBQUEsSUFBSSxFQUFKQTtBQUZLLEdBQVA7QUFJRDtBQUVEOzs7Ozs7Ozs7QUFPTyxTQUFTdUYsY0FBVCxDQUF3QjdFLE1BQXhCLEVBQWdDO0FBQ3JDLFNBQU87QUFDTC9DLElBQUFBLElBQUksRUFBRUMsd0JBQVk0SCxnQkFEYjtBQUVMOUUsSUFBQUEsTUFBTSxFQUFOQTtBQUZLLEdBQVA7QUFJRDtBQUVEOzs7Ozs7O0FBS08sU0FBUytFLHNCQUFULEdBQWtDO0FBQ3ZDLFNBQU87QUFDTDlILElBQUFBLElBQUksRUFBRUMsd0JBQVk4SDtBQURiLEdBQVA7QUFHRDtBQUVEOzs7O0FBR0E7Ozs7Ozs7O0FBT0E7OztBQUNBLElBQU1DLGVBQWUsR0FBRyxJQUF4QjtBQUNBOztBQUVPLFNBQVNDLE9BQVQsQ0FBaUJDLEdBQWpCLEVBQXNCQyxLQUF0QixFQUE2QjtBQUNsQyxTQUFPO0FBQ0xuSSxJQUFBQSxJQUFJLEVBQUVDLHdCQUFZbUksUUFEYjtBQUVMRixJQUFBQSxHQUFHLEVBQUhBLEdBRks7QUFHTEMsSUFBQUEsS0FBSyxFQUFMQTtBQUhLLEdBQVA7QUFLRDs7QUFFTSxTQUFTRSxjQUFULENBQXdCQyxJQUF4QixFQUE4QnZGLE1BQTlCLEVBQXNDO0FBQzNDLFNBQU87QUFDTC9DLElBQUFBLElBQUksRUFBRUMsd0JBQVlzSSxZQURiO0FBRUxELElBQUFBLElBQUksRUFBSkEsSUFGSztBQUdMdkYsSUFBQUEsTUFBTSxFQUFOQTtBQUhLLEdBQVA7QUFLRDtBQUVEOzs7Ozs7Ozs7QUFRTyxTQUFTeUYsYUFBVCxDQUF1QnpGLE1BQXZCLEVBQStCMEYsU0FBL0IsRUFBMEM7QUFDL0MsU0FBTztBQUNMekksSUFBQUEsSUFBSSxFQUFFQyx3QkFBWXlJLG1CQURiO0FBRUwzRixJQUFBQSxNQUFNLEVBQU5BLE1BRks7QUFHTDBGLElBQUFBLFNBQVMsRUFBVEE7QUFISyxHQUFQO0FBS0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjMgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG4vLyB2aXMtc3RhdGUtcmVkdWNlclxuaW1wb3J0IEFjdGlvblR5cGVzIGZyb20gJ2NvbnN0YW50cy9hY3Rpb24tdHlwZXMnO1xuXG4vKipcbiAqIFVwZGF0ZSBsYXllciBiYXNlIGNvbmZpZzogZGF0YUlkLCBsYWJlbCwgY29sdW1uLCBpc1Zpc2libGVcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBuZXdDb25maWcgLSBuZXcgY29uZmlnXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLkxBWUVSX0NPTkZJR19DSEFOR0UsIG9sZExheWVyOiBvbGRMYXllciwgbmV3Q29uZmlnOiBuZXdDb25maWd9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJDb25maWdDaGFuZ2Uob2xkTGF5ZXIsIG5ld0NvbmZpZykge1xuICAvLyBjb25zb2xlLmxvZyhcbiAgLy8gICAnbGF5ZXJDb25maWdDaGFuZ2UnLFxuICAvLyAgICdvbGRMYXllcicsXG4gIC8vICAgb2xkTGF5ZXIsXG4gIC8vICAgJ25ld0NvbmZpZycsXG4gIC8vICAgbmV3Q29uZmlnXG4gIC8vICk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfQ09ORklHX0NIQU5HRSxcbiAgICBvbGRMYXllcixcbiAgICBuZXdDb25maWdcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUxheWVyRGF0YShsYXllciwgY29sbGVjdGVkKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuVVBEQVRFX1NUQVRFX0xBWUVSX0RBVEEsXG4gICAgbGF5ZXIsXG4gICAgY29sbGVjdGVkXG4gIH07XG59XG5leHBvcnQgZnVuY3Rpb24gYXhpb3NBUElDQWxsKGxheWVyKSB7XG4gIHJldHVybiB7dHlwZTogQWN0aW9uVHlwZXMuQVNZTkNfQVBJX0NBTEwsIGxheWVyfTtcbn1cbi8qKlxuICogVXBkYXRlIGxheWVyIHRleHQgbGFiZWxcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHggLWBpZHhgIG9mIHRleHQgbGFiZWwgdG8gYmUgdXBkYXRlZFxuICogQHBhcmFtIHtzdHJpbmd9IHByb3AgLSBgcHJvcGAgb2YgdGV4dCBsYWJlbCwgZSxnLCBgYW5jaG9yYCwgYGFsaWdubWVudGAsIGBjb2xvcmAsIGBzaXplYCwgYGZpZWxkYFxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIG5ldyB2YWx1ZVxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9URVhUX0xBQkVMX0NIQU5HRSwgb2xkTGF5ZXI6IG9sZExheWVyLCBpZHg6IGlkeCwgcHJvcDogcHJvcCwgdmFsdWU6fX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxheWVyVGV4dExhYmVsQ2hhbmdlKG9sZExheWVyLCBpZHgsIHByb3AsIHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfVEVYVF9MQUJFTF9DSEFOR0UsXG4gICAgb2xkTGF5ZXIsXG4gICAgaWR4LFxuICAgIHByb3AsXG4gICAgdmFsdWVcbiAgfTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgdHlwZS4gUHJldmlld3MgbGF5ZXIgY29uZmlnIHdpbGwgYmUgY29waWVkIGlmIGFwcGxpY2FibGUuXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge09iamVjdH0gb2xkTGF5ZXIgLSBsYXllciB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0ge3N0cmluZ30gbmV3VHlwZSAtIG5ldyB0eXBlXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLkxBWUVSX1RZUEVfQ0hBTkdFLCBvbGRMYXllcjogb2xkTGF5ZXIsIG5ld1R5cGU6IG5ld1R5cGV9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJUeXBlQ2hhbmdlKG9sZExheWVyLCBuZXdUeXBlKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdsYXllclR5cGVDaGFuZ2UnLCAnb2xkTGF5ZXInLCBvbGRMYXllciwgJ25ld1R5cGUnLCBuZXdUeXBlKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9UWVBFX0NIQU5HRSxcbiAgICBvbGRMYXllcixcbiAgICBuZXdUeXBlXG4gIH07XG59XG5cbi8qKlxuICogVXBkYXRlIGxheWVyIHZpc3VhbCBjaGFubmVsXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge09iamVjdH0gb2xkTGF5ZXIgLSBsYXllciB0byBiZSB1cGRhdGVkXG4gKiBAcGFyYW0ge09iamVjdH0gbmV3Q29uZmlnIC0gbmV3IHZpc3VhbCBjaGFubmVsIGNvbmZpZ1xuICogQHBhcmFtIHtzdHJpbmd9IGNoYW5uZWwgLSBjaGFubmVsIHRvIGJlIHVwZGF0ZWRcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfVklTVUFMX0NIQU5ORUxfQ0hBTkdFLCBvbGRMYXllcjogb2xkTGF5ZXIsIG5ld0NvbmZpZzogbmV3Q29uZmlnLCBjaGFubmVsOiBjaGFubmVsfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxheWVyVmlzdWFsQ2hhbm5lbENvbmZpZ0NoYW5nZShvbGRMYXllciwgbmV3Q29uZmlnLCBjaGFubmVsKSB7XG4gIC8vIGNvbnNvbGUubG9nKFxuICAvLyAgICdsYXllclZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2UnLFxuICAvLyAgICdvbGRMYXllcicsXG4gIC8vICAgb2xkTGF5ZXIsXG4gIC8vICAgJ25ld0NvbmZpZycsXG4gIC8vICAgbmV3Q29uZmlnLFxuICAvLyAgIGNoYW5uZWxcbiAgLy8gKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9WSVNVQUxfQ0hBTk5FTF9DSEFOR0UsXG4gICAgb2xkTGF5ZXIsXG4gICAgbmV3Q29uZmlnLFxuICAgIGNoYW5uZWxcbiAgfTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgYHZpc0NvbmZpZ2BcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBuZXdWaXNDb25maWcgLSBuZXcgdmlzQ29uZmlnIGFzIGEga2V5IHZhbHVlIG1hcDogZS5nLiBge29wYWNpdHk6IDAuOH1gXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLkxBWUVSX1ZJU19DT05GSUdfQ0hBTkdFLCBvbGRMYXllcjogb2xkTGF5ZXIsIG5ld1Zpc0NvbmZpZzogbmV3VmlzQ29uZmlnfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxheWVyVmlzQ29uZmlnQ2hhbmdlKG9sZExheWVyLCBuZXdWaXNDb25maWcpIHtcbiAgLy8gY29uc29sZS5sb2coXG4gIC8vICAgJ2xheWVyVmlzQ29uZmlnQ2hhbmdlJyxcbiAgLy8gICAnb2xkTGF5ZXInLFxuICAvLyAgIG9sZExheWVyLFxuICAvLyAgICduZXdWaXNDb25maWcnLFxuICAvLyAgIG5ld1Zpc0NvbmZpZ1xuICAvLyApO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkxBWUVSX1ZJU19DT05GSUdfQ0hBTkdFLFxuICAgIG9sZExheWVyLFxuICAgIG5ld1Zpc0NvbmZpZ1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2lkZ2V0Q29uZmlnQ2hhbmdlKG9sZFdpZGdldCwgbmV3Q29uZmlnLCBhdXRoLCBwcm9qZWN0KSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuV0lER0VUX0NPTkZJR19DSEFOR0UsXG4gICAgb2xkV2lkZ2V0LFxuICAgIG5ld0NvbmZpZyxcbiAgICBhdXRoLFxuICAgIHByb2plY3RcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdpZGdldFR5cGVDaGFuZ2Uob2xkV2lkZ2V0LCBuZXdUeXBlKSB7XG4gIC8vIGNvbnNvbGUubG9nKCd3aWRnZXRUeXBlQ2hhbmdlJywgJ29sZFdpZGdldCcsIG9sZFdpZGdldCwgJ25ld1R5cGUnLCBuZXdUeXBlKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5XSURHRVRfVFlQRV9DSEFOR0UsXG4gICAgb2xkV2lkZ2V0LFxuICAgIG5ld1R5cGVcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdpZGdldFZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2Uob2xkV2lkZ2V0LCBuZXdDb25maWcsIGNoYW5uZWwpIHtcbiAgLy8gY29uc29sZS5sb2coXG4gIC8vICAgJ3dpZGdldFZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2UnLFxuICAvLyAgICdvbGRXaWRnZXQnLFxuICAvLyAgIG9sZFdpZGdldCxcbiAgLy8gICAnbmV3Q29uZmlnJyxcbiAgLy8gICBuZXdDb25maWcsXG4gIC8vICAgJ2NoYW5uZWwnLFxuICAvLyAgIGNoYW5uZWxcbiAgLy8gKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5XSURHRVRfVklTVUFMX0NIQU5ORUxfQ0hBTkdFLFxuICAgIG9sZFdpZGdldCxcbiAgICBuZXdDb25maWcsXG4gICAgY2hhbm5lbFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2lkZ2V0VmlzQ29uZmlnQ2hhbmdlKG9sZFdpZGdldCwgbmV3VmlzQ29uZmlnKSB7XG4gIC8vIGNvbnNvbGUubG9nKFxuICAvLyAgICd3aWRnZXRWaXNDb25maWdDaGFuZ2UnLFxuICAvLyAgICdvbGRXaWRnZXQnLFxuICAvLyAgIG9sZFdpZGdldCxcbiAgLy8gICAnbmV3VmlzQ29uZmlnJyxcbiAgLy8gICBuZXdWaXNDb25maWdcbiAgLy8gKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5XSURHRVRfVklTX0NPTkZJR19DSEFOR0UsXG4gICAgb2xkV2lkZ2V0LFxuICAgIG5ld1Zpc0NvbmZpZ1xuICB9O1xufVxuXG4vKipcbiAqIFNldCB0aGUgY29sb3IgcGFsZXR0ZSB1aSBmb3IgbGF5ZXIgY29sb3JcbiAqIEBtZW1iZXJPZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvbGRMYXllciAtIGxheWVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wIC0gd2hpY2ggY29sb3IgcHJvcFxuICogQHBhcmFtIHtvYmplY3R9IG5ld0NvbmZpZyAtIHRvIGJlIG1lcmdlZFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJDb2xvclVJQ2hhbmdlKG9sZExheWVyLCBwcm9wLCBuZXdDb25maWcpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9DT0xPUl9VSV9DSEFOR0UsXG4gICAgb2xkTGF5ZXIsXG4gICAgcHJvcCxcbiAgICBuZXdDb25maWdcbiAgfTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgbGF5ZXIgYmxlbmRpbmcgbW9kZVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtzdHJpbmd9IG1vZGUgb25lIG9mIGBhZGRpdGl2ZWAsIGBub3JtYWxgIGFuZCBgc3VidHJhY3RpdmVgXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLlVQREFURV9MQVlFUl9CTEVORElORywgbW9kZTogbW9kZX19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVMYXllckJsZW5kaW5nKG1vZGUpIHtcbiAgLy8gY29uc29sZS5sb2coJ3VwZGF0ZUxheWVyQmxlbmRpbmcnLCAnbW9kZScsIG1vZGUpO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlVQREFURV9MQVlFUl9CTEVORElORyxcbiAgICBtb2RlXG4gIH07XG59XG5cbi8qKlxuICogVXBkYXRlIGBpbnRlcmFjdGlvbkNvbmZpZ2BcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBuZXcgY29uZmlnIGFzIGtleSB2YWx1ZSBtYXA6IGB7dG9vbHRpcDoge2VuYWJsZWQ6IHRydWV9fWBcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuSU5URVJBQ1RJT05fQ09ORklHX0NIQU5HRSwgY29uZmlnOiBjb25maWd9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJhY3Rpb25Db25maWdDaGFuZ2UoY29uZmlnKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdpbnRlcmFjdGlvbkNvbmZpZ0NoYW5nZScsICdjb25maWcnLCBjb25maWcpO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLklOVEVSQUNUSU9OX0NPTkZJR19DSEFOR0UsXG4gICAgY29uZmlnXG4gIH07XG59XG5cbi8qKlxuICogVXBkYXRlIGZpbHRlciBwcm9wZXJ0eVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtOdW1iZXJ9IGlkeCAtYGlkeGAgb2YgZmlsdGVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIC0gYHByb3BgIG9mIGZpbHRlciwgZSxnLCBgZGF0YUlkYCwgYG5hbWVgLCBgdmFsdWVgXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gbmV3IHZhbHVlXG4gKiBAcGFyYW0ge051bWJlcn0gdmFsdWVJbmRleCAtIGFycmF5IHByb3BlcnRpZXMgbGlrZSBkYXRhc2V0IHJlcXVpcmUgaW5kZXggaW4gb3JkZXIgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZVxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRklMVEVSLCBpZHg6IGlkeCwgcHJvcDogcHJvcCwgdmFsdWU6IHZhbHVlfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEZpbHRlcihcbiAgaWR4LFxuICBwcm9wLFxuICB2YWx1ZSxcbiAgdmFsdWVJbmRleCxcbiAgbWFwU3RhdGUsXG4gIGF1dGgsXG4gIHByb2plY3Rcbikge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlNFVF9GSUxURVIsXG4gICAgaWR4LFxuICAgIHByb3AsXG4gICAgdmFsdWUsXG4gICAgdmFsdWVJbmRleCxcbiAgICBtYXBTdGF0ZSxcbiAgICBhdXRoLFxuICAgIHByb2plY3RcbiAgfTtcbn1cblxuLyoqXG4gKiB1cGRhdGUgZmlsdGVyIHByb3BlcnR5XG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge051bWJlcn0gaWR4IC0gYGlkeGAgb2YgZmlsdGVyIHRvIGJlIHVwZGF0ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIC0gYHByb3BgIG9mIGZpbHRlciwgZSxnLCBgZGF0YUlkYCwgYG5hbWVgLCBgdmFsdWVgXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gbmV3IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YUlkIC0gYGRhdGFJZGAgb2YgZmlsdGVyIHdpdGggd2hpY2ggdGhlIGZpbHRlciBpcyBhc3NvY2lhdGVkXG4gKiBAcGFyYW0ge3N0cmluZ30gcmFuZ2UgLSBgcmFuZ2VgIG9mIGZpbHRlclxuICogQHBhcmFtIHtvYmplY3R9IGhpc3RvZ3JhbSAtIGBoaXN0b2dyYW1gIG9mIGZpbHRlclxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRklMVEVSX0FQSSwgaWR4OmlkeCwgZGF0YUlkOmRhdGFJZCxyYW5nZTpyYW5nZSwgaGlzdG9ncmFtOmhpc3RvZ3JhbSB9fVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RmlsdGVyQVBJKFxuICBpZHgsXG4gIHByb3AsXG4gIHZhbHVlLFxuICB2YWx1ZUluZGV4LFxuICBkYXRhSWQsXG4gIGRvbWFpbixcbiAgaGlzdG9ncmFtXG4pIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRklMVEVSX0FQSSxcbiAgICBpZHgsXG4gICAgcHJvcCxcbiAgICB2YWx1ZSxcbiAgICB2YWx1ZUluZGV4LFxuICAgIGRhdGFJZCxcbiAgICBkb21haW4sXG4gICAgaGlzdG9ncmFtXG4gIH07XG59XG4vKipcbiAqIEFkZCBhIG5ldyBmaWx0ZXJcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhSWQgLSBkYXRhc2V0IGBpZGAgdGhpcyBuZXcgZmlsdGVyIGlzIGFzc29jaWF0ZWQgd2l0aFxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5BRERfRklMVEVSLCBkYXRhSWQ6IGRhdGFJZH19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRGaWx0ZXIoZGF0YUlkKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdhZGRGaWx0ZXInLCAnZGF0YUlEJywgZGF0YUlkKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5BRERfRklMVEVSLFxuICAgIGRhdGFJZFxuICB9O1xufVxuXG4vKipcbiAqIEFkZCBhIG5ldyBsYXllclxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gbmV3IGxheWVyIHByb3BzXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLkFERF9MQVlFUiwgcHJvcHM6IHByb3BzfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZExheWVyKHByb3BzKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdhZGRMYXllcicsICdwcm9wcycsIHByb3BzKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5BRERfTEFZRVIsXG4gICAgcHJvcHNcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFdpZGdldChwcm9wcykge1xuICAvLyBjb25zb2xlLmxvZygnYWRkV2lkZ2V0JywgJ3Byb3BzJywgcHJvcHMpO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkFERF9XSURHRVQsXG4gICAgcHJvcHNcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlb3JkZXJXaWRnZXQob3JkZXIpIHtcbiAgLy8gY29uc29sZS5sb2coJ3Jlb3JkZXJXaWRnZXQnLCAnb3JkZXInLCBvcmRlcik7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuUkVPUkRFUl9XSURHRVQsXG4gICAgb3JkZXJcbiAgfTtcbn1cblxuLyoqXG4gKiBSZW9yZGVyIGxheWVyLCBvcmRlciBpcyBhbiBhcnJheSBvZiBsYXllciBpbmRleGVzLCBpbmRleCAwIHdpbGwgYmUgdGhlIG9uZSBhdCB0aGUgYm90dG9tXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge0FycmF5PE51bWJlcj59IG9yZGVyIGFuIGFycmF5IG9mIGxheWVyIGluZGV4ZXNcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuUkVPUkRFUl9MQVlFUiwgb3JkZXI6IG9yZGVyfX1cbiAqIEBwdWJsaWNcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gYnJpbmcgYGxheWVyc1sxXWAgYmVsb3cgYGxheWVyc1swXWAsIHRoZSBzZXF1ZW5jZSBsYXllcnMgd2lsbCBiZSByZW5kZXJlZCBpcyBgMWAsIGAwYCwgYDJgLCBgM2AuXG4gKiAvLyBgMWAgd2lsbCBiZSBhdCB0aGUgYm90dG9tLCBgM2Agd2lsbCBiZSBhdCB0aGUgdG9wLlxuICogdGhpcy5wcm9wcy5kaXNwYXRjaChyZW9yZGVyTGF5ZXIoWzEsIDAsIDIsIDNdKSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW9yZGVyTGF5ZXIob3JkZXIpIHtcbiAgLy8gY29uc29sZS5sb2coJ3Jlb3JkZXJMYXllcicsICdvcmRlcicsIG9yZGVyKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5SRU9SREVSX0xBWUVSLFxuICAgIG9yZGVyXG4gIH07XG59XG5cbi8qKlxuICogUmVtb3ZlIGEgZmlsdGVyIGZyb20gYHZpc1N0YXRlLmZpbHRlcnNgLCBvbmNlIGEgZmlsdGVyIGlzIHJlbW92ZWQsIGRhdGEgd2lsbCBiZSByZS1maWx0ZXJlZCBhbmQgbGF5ZXIgd2lsbCBiZSB1cGRhdGVkXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge051bWJlcn0gaWR4IGlkeCBvZiBmaWx0ZXIgdG8gYmUgcmVtb3ZlZFxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5SRU1PVkVfRklMVEVSLCBpZHg6IGlkeH19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVGaWx0ZXIoaWR4LCBtYXBTdGF0ZSwgYXV0aCwgcHJvamVjdCkge1xuICAvLyBjb25zb2xlLmxvZygncmVtb3ZlRmlsdGVyJywgJ2lkeCcsIGlkeCk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuUkVNT1ZFX0ZJTFRFUixcbiAgICBpZHgsXG4gICAgbWFwU3RhdGUsXG4gICAgYXV0aCxcbiAgICBwcm9qZWN0XG4gIH07XG59XG5cbi8qKlxuICogUmVtb3ZlIGEgbGF5ZXJcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHggaWR4IG9mIGxheWVyIHRvIGJlIHJlbW92ZWRcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuUkVNT1ZFX0xBWUVSLCBpZHg6IGlkeH19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVMYXllcihpZHgpIHtcbiAgLy8gY29uc29sZS5sb2coJ3JlbW92ZUxheWVyJywgJ2lkeCcsIGlkeCk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuUkVNT1ZFX0xBWUVSLFxuICAgIGlkeFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlV2lkZ2V0KGlkeCkge1xuICAvLyBjb25zb2xlLmxvZygncmVtb3ZlV2lkZ2V0JywgJ2lkeCcsIGlkeCk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuUkVNT1ZFX1dJREdFVCxcbiAgICBpZHhcbiAgfTtcbn1cblxuLyoqXG4gKiBSZW1vdmUgYSBkYXRhc2V0IGFuZCBhbGwgbGF5ZXJzLCBmaWx0ZXJzLCB0b29sdGlwIGNvbmZpZ3MgdGhhdCBiYXNlZCBvbiBpdFxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtzdHJpbmd9IGtleSBkYXRhc2V0IGlkXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLlJFTU9WRV9EQVRBU0VULCBrZXk6IGtleX19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVEYXRhc2V0KGtleSkge1xuICAvLyBjb25zb2xlLmxvZygncmVtb3ZlRGF0YXNldCcsICdrZXknLCBrZXkpO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlJFTU9WRV9EQVRBU0VULFxuICAgIGtleVxuICB9O1xufVxuXG4vKipcbiAqIERpc3BsYXkgZGF0YXNldCB0YWJsZSBpbiBhIG1vZGFsXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YUlkIGRhdGFzZXQgaWQgdG8gc2hvdyBpbiB0YWJsZVxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5TSE9XX0RBVEFTRVRfVEFCTEUsIGRhdGFJZDogZGF0YUlkfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNob3dEYXRhc2V0VGFibGUoZGF0YUlkKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdzaG93RGF0YXNldFRhYmxlJywgJ2RhdGFJZCcsIGRhdGFJZCk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuU0hPV19EQVRBU0VUX1RBQkxFLFxuICAgIGRhdGFJZFxuICB9O1xufVxuXG4vKipcbiAqIEFkZCBuZXcgZGF0YXNldCB0byBgdmlzU3RhdGVgLCB3aXRoIG9wdGlvbiB0byBsb2FkIGEgbWFwIGNvbmZpZyBhbG9uZyB3aXRoIHRoZSBkYXRhc2V0c1xuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fE9iamVjdH0gZGF0YXNldHMgLSAqKipyZXF1aXJlZCoqIGRhdGFzZXRzIGNhbiBiZSBhIGRhdGFzZXQgb3IgYW4gYXJyYXkgb2YgZGF0YXNldHNcbiAqIEVhY2ggZGF0YXNldCBvYmplY3QgbmVlZHMgdG8gaGF2ZSBgaW5mb2AgYW5kIGBkYXRhYCBwcm9wZXJ0eS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhc2V0cy5pbmZvIC1pbmZvIG9mIGEgZGF0YXNldFxuICogQHBhcmFtIHtzdHJpbmd9IGRhdGFzZXRzLmluZm8uaWQgLSBpZCBvZiB0aGlzIGRhdGFzZXQuIElmIGNvbmZpZyBpcyBkZWZpbmVkLCBgaWRgIHNob3VsZCBtYXRjaGVzIHRoZSBgZGF0YUlkYCBpbiBjb25maWcuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldHMuaW5mby5sYWJlbCAtIEEgZGlzcGxheSBuYW1lIG9mIHRoaXMgZGF0YXNldFxuICogQHBhcmFtIHtPYmplY3R9IGRhdGFzZXRzLmRhdGEgLSAqKipyZXF1aXJlZCoqIFRoZSBkYXRhIG9iamVjdCwgaW4gYSB0YWJ1bGFyIGZvcm1hdCB3aXRoIDIgcHJvcGVydGllcyBgZmllbGRzYCBhbmQgYHJvd3NgXG4gKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGRhdGFzZXRzLmRhdGEuZmllbGRzIC0gKioqcmVxdWlyZWQqKiBBcnJheSBvZiBmaWVsZHMsXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldHMuZGF0YS5maWVsZHMubmFtZSAtICoqKnJlcXVpcmVkKiogTmFtZSBvZiB0aGUgZmllbGQsXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5Pn0gZGF0YXNldHMuZGF0YS5yb3dzIC0gKioqcmVxdWlyZWQqKiBBcnJheSBvZiByb3dzLCBpbiBhIHRhYnVsYXIgZm9ybWF0IHdpdGggYGZpZWxkc2AgYW5kIGByb3dzYFxuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zLmNlbnRlck1hcCBgZGVmYXVsdDogdHJ1ZWAgaWYgYGNlbnRlck1hcGAgaXMgc2V0IHRvIGB0cnVlYCBrZXBsZXIuZ2wgd2lsbFxuICogcGxhY2UgdGhlIG1hcCB2aWV3IHdpdGhpbiB0aGUgZGF0YSBwb2ludHMgYm91bmRhcmllc1xuICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zLnJlYWRPbmx5IGBkZWZhdWx0OiBmYWxzZWAgaWYgYHJlYWRPbmx5YCBpcyBzZXQgdG8gYHRydWVgXG4gKiB0aGUgbGVmdCBzZXR0aW5nIHBhbmVsIHdpbGwgYmUgaGlkZGVuXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIHRoaXMgb2JqZWN0IHdpbGwgY29udGFpbiB0aGUgZnVsbCBrZXBsZXIuZ2wgaW5zdGFuY2UgY29uZmlndXJhdGlvbiB7bWFwU3RhdGUsIG1hcFN0eWxlLCB2aXNTdGF0ZX1cbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuVVBEQVRFX1ZJU19EQVRBLCBkYXRhc2V0czogZGF0YXNldHMsIG9wdGlvbnM6IG9wdGlvbnMsIGNvbmZpZzogY29uZmlnfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVZpc0RhdGEoZGF0YXNldHMsIG9wdGlvbnMsIGNvbmZpZykge1xuICAvLyBjb25zb2xlLmxvZyhcbiAgLy8gICAndXBkYXRlVmlzRGF0YScsXG4gIC8vICAgJ2RhdGFzZXRzJyxcbiAgLy8gICBkYXRhc2V0cyxcbiAgLy8gICAnb3B0aW9ucycsXG4gIC8vICAgb3B0aW9ucyxcbiAgLy8gICAnY29uZmlnJyxcbiAgLy8gICBjb25maWdcbiAgLy8gKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5VUERBVEVfVklTX0RBVEEsXG4gICAgZGF0YXNldHMsXG4gICAgb3B0aW9ucyxcbiAgICBjb25maWdcbiAgfTtcbn1cblxuLyoqXG4gKiBTdGFydCBhbmQgZW5kIGZpbHRlciBhbmltYXRpb25cbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHggLSBpZHggb2YgZmlsdGVyXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLlRPR0dMRV9GSUxURVJfQU5JTUFUSU9OLCBpZHg6IGlkeH19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2dnbGVGaWx0ZXJBbmltYXRpb24oaWR4KSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuVE9HR0xFX0ZJTFRFUl9BTklNQVRJT04sXG4gICAgaWR4XG4gIH07XG59XG5cbi8qKlxuICogQ2hhbmdlIGZpbHRlciBhbmltYXRpb24gc3BlZWRcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHggLSAgYGlkeGAgb2YgZmlsdGVyXG4gKiBAcGFyYW0ge051bWJlcn0gc3BlZWQgLSBgc3BlZWRgIHRvIGNoYW5nZSBpdCB0by4gYHNwZWVkYCBpcyBhIG11bHRpcGxpZXJcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuVVBEQVRFX0ZJTFRFUl9BTklNQVRJT05fU1BFRUQsIGlkeDogaWR4LCBzcGVlZDogc3BlZWR9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlRmlsdGVyQW5pbWF0aW9uU3BlZWQoaWR4LCBzcGVlZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlVQREFURV9GSUxURVJfQU5JTUFUSU9OX1NQRUVELFxuICAgIGlkeCxcbiAgICBzcGVlZFxuICB9O1xufVxuXG4vKipcbiAqIFJlc2V0IGFuaW1hdGlvblxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlIC0gIEN1cnJlbnQgdmFsdWUgb2YgdGhlIHNsaWRlclxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5SRVNFVF9BTklNQVRJT04sIHZhbHVlOiB2YWx1ZX19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBbmltYXRpb25UaW1lKHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuVVBEQVRFX0FOSU1BVElPTl9USU1FLFxuICAgIHZhbHVlXG4gIH07XG59XG5cbi8qKlxuICogdXBkYXRlIHRyaXAgbGF5ZXIgYW5pbWF0aW9uIHNwZWVkXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge051bWJlcn0gc3BlZWQgLSBgc3BlZWRgIHRvIGNoYW5nZSBpdCB0by4gYHNwZWVkYCBpcyBhIG11bHRpcGxpZXJcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuVVBEQVRFX0xBWUVSX0FOSU1BVElPTl9TUEVFRCwgc3BlZWQ6IHNwZWVkfX1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUxheWVyQW5pbWF0aW9uU3BlZWQoc3BlZWQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5VUERBVEVfTEFZRVJfQU5JTUFUSU9OX1NQRUVELFxuICAgIHNwZWVkXG4gIH07XG59XG5cbi8qKlxuICogU2hvdyBsYXJnZXIgdGltZSBmaWx0ZXIgYXQgYm90dG9tIGZvciB0aW1lIHBsYXliYWNrIChhcHBseSB0byB0aW1lIGZpbHRlciBvbmx5KVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtOdW1iZXJ9IGlkeCAtIGluZGV4IG9mIGZpbHRlciB0byBlbmxhcmdlXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLkVOTEFSR0VfRklMVEVSLCBpZHg6IGlkeH19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmxhcmdlRmlsdGVyKGlkeCkge1xuICAvLyBjb25zb2xlLmxvZygnZW5sYXJnZUZpbHRlcicsICdpZHgnLCBpZHgpO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkVOTEFSR0VfRklMVEVSLFxuICAgIGlkeFxuICB9O1xufVxuXG4vKipcbiAqIFRyaWdnZXIgbGF5ZXIgaG92ZXIgZXZlbnQgd2l0aCBob3ZlcmVkIG9iamVjdFxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IGluZm8gLSBPYmplY3QgaG92ZXJlZCwgcmV0dXJuZWQgYnkgZGVjay5nbFxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9IT1ZFUiwgaW5mbzogaW5mb319XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkxheWVySG92ZXIoaW5mbykge1xuICAvLyBjb25zb2xlLmxvZygnb25MYXllckhvdmVyJywgaW5mbyk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfSE9WRVIsXG4gICAgaW5mb1xuICB9O1xufVxuXG4vKipcbiAqIFRyaWdnZXIgbGF5ZXIgY2xpY2sgZXZlbnQgd2l0aCBjbGlja2VkIG9iamVjdFxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IGluZm8gLSBPYmplY3QgY2xpY2tlZCwgcmV0dXJuZWQgYnkgZGVjay5nbFxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5MQVlFUl9DTElDSywgaW5mbzogaW5mb319XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkxheWVyQ2xpY2soaW5mbykge1xuICAvLyBjb25zb2xlLmxvZygnb25MYXllckNsaWNrJywgaW5mbyk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTEFZRVJfQ0xJQ0ssXG4gICAgaW5mb1xuICB9O1xufVxuXG4vKipcbiAqIFRyaWdnZXIgbWFwIGNsaWNrIGV2ZW50LCB1bnNlbGVjdCBjbGlja2VkIG9iamVjdFxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5NQVBfQ0xJQ0t9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25NYXBDbGljaygpIHtcbiAgLy8gY29uc29sZS5sb2coJ29uTWFwQ2xpY2snKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5NQVBfQ0xJQ0tcbiAgfTtcbn1cblxuLyoqXG4gKiBUcmlnZ2VyIG1hcCBtb3VzZSBtb3ZlZXZlbnQsIHBheWxvYWQgd291bGQgYmVcbiAqIFJlYWN0LW1hcC1nbCBQb2ludGVyRXZlbnRcbiAqIGh0dHBzOi8vdWJlci5naXRodWIuaW8vcmVhY3QtbWFwLWdsLyMvZG9jdW1lbnRhdGlvbi9hcGktcmVmZXJlbmNlL3BvaW50ZXItZXZlbnRcbiAqXG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge09iamVjdH0gZXZ0IC0gUG9pbnRlckV2ZW50XG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLk1BUF9DTElDS319XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbk1vdXNlTW92ZShldnQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5NT1VTRV9NT1ZFLFxuICAgIGV2dFxuICB9O1xufVxuXG4vKipcbiAqIFRvZ2dsZSB2aXNpYmlsaXR5IG9mIGEgbGF5ZXIgaW4gYSBzcGxpdCBtYXBcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBtYXBJbmRleCAtIGluZGV4IG9mIHRoZSBzcGxpdCBtYXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBsYXllcklkIC0gaWQgb2YgdGhlIGxheWVyXG4gKiBAcmV0dXJucyB7e3R5cGU6IEFjdGlvblR5cGVzLlRPR0dMRV9MQVlFUl9GT1JfTUFQLCBtYXBJbmRleDogKiwgbGF5ZXJJZDogKn19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2dnbGVMYXllckZvck1hcChtYXBJbmRleCwgbGF5ZXJJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlRPR0dMRV9MQVlFUl9GT1JfTUFQLFxuICAgIG1hcEluZGV4LFxuICAgIGxheWVySWRcbiAgfTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIHByb3BlcnR5IG9mIGEgZmlsdGVyIHBsb3RcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHhcbiAqIEBwYXJhbSB7T2JqZWN0fSBuZXdQcm9wIGtleSB2YWx1ZSBtYXBwaW5nIG9mIG5ldyBwcm9wIGB7eUF4aXM6ICdoaXN0b2dyYW0nfWBcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuU0VUX0ZJTFRFUl9QTE9ULCBpZHg6ICosIG5ld1Byb3A6ICp9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RmlsdGVyUGxvdChpZHgsIG5ld1Byb3ApIHtcbiAgLy8gY29uc29sZS5sb2coJ3NldEZpbHRlclBsb3QnLCBpZHgsIG5ld1Byb3ApO1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLlNFVF9GSUxURVJfUExPVCxcbiAgICBpZHgsXG4gICAgbmV3UHJvcFxuICB9O1xufVxuXG4vKipcbiAqIFRyaWdnZXIgZmlsZSBsb2FkaW5nIGRpc3BhdGNoIGBhZGREYXRhVG9NYXBgIGlmIHN1Y2NlZWQsIG9yIGBsb2FkRmlsZXNFcnJgIGlmIGZhaWxlZFxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBmaWxlcyBhcnJheSBvZiBmaWxlYmxvYlxuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5MT0FEX0ZJTEVTLCBmaWxlczogKn19XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkRmlsZXMoZmlsZXMpIHtcbiAgLy8gY29uc29sZS5sb2coJ2xvYWRGaWxlcycsIGZpbGVzKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MT0FEX0ZJTEVTLFxuICAgIGZpbGVzXG4gIH07XG59XG5cbi8qKlxuICogVHJpZ2dlciBsb2FkaW5nIGZpbGUgZXJyb3JcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7Kn0gZXJyb3JcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuTE9BRF9GSUxFU19FUlIsIGVycm9yOiBPYmplY3R9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEZpbGVzRXJyKGVycm9yKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdsb2FkRmlsZXNFcnInLCBlcnJvcik7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuTE9BRF9GSUxFU19FUlIsXG4gICAgZXJyb3JcbiAgfTtcbn1cblxuLyoqXG4gKiBTdG9yZSBmZWF0dXJlcyB0byBzdGF0ZVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBmZWF0dXJlc1xuICogQHJldHVybnMge3t0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRkVBVFVSRVMsIGZlYXR1cmVzOiBPYmplY3R9fVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RmVhdHVyZXMoZmVhdHVyZXMsIGF1dGgsIHByb2plY3QsIG1hcFN0YXRlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuU0VUX0ZFQVRVUkVTLFxuICAgIGZlYXR1cmVzLFxuICAgIGF1dGgsXG4gICAgcHJvamVjdCxcbiAgICBtYXBTdGF0ZVxuICB9O1xufVxuXG4vKipcbiAqIEl0IHdpbGwgYXBwbHkgdGhlIHByb3ZpZGUgZmVhdHVyZSBhcyBmaWx0ZXIgdG8gdGhlIGdpdmVuIGxheWVyLlxuICogSWYgdGhlIGdpdmVuIGZlYXR1cmUgaXMgYWxyZWFkeSBhcHBsaWVkIGFzIGZpbHRlciB0byB0aGUgbGF5ZXIsIGl0IHdpbGwgcmVtb3ZlIHRoZSBsYXllciBmcm9tIHRoZSBmaWx0ZXJcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBsYXllclxuICogQHBhcmFtIHtPYmplY3R9IGZlYXR1cmVcbiAqIEByZXR1cm4ge3tmZWF0dXJlOiAqLCB0eXBlOiBBY3Rpb25UeXBlcy5TRVRfUE9MWUdPTl9GSUxURVJfTEFZRVIsIGxheWVyOiAqfX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFBvbHlnb25GaWx0ZXJMYXllcihsYXllciwgZmVhdHVyZSwgYXV0aCwgcHJvamVjdCwgbWFwU3RhdGUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5TRVRfUE9MWUdPTl9GSUxURVJfTEFZRVIsXG4gICAgbGF5ZXIsXG4gICAgZmVhdHVyZSxcbiAgICBhdXRoLFxuICAgIHByb2plY3QsXG4gICAgbWFwU3RhdGVcbiAgfTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIGN1cnJlbnQgZmVhdHVyZSB0byBiZSBlZGl0ZWQvZGVsZXRlZFxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IGZlYXR1cmVcbiAqIEBwYXJhbSB7c3RyaW5nfSBmZWF0dXJlLnNlbGVjdGVkRmVhdHVyZUlkXG4gKiBAcmV0dXJuIHt7c2VsZWN0ZWRGZWF0dXJlSWQ6ICosIHR5cGU6IEFjdGlvblR5cGVzLlNFVF9TRUxFQ1RFRF9GRUFUVVJFfX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFNlbGVjdGVkRmVhdHVyZShmZWF0dXJlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuU0VUX1NFTEVDVEVEX0ZFQVRVUkUsXG4gICAgZmVhdHVyZVxuICB9O1xufVxuXG4vKipcbiAqIERlbGV0ZSB0aGUgZ2l2ZW4gZmVhdHVyZVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtzdHJpbmd9IGZlYXR1cmVJZCBpZiBvZiB0aGUgZmVhdHVyZVxuICogQHJldHVybiB7e3R5cGU6IEFjdGlvblR5cGVzLkRFTEVURV9GRUFUVVJFLCBmZWF0dXJlSWQ6ICp9fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlRmVhdHVyZShmZWF0dXJlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuREVMRVRFX0ZFQVRVUkUsXG4gICAgZmVhdHVyZVxuICB9O1xufVxuXG4vKiogU2V0IHRoZSBtYXAgbW9kZVxuICogQG1lbWJlcm9mIHZpc1N0YXRlQWN0aW9uc1xuICogQHBhcmFtIHtzdHJpbmd9IG1vZGUgb25lIG9mIEVESVRPUl9NT0RFU1xuICogQHJldHVybiB7e3R5cGU6IEFjdGlvblR5cGVzLiBTRVRfRURJVE9SX01PREUsIG1vZGU6ICp9fVxuICogQHB1YmxpY1xuICogQGV4YW1wbGVcbiAqIGltcG9ydCB7c2V0TWFwTW9kZX0gZnJvbSAna2VwbGVyLmdsL2FjdGlvbnMnO1xuICogaW1wb3J0IHtFRElUT1JfTU9ERVN9IGZyb20gJ2tlcGxlci5nbC9jb25zdGFudHMnO1xuICpcbiAqIHRoaXMucHJvcHMuZGlzcGF0Y2goc2V0TWFwTW9kZShFRElUT1JfTU9ERVMuRFJBV19QT0xZR09OKSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRFZGl0b3JNb2RlKG1vZGUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5TRVRfRURJVE9SX01PREUsXG4gICAgbW9kZVxuICB9O1xufVxuXG4vKipcbiAqIFRyaWdnZXIgQ1BVIGZpbHRlciBvZiBzZWxlY3RlZCBkYXRhc2V0XG4gKiBAbWVtYmVyb2YgdmlzU3RhdGVBY3Rpb25zXG4gKiBAcGFyYW0ge3N0cmluZyB8IEFycmFyeTxzdHJpbmc+fSBkYXRhSWQgLSBzaW5nbGUgZGF0YUlkIG9yIGFuIGFycmF5IG9mIGRhdGFJZHNcbiAqIEByZXR1cm5zIHt7dHlwZTogQWN0aW9uVHlwZXMuQVBQTFlfQ1BVX0ZJTFRFUiwgZGF0YUlkOiBzdHJpbmd9fVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlDUFVGaWx0ZXIoZGF0YUlkKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuQVBQTFlfQ1BVX0ZJTFRFUixcbiAgICBkYXRhSWRcbiAgfTtcbn1cblxuLyoqXG4gKiBUb2dnbGUgZWRpdG9yIGxheWVyIHZpc2liaWxpdHlcbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEByZXR1cm4ge3t0eXBlOiBBY3Rpb25UeXBlcy5UT0dHTEVfRURJVE9SX1ZJU0lCSUxJVFl9fVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlRWRpdG9yVmlzaWJpbGl0eSgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5UT0dHTEVfRURJVE9SX1ZJU0lCSUxJVFlcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGlzIGRlY2xhcmF0aW9uIGlzIG5lZWRlZCB0byBncm91cCBhY3Rpb25zIGluIGRvY3NcbiAqL1xuLyoqXG4gKiBBY3Rpb25zIGhhbmRsZWQgbW9zdGx5IGJ5IGB2aXNTdGF0ZWAgcmVkdWNlci5cbiAqIFRoZXkgbWFuYWdlIGhvdyBkYXRhIGlzIHByb2Nlc3NlZCwgZmlsdGVyZWQgYW5kIGRpc3BsYXllZCBvbiB0aGUgbWFwIGJ5IG9wZXJhdGVzIG9uIGxheWVycyxcbiAqIGZpbHRlcnMgYW5kIGludGVyYWN0aW9uIHNldHRpbmdzLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IHZpc1N0YXRlQWN0aW9ucyA9IG51bGw7XG4vKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC12YXJzICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkVVJMKFVSTCwgcmFuZ2UpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBBY3Rpb25UeXBlcy5MT0FEX1VSTCxcbiAgICBVUkwsXG4gICAgcmFuZ2VcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRFRExpbmtEYXRhKGRhdGEsIGRhdGFJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEFjdGlvblR5cGVzLkxPQURfRURfTElOSyxcbiAgICBkYXRhLFxuICAgIGRhdGFJZFxuICB9O1xufVxuXG4vKipcbiAqIFVwZGF0ZSBkYXRhc2V0IGluZm9cbiAqIEBtZW1iZXJvZiB2aXNTdGF0ZUFjdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhSWRcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cGRhdGVkQXRcbiAqIEByZXR1cm4ge3t0eXBlOkFjdGlvblR5cGVzLlVQREFURV9EQVRBU0VUX0lORk8sZGF0YUlkOk9iamVjdCwgdXBkYXRlZEF0Oip9fVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVEYXRhc2V0KGRhdGFJZCwgdXBkYXRlZEF0KSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogQWN0aW9uVHlwZXMuVVBEQVRFX0RBVEFTRVRfSU5GTyxcbiAgICBkYXRhSWQsXG4gICAgdXBkYXRlZEF0XG4gIH07XG59XG4iXX0=