kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
300 lines (240 loc) • 34 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getInitialInputStyle = getInitialInputStyle;
exports.addCustomMapStyleUpdater = exports.inputMapStyleUpdater = exports.loadCustomMapStyleUpdater = exports.resetMapConfigMapStyleUpdater = exports.receiveMapConfigUpdater = exports.loadMapStyleErrUpdater = exports.loadMapStylesUpdater = exports.mapStyleChangeUpdater = exports.mapConfigChangeUpdater = exports.initMapStyleUpdater = exports.INITIAL_MAP_STYLE = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _immutable = _interopRequireDefault(require("immutable"));
var _tasks = _interopRequireWildcard(require("react-palm/tasks"));
var _mapboxGlStyleEditor = require("../utils/map-style-utils/mapbox-gl-style-editor");
var _defaultSettings = require("../constants/default-settings");
var _utils = require("../utils/utils");
var _tasks2 = require("../tasks/tasks");
var _mapStyleActions = require("../actions/map-style-actions");
var _d3Color = require("d3-color");
var _colorUtils = require("../utils/color-utils");
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var DEFAULT_BLDG_COLOR = '#D1CEC7';
var getDefaultState = function getDefaultState() {
var visibleLayerGroups = {};
var styleType = 'streets';
var topLayerGroups = {};
return {
styleType: styleType,
visibleLayerGroups: visibleLayerGroups,
topLayerGroups: topLayerGroups,
mapStyles: _defaultSettings.DEFAULT_MAP_STYLES.reduce(function (accu, curr) {
return _objectSpread({}, accu, (0, _defineProperty2["default"])({}, curr.id, curr));
}, {}),
// save mapbox access token
mapboxApiAccessToken: null,
inputStyle: getInitialInputStyle(),
threeDBuildingColor: (0, _colorUtils.hexToRgb)(DEFAULT_BLDG_COLOR)
};
};
var INITIAL_MAP_STYLE = getDefaultState();
/**
* Create two map styles from preset map style, one for top map one for bottom
*
* @param {string} styleType - current map style
* @param {object} visibleLayerGroups - visible layers of bottom map
* @param {object} topLayerGroups - visible layers of top map
* @param {object} mapStyles - a dictionary of all map styles
* @returns {object} bottomMapStyle | topMapStyle | isRaster
*/
exports.INITIAL_MAP_STYLE = INITIAL_MAP_STYLE;
function getMapStyles(_ref) {
var styleType = _ref.styleType,
visibleLayerGroups = _ref.visibleLayerGroups,
topLayerGroups = _ref.topLayerGroups,
mapStyles = _ref.mapStyles;
var mapStyle = mapStyles[styleType]; // style might not be loaded yet
if (!mapStyle || !mapStyle.style) {
return {};
}
var editable = Object.keys(visibleLayerGroups).length;
var bottomMapStyle = !editable ? _immutable["default"].fromJS(mapStyle.style) : (0, _mapboxGlStyleEditor.editBottomMapStyle)({
id: styleType,
mapStyle: mapStyle,
visibleLayerGroups: visibleLayerGroups
});
var hasTopLayer = editable && Object.values(topLayerGroups).some(function (v) {
return v;
}); // mute top layer if not visible in bottom layer
var topLayers = hasTopLayer && Object.keys(topLayerGroups).reduce(function (accu, key) {
return _objectSpread({}, accu, (0, _defineProperty2["default"])({}, key, topLayerGroups[key] && visibleLayerGroups[key]));
}, {});
var topMapStyle = hasTopLayer ? (0, _mapboxGlStyleEditor.editTopMapStyle)({
id: styleType,
mapStyle: mapStyle,
visibleLayerGroups: topLayers
}) : null;
var threeDBuildingColor = get3DBuildingColor(mapStyle);
return {
bottomMapStyle: bottomMapStyle,
topMapStyle: topMapStyle,
editable: editable,
threeDBuildingColor: threeDBuildingColor
};
}
function get3DBuildingColor(style) {
// set building color to be the same as the background color.
var backgroundLayer = (style.style.layers || []).find(function (_ref2) {
var id = _ref2.id;
return id === 'background';
});
var buildingColor = backgroundLayer && backgroundLayer.paint && backgroundLayer.paint['background-color'] ? backgroundLayer.paint['background-color'] : DEFAULT_BLDG_COLOR; // brighten or darken building based on style
var operation = style.id.match(/(?=(dark|night))/) ? 'brighter' : 'darker';
var rgbObj = (0, _d3Color.rgb)(buildingColor)[operation]([0.2]);
return [rgbObj.r, rgbObj.g, rgbObj.b];
}
function getLayerGroupsFromStyle(style) {
return _defaultSettings.DEFAULT_LAYER_GROUPS.filter(function (lg) {
return style.layers.filter(lg.filter).length;
});
} // Updaters
var initMapStyleUpdater = function initMapStyleUpdater(state, action) {
return _objectSpread({}, state, {
// save mapbox access token to map style state
mapboxApiAccessToken: (action.payload || {}).mapboxApiAccessToken
});
};
exports.initMapStyleUpdater = initMapStyleUpdater;
var mapConfigChangeUpdater = function mapConfigChangeUpdater(state, action) {
return _objectSpread({}, state, {}, action.payload, {}, getMapStyles(_objectSpread({}, state, {}, action.payload)));
};
exports.mapConfigChangeUpdater = mapConfigChangeUpdater;
var mapStyleChangeUpdater = function mapStyleChangeUpdater(state, _ref3) {
var styleType = _ref3.payload;
if (!state.mapStyles[styleType]) {
// we might not have received the style yet
return state;
}
var defaultLGVisibility = (0, _mapboxGlStyleEditor.getDefaultLayerGroupVisibility)(state.mapStyles[styleType]);
var visibleLayerGroups = (0, _mapboxGlStyleEditor.mergeLayerGroupVisibility)(defaultLGVisibility, state.visibleLayerGroups);
return _objectSpread({}, state, {
styleType: styleType,
visibleLayerGroups: visibleLayerGroups
}, getMapStyles(_objectSpread({}, state, {
visibleLayerGroups: visibleLayerGroups,
styleType: styleType
})));
};
exports.mapStyleChangeUpdater = mapStyleChangeUpdater;
var loadMapStylesUpdater = function loadMapStylesUpdater(state, action) {
var newStyles = action.payload; // add new styles to state
var newState = _objectSpread({}, state, {
mapStyles: _objectSpread({}, state.mapStyles, {}, newStyles)
});
return newStyles[state.styleType] ? mapStyleChangeUpdater(newState, {
payload: state.styleType
}) : newState;
}; // do nothing for now, if didn't load, skip it
exports.loadMapStylesUpdater = loadMapStylesUpdater;
var loadMapStyleErrUpdater = function loadMapStyleErrUpdater(state, action) {
return state;
};
exports.loadMapStyleErrUpdater = loadMapStyleErrUpdater;
var receiveMapConfigUpdater = function receiveMapConfigUpdater(state, _ref4) {
var mapStyle = _ref4.payload.mapStyle;
if (!mapStyle) {
return state;
} // if saved custom mapStyles load the style object
var loadMapStyleTasks = mapStyle.mapStyles ? [_tasks["default"].all(Object.values(mapStyle.mapStyles).map(function (_ref5) {
var id = _ref5.id,
url = _ref5.url,
accessToken = _ref5.accessToken;
return {
id: id,
url: (0, _mapboxGlStyleEditor.getStyleDownloadUrl)(url, accessToken || state.mapboxApiAccessToken)
};
}).map(_tasks2.LOAD_MAP_STYLE_TASK)).bimap( // success
function (results) {
return (0, _mapStyleActions.loadMapStyles)(results.reduce(function (accu, _ref6) {
var id = _ref6.id,
style = _ref6.style;
return _objectSpread({}, accu, (0, _defineProperty2["default"])({}, id, _objectSpread({}, mapStyle.mapStyles[id], {
layerGroups: getLayerGroupsFromStyle(style),
style: style
})));
}, {}));
}, // error
function (error) {
return (0, _mapStyleActions.loadMapStyleErr)(error);
})] : null;
var newState = mapConfigChangeUpdater(state, {
payload: mapStyle
});
return loadMapStyleTasks ? (0, _tasks.withTask)(newState, loadMapStyleTasks) : newState;
};
exports.receiveMapConfigUpdater = receiveMapConfigUpdater;
var resetMapConfigMapStyleUpdater = function resetMapConfigMapStyleUpdater(state) {
var emptyConfig = _objectSpread({}, INITIAL_MAP_STYLE, {
mapboxApiAccessToken: state.mapboxApiAccessToken
}, state.initialState, {
mapStyles: state.mapStyles,
initialState: state.initialState
});
return mapStyleChangeUpdater(emptyConfig, {
payload: emptyConfig.styleType
});
};
exports.resetMapConfigMapStyleUpdater = resetMapConfigMapStyleUpdater;
var loadCustomMapStyleUpdater = function loadCustomMapStyleUpdater(state, _ref7) {
var _ref7$payload = _ref7.payload,
icon = _ref7$payload.icon,
style = _ref7$payload.style,
error = _ref7$payload.error;
return _objectSpread({}, state, {
inputStyle: _objectSpread({}, state.inputStyle, {}, style ? {
id: style.id || (0, _utils.generateHashId)(),
// make a copy of the style object
style: JSON.parse(JSON.stringify(style)),
label: style.name,
// gathering layer group info from style json
layerGroups: getLayerGroupsFromStyle(style)
} : {}, {}, icon ? {
icon: icon
} : {}, {}, error !== undefined ? {
error: error
} : {})
});
};
exports.loadCustomMapStyleUpdater = loadCustomMapStyleUpdater;
var inputMapStyleUpdater = function inputMapStyleUpdater(state, _ref8) {
var inputStyle = _ref8.payload;
return _objectSpread({}, state, {
inputStyle: _objectSpread({}, inputStyle, {
isValid: (0, _mapboxGlStyleEditor.isValidStyleUrl)(inputStyle.url)
})
});
};
exports.inputMapStyleUpdater = inputMapStyleUpdater;
var addCustomMapStyleUpdater = function addCustomMapStyleUpdater(state, action) {
var styleId = state.inputStyle.id;
var newState = _objectSpread({}, state, {
mapStyles: _objectSpread({}, state.mapStyles, (0, _defineProperty2["default"])({}, styleId, state.inputStyle)),
// set to default
inputStyle: getInitialInputStyle()
}); // set new style
return mapStyleChangeUpdater(newState, {
payload: styleId
});
};
exports.addCustomMapStyleUpdater = addCustomMapStyleUpdater;
function getInitialInputStyle() {
return {
accessToken: null,
error: false,
isValid: false,
label: null,
style: null,
url: null,
custom: true
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy9tYXAtc3R5bGUtdXBkYXRlcnMuanMiXSwibmFtZXMiOlsiREVGQVVMVF9CTERHX0NPTE9SIiwiZ2V0RGVmYXVsdFN0YXRlIiwidmlzaWJsZUxheWVyR3JvdXBzIiwic3R5bGVUeXBlIiwidG9wTGF5ZXJHcm91cHMiLCJtYXBTdHlsZXMiLCJERUZBVUxUX01BUF9TVFlMRVMiLCJyZWR1Y2UiLCJhY2N1IiwiY3VyciIsImlkIiwibWFwYm94QXBpQWNjZXNzVG9rZW4iLCJpbnB1dFN0eWxlIiwiZ2V0SW5pdGlhbElucHV0U3R5bGUiLCJ0aHJlZURCdWlsZGluZ0NvbG9yIiwiSU5JVElBTF9NQVBfU1RZTEUiLCJnZXRNYXBTdHlsZXMiLCJtYXBTdHlsZSIsInN0eWxlIiwiZWRpdGFibGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYm90dG9tTWFwU3R5bGUiLCJJbW11dGFibGUiLCJmcm9tSlMiLCJoYXNUb3BMYXllciIsInZhbHVlcyIsInNvbWUiLCJ2IiwidG9wTGF5ZXJzIiwia2V5IiwidG9wTWFwU3R5bGUiLCJnZXQzREJ1aWxkaW5nQ29sb3IiLCJiYWNrZ3JvdW5kTGF5ZXIiLCJsYXllcnMiLCJmaW5kIiwiYnVpbGRpbmdDb2xvciIsInBhaW50Iiwib3BlcmF0aW9uIiwibWF0Y2giLCJyZ2JPYmoiLCJyIiwiZyIsImIiLCJnZXRMYXllckdyb3Vwc0Zyb21TdHlsZSIsIkRFRkFVTFRfTEFZRVJfR1JPVVBTIiwiZmlsdGVyIiwibGciLCJpbml0TWFwU3R5bGVVcGRhdGVyIiwic3RhdGUiLCJhY3Rpb24iLCJwYXlsb2FkIiwibWFwQ29uZmlnQ2hhbmdlVXBkYXRlciIsIm1hcFN0eWxlQ2hhbmdlVXBkYXRlciIsImRlZmF1bHRMR1Zpc2liaWxpdHkiLCJsb2FkTWFwU3R5bGVzVXBkYXRlciIsIm5ld1N0eWxlcyIsIm5ld1N0YXRlIiwibG9hZE1hcFN0eWxlRXJyVXBkYXRlciIsInJlY2VpdmVNYXBDb25maWdVcGRhdGVyIiwibG9hZE1hcFN0eWxlVGFza3MiLCJUYXNrIiwiYWxsIiwibWFwIiwidXJsIiwiYWNjZXNzVG9rZW4iLCJMT0FEX01BUF9TVFlMRV9UQVNLIiwiYmltYXAiLCJyZXN1bHRzIiwibGF5ZXJHcm91cHMiLCJlcnJvciIsInJlc2V0TWFwQ29uZmlnTWFwU3R5bGVVcGRhdGVyIiwiZW1wdHlDb25maWciLCJpbml0aWFsU3RhdGUiLCJsb2FkQ3VzdG9tTWFwU3R5bGVVcGRhdGVyIiwiaWNvbiIsIkpTT04iLCJwYXJzZSIsInN0cmluZ2lmeSIsImxhYmVsIiwibmFtZSIsInVuZGVmaW5lZCIsImlucHV0TWFwU3R5bGVVcGRhdGVyIiwiaXNWYWxpZCIsImFkZEN1c3RvbU1hcFN0eWxlVXBkYXRlciIsInN0eWxlSWQiLCJjdXN0b20iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUdBOztBQVFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7QUFFQSxJQUFNQSxrQkFBa0IsR0FBRyxTQUEzQjs7QUFFQSxJQUFNQyxlQUFlLEdBQUcsU0FBbEJBLGVBQWtCLEdBQU07QUFDNUIsTUFBTUMsa0JBQWtCLEdBQUcsRUFBM0I7QUFDQSxNQUFNQyxTQUFTLEdBQUcsU0FBbEI7QUFDQSxNQUFNQyxjQUFjLEdBQUcsRUFBdkI7QUFFQSxTQUFPO0FBQ0xELElBQUFBLFNBQVMsRUFBVEEsU0FESztBQUVMRCxJQUFBQSxrQkFBa0IsRUFBbEJBLGtCQUZLO0FBR0xFLElBQUFBLGNBQWMsRUFBZEEsY0FISztBQUlMQyxJQUFBQSxTQUFTLEVBQUVDLG9DQUFtQkMsTUFBbkIsQ0FBMEIsVUFBQ0MsSUFBRCxFQUFPQyxJQUFQO0FBQUEsK0JBQ2hDRCxJQURnQyx1Q0FFbENDLElBQUksQ0FBQ0MsRUFGNkIsRUFFeEJELElBRndCO0FBQUEsS0FBMUIsRUFHUCxFQUhPLENBSk47QUFRTDtBQUNBRSxJQUFBQSxvQkFBb0IsRUFBRSxJQVRqQjtBQVVMQyxJQUFBQSxVQUFVLEVBQUVDLG9CQUFv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QUEsS0FBSyxFQUFFLElBSkY7QUFLTDlELElBQUFBLEtBQUssRUFBRSxJQUxGO0FBTUwrQyxJQUFBQSxHQUFHLEVBQUUsSUFOQTtBQU9Mc0IsSUFBQUEsTUFBTSxFQUFFO0FBUEgsR0FBUDtBQVNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDE5IFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IEltbXV0YWJsZSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IFRhc2ssIHt3aXRoVGFza30gZnJvbSAncmVhY3QtcGFsbS90YXNrcyc7XG5cbi8vIFV0aWxzXG5pbXBvcnQge1xuICBnZXREZWZhdWx0TGF5ZXJHcm91cFZpc2liaWxpdHksXG4gIGlzVmFsaWRTdHlsZVVybCxcbiAgZ2V0U3R5bGVEb3dubG9hZFVybCxcbiAgbWVyZ2VMYXllckdyb3VwVmlzaWJpbGl0eSxcbiAgZWRpdFRvcE1hcFN0eWxlLFxuICBlZGl0Qm90dG9tTWFwU3R5bGVcbn0gZnJvbSAndXRpbHMvbWFwLXN0eWxlLXV0aWxzL21hcGJveC1nbC1zdHlsZS1lZGl0b3InO1xuaW1wb3J0IHtERUZBVUxUX01BUF9TVFlMRVMsIERFRkFVTFRfTEFZRVJfR1JPVVBTfSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5pbXBvcnQge2dlbmVyYXRlSGFzaElkfSBmcm9tICd1dGlscy91dGlscyc7XG5pbXBvcnQge0xPQURfTUFQX1NUWUxFX1RBU0t9IGZyb20gJ3Rhc2tzL3Rhc2tzJztcbmltcG9ydCB7bG9hZE1hcFN0eWxlcywgbG9hZE1hcFN0eWxlRXJyfSBmcm9tICdhY3Rpb25zL21hcC1zdHlsZS1hY3Rpb25zJztcbmltcG9ydCB7cmdifSBmcm9tICdkMy1jb2xvcic7XG5pbXBvcnQgeyBoZXhUb1JnYiB9IGZyb20gJ3V0aWxzL2NvbG9yLXV0aWxzJztcblxuY29uc3QgREVGQVVMVF9CTERHX0NPTE9SID0gJyNEMUNFQzcnO1xuXG5jb25zdCBnZXREZWZhdWx0U3RhdGUgPSAoKSA9PiB7XG4gIGNvbnN0IHZpc2libGVMYXllckdyb3VwcyA9IHt9O1xuICBjb25zdCBzdHlsZVR5cGUgPSAnc3RyZWV0cyc7XG4gIGNvbnN0IHRvcExheWVyR3JvdXBzID0ge307XG5cbiAgcmV0dXJuIHtcbiAgICBzdHlsZVR5cGUsXG4gICAgdmlzaWJsZUxheWVyR3JvdXBzLFxuICAgIHRvcExheWVyR3JvdXBzLFxuICAgIG1hcFN0eWxlczogREVGQVVMVF9NQVBfU1RZTEVTLnJlZHVjZSgoYWNjdSwgY3VycikgPT4gKHtcbiAgICAgIC4uLmFjY3UsXG4gICAgICBbY3Vyci5pZF06IGN1cnJcbiAgICB9KSwge30pLFxuICAgIC8vIHNhdmUgbWFwYm94IGFjY2VzcyB0b2tlblxuICAgIG1hcGJveEFwaUFjY2Vzc1Rva2VuOiBudWxsLFxuICAgIGlucHV0U3R5bGU6IGdldEluaXRpYWxJbnB1dFN0eWxlKCksXG4gICAgdGhyZWVEQnVpbGRpbmdDb2xvcjogaGV4VG9SZ2IoREVGQVVMVF9CTERHX0NPTE9SKVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IElOSVRJQUxfTUFQX1NUWUxFID0gZ2V0RGVmYXVsdFN0YXRlKCk7XG5cbi8qKlxuICogQ3JlYXRlIHR3byBtYXAgc3R5bGVzIGZyb20gcHJlc2V0IG1hcCBzdHlsZSwgb25lIGZvciB0b3AgbWFwIG9uZSBmb3IgYm90dG9tXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0eWxlVHlwZSAtIGN1cnJlbnQgbWFwIHN0eWxlXG4gKiBAcGFyYW0ge29iamVjdH0gdmlzaWJsZUxheWVyR3JvdXBzIC0gdmlzaWJsZSBsYXllcnMgb2YgYm90dG9tIG1hcFxuICogQHBhcmFtIHtvYmplY3R9IHRvcExheWVyR3JvdXBzIC0gdmlzaWJsZSBsYXllcnMgb2YgdG9wIG1hcFxuICogQHBhcmFtIHtvYmplY3R9IG1hcFN0eWxlcyAtIGEgZGljdGlvbmFyeSBvZiBhbGwgbWFwIHN0eWxlc1xuICogQHJldHVybnMge29iamVjdH0gYm90dG9tTWFwU3R5bGUgfCB0b3BNYXBTdHlsZSB8IGlzUmFzdGVyXG4gKi9cbmZ1bmN0aW9uIGdldE1hcFN0eWxlcyh7XG4gIHN0eWxlVHlwZSxcbiAgdmlzaWJsZUxheWVyR3JvdXBzLFxuICB0b3BMYXllckdyb3VwcyxcbiAgbWFwU3R5bGVzXG59KSB7XG4gIGNvbnN0IG1hcFN0eWxlID0gbWFwU3R5bGVzW3N0eWxlVHlwZV07XG5cbiAgLy8gc3R5bGUgbWlnaHQgbm90IGJlIGxvYWRlZCB5ZXRcbiAgaWYgKCFtYXBTdHlsZSB8fCAhbWFwU3R5bGUuc3R5bGUpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBjb25zdCBlZGl0YWJsZSA9IE9iamVjdC5rZXlzKHZpc2libGVMYXllckdyb3VwcykubGVuZ3RoO1xuXG4gIGNvbnN0IGJvdHRvbU1hcFN0eWxlID0gIWVkaXRhYmxlXG4gICAgPyBJbW11dGFibGUuZnJvbUpTKG1hcFN0eWxlLnN0eWxlKVxuICAgIDogZWRpdEJvdHRvbU1hcFN0eWxlKHtcbiAgICAgICAgaWQ6IHN0eWxlVHlwZSxcbiAgICAgICAgbWFwU3R5bGUsXG4gICAgICAgIHZpc2libGVMYXllckdyb3Vwc1xuICAgICAgfSk7XG5cbiAgY29uc3QgaGFzVG9wTGF5ZXIgPSBlZGl0YWJsZSAmJiBPYmplY3QudmFsdWVzKHRvcExheWVyR3JvdXBzKS5zb21lKHYgPT4gdik7XG5cbiAgLy8gbXV0ZSB0b3AgbGF5ZXIgaWYgbm90IHZpc2libGUgaW4gYm90dG9tIGxheWVyXG4gIGNvbnN0IHRvcExheWVycyA9XG4gICAgaGFzVG9wTGF5ZXIgJiZcbiAgICBPYmplY3Qua2V5cyh0b3BMYXllckdyb3VwcykucmVkdWNlKFxuICAgICAgKGFjY3UsIGtleSkgPT4gKHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgW2tleV06IHRvcExheWVyR3JvdXBzW2tleV0gJiYgdmlzaWJsZUxheWVyR3JvdXBzW2tleV1cbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuXG4gIGNvbnN0IHRvcE1hcFN0eWxlID0gaGFzVG9wTGF5ZXJcbiAgICA/IGVkaXRUb3BNYXBTdHlsZSh7XG4gICAgICAgIGlkOiBzdHlsZVR5cGUsXG4gICAgICAgIG1hcFN0eWxlLFxuICAgICAgICB2aXNpYmxlTGF5ZXJHcm91cHM6IHRvcExheWVyc1xuICAgICAgfSlcbiAgICA6IG51bGw7XG4gIGNvbnN0IHRocmVlREJ1aWxkaW5nQ29sb3IgPSBnZXQzREJ1aWxkaW5nQ29sb3IobWFwU3R5bGUpO1xuICByZXR1cm4ge2JvdHRvbU1hcFN0eWxlLCB0b3BNYXBTdHlsZSwgZWRpdGFibGUsIHRocmVlREJ1aWxkaW5nQ29sb3J9O1xufVxuXG5mdW5jdGlvbiBnZXQzREJ1aWxkaW5nQ29sb3Ioc3R5bGUpIHtcbiAgLy8gc2V0IGJ1aWxkaW5nIGNvbG9yIHRvIGJlIHRoZSBzYW1lIGFzIHRoZSBiYWNrZ3JvdW5kIGNvbG9yLlxuICBjb25zdCBiYWNrZ3JvdW5kTGF5ZXIgPSAoc3R5bGUuc3R5bGUubGF5ZXJzIHx8IFtdKS5maW5kKCh7aWR9KSA9PiBpZCA9PT0gJ2JhY2tncm91bmQnKTtcbiAgY29uc3QgYnVpbGRpbmdDb2xvciA9IGJhY2tncm91bmRMYXllciAmJiBiYWNrZ3JvdW5kTGF5ZXIucGFpbnQgJiYgYmFja2dyb3VuZExheWVyLnBhaW50WydiYWNrZ3JvdW5kLWNvbG9yJ10gP1xuICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZExheWVyLnBhaW50WydiYWNrZ3JvdW5kLWNvbG9yJ10gOiBERUZBVUxUX0JMREdfQ09MT1I7XG4gIC8vIGJyaWdodGVuIG9yIGRhcmtlbiBidWlsZGluZyBiYXNlZCBvbiBzdHlsZVxuICBjb25zdCBvcGVyYXRpb24gPSBzdHlsZS5pZC5tYXRjaCgvKD89KGRhcmt8bmlnaHQpKS8pID8gJ2JyaWdodGVyJzogICdkYXJrZXInO1xuICBjb25zdCByZ2JPYmogPSByZ2IoYnVpbGRpbmdDb2xvcilbb3BlcmF0aW9uXShbMC4yXSk7XG4gIHJldHVybiBbcmdiT2JqLnIsIHJnYk9iai5nLCByZ2JPYmouYl07XG59XG5cbmZ1bmN0aW9uIGdldExheWVyR3JvdXBzRnJvbVN0eWxlKHN0eWxlKSB7XG4gIHJldHVybiBERUZBVUxUX0xBWUVSX0dST1VQUy5maWx0ZXIobGcgPT4gc3R5bGUubGF5ZXJzLmZpbHRlcihsZy5maWx0ZXIpLmxlbmd0aCk7XG59XG5cbi8vIFVwZGF0ZXJzXG5leHBvcnQgY29uc3QgaW5pdE1hcFN0eWxlVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgLy8gc2F2ZSBtYXBib3ggYWNjZXNzIHRva2VuIHRvIG1hcCBzdHlsZSBzdGF0ZVxuICBtYXBib3hBcGlBY2Nlc3NUb2tlbjogKGFjdGlvbi5wYXlsb2FkIHx8IHt9KS5tYXBib3hBcGlBY2Nlc3NUb2tlblxufSk7XG5cbmV4cG9ydCBjb25zdCBtYXBDb25maWdDaGFuZ2VVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICAuLi5hY3Rpb24ucGF5bG9hZCxcbiAgLi4uZ2V0TWFwU3R5bGVzKHtcbiAgICAuLi5zdGF0ZSxcbiAgICAuLi5hY3Rpb24ucGF5bG9hZFxuICB9KVxufSk7XG5cbmV4cG9ydCBjb25zdCBtYXBTdHlsZUNoYW5nZVVwZGF0ZXIgPSAoc3RhdGUsIHtwYXlsb2FkOiBzdHlsZVR5cGV9KSA9PiB7XG4gIGlmICghc3RhdGUubWFwU3R5bGVzW3N0eWxlVHlwZV0pIHtcbiAgICAvLyB3ZSBtaWdodCBub3QgaGF2ZSByZWNlaXZlZCB0aGUgc3R5bGUgeWV0XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIGNvbnN0IGRlZmF1bHRMR1Zpc2liaWxpdHkgPSBnZXREZWZhdWx0TGF5ZXJHcm91cFZpc2liaWxpdHkoXG4gICAgc3RhdGUubWFwU3R5bGVzW3N0eWxlVHlwZV1cbiAgKTtcblxuICBjb25zdCB2aXNpYmxlTGF5ZXJHcm91cHMgPSBtZXJnZUxheWVyR3JvdXBWaXNpYmlsaXR5KGRlZmF1bHRMR1Zpc2liaWxpdHksIHN0YXRlLnZpc2libGVMYXllckdyb3Vwcyk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBzdHlsZVR5cGUsXG4gICAgdmlzaWJsZUxheWVyR3JvdXBzLFxuICAgIC4uLmdldE1hcFN0eWxlcyh7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIHZpc2libGVMYXllckdyb3VwcyxcbiAgICAgIHN0eWxlVHlwZVxuICAgIH0pXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgbG9hZE1hcFN0eWxlc1VwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICBjb25zdCBuZXdTdHlsZXMgPSBhY3Rpb24ucGF5bG9hZDtcblxuICAvLyBhZGQgbmV3IHN0eWxlcyB0byBzdGF0ZVxuICBjb25zdCBuZXdTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBtYXBTdHlsZXM6IHtcbiAgICAgIC4uLnN0YXRlLm1hcFN0eWxlcyxcbiAgICAgIC4uLm5ld1N0eWxlc1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gbmV3U3R5bGVzW3N0YXRlLnN0eWxlVHlwZV1cbiAgICA/IG1hcFN0eWxlQ2hhbmdlVXBkYXRlcihuZXdTdGF0ZSwge3BheWxvYWQ6IHN0YXRlLnN0eWxlVHlwZX0pXG4gICAgOiBuZXdTdGF0ZTtcbn07XG5cbi8vIGRvIG5vdGhpbmcgZm9yIG5vdywgaWYgZGlkbid0IGxvYWQsIHNraXAgaXRcbmV4cG9ydCBjb25zdCBsb2FkTWFwU3R5bGVFcnJVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHN0YXRlO1xuZXhwb3J0IGNvbnN0IHJlY2VpdmVNYXBDb25maWdVcGRhdGVyID0gKHN0YXRlLCB7cGF5bG9hZDoge21hcFN0eWxlfX0pID0+IHtcbiAgaWYgKCFtYXBTdHlsZSkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8vIGlmIHNhdmVkIGN1c3RvbSBtYXBTdHlsZXMgbG9hZCB0aGUgc3R5bGUgb2JqZWN0XG4gIGNvbnN0IGxvYWRNYXBTdHlsZVRhc2tzID0gbWFwU3R5bGUubWFwU3R5bGVzID8gW1xuICAgIFRhc2suYWxsKFxuICAgICAgT2JqZWN0LnZhbHVlcyhtYXBTdHlsZS5tYXBTdHlsZXMpXG4gICAgICAubWFwKCh7aWQsIHVybCwgYWNjZXNzVG9rZW59KSA9PiAoe1xuICAgICAgICBpZCwgdXJsOiBnZXRTdHlsZURvd25sb2FkVXJsKHVybCwgYWNjZXNzVG9rZW4gfHwgc3RhdGUubWFwYm94QXBpQWNjZXNzVG9rZW4pXG4gICAgICB9KSlcbiAgICAgIC5tYXAoTE9BRF9NQVBfU1RZTEVfVEFTSykpXG4gICAgICAuYmltYXAoXG4gICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgICAgcmVzdWx0cyA9PiAoXG4gICAgICAgICAgbG9hZE1hcFN0eWxlcyhcbiAgICAgICAgICAgIHJlc3VsdHMucmVkdWNlKChhY2N1LCB7aWQsIHN0eWxlfSkgPT4gKHtcbiAgICAgICAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgICAgICAgW2lkXToge1xuICAgICAgICAgICAgICAgIC4uLm1hcFN0eWxlLm1hcFN0eWxlc1tpZF0sXG4gICAgICAgICAgICAgICAgbGF5ZXJHcm91cHM6IGdldExheWVyR3JvdXBzRnJvbVN0eWxlKHN0eWxlKSxcbiAgICAgICAgICAgICAgICBzdHlsZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSwge30pXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICAvLyBlcnJvclxuICAgICAgICBlcnJvciA9PiBsb2FkTWFwU3R5bGVFcnIoZXJyb3IpXG4gICAgICApXG4gIF0gOiBudWxsO1xuXG4gIGNvbnN0IG5ld1N0YXRlID0gbWFwQ29uZmlnQ2hhbmdlVXBkYXRlcihzdGF0ZSwge3BheWxvYWQ6IG1hcFN0eWxlfSk7XG5cbiAgcmV0dXJuIGxvYWRNYXBTdHlsZVRhc2tzID8gd2l0aFRhc2soXG4gICAgbmV3U3RhdGUsXG4gICAgbG9hZE1hcFN0eWxlVGFza3NcbiAgKSA6IG5ld1N0YXRlO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlc2V0TWFwQ29uZmlnTWFwU3R5bGVVcGRhdGVyID0gKHN0YXRlKSA9PiB7XG4gIGNvbnN0IGVtcHR5Q29uZmlnID0ge1xuICAgIC4uLklOSVRJQUxfTUFQX1NUWUxFLFxuICAgIG1hcGJveEFwaUFjY2Vzc1Rva2VuOiBzdGF0ZS5tYXBib3hBcGlBY2Nlc3NUb2tlbixcbiAgICAuLi5zdGF0ZS5pbml0aWFsU3RhdGUsXG4gICAgbWFwU3R5bGVzOiBzdGF0ZS5tYXBTdHlsZXMsXG4gICAgaW5pdGlhbFN0YXRlOiBzdGF0ZS5pbml0aWFsU3RhdGVcbiAgfTtcblxuICByZXR1cm4gbWFwU3R5bGVDaGFuZ2VVcGRhdGVyKGVtcHR5Q29uZmlnLCB7cGF5bG9hZDogZW1wdHlDb25maWcuc3R5bGVUeXBlfSk7XG59O1xuXG5leHBvcnQgY29uc3QgbG9hZEN1c3RvbU1hcFN0eWxlVXBkYXRlciA9IChzdGF0ZSwge3BheWxvYWQ6IHtpY29uLCBzdHlsZSwgZXJyb3J9fSkgPT4gKHtcbiAgLi4uc3RhdGUsXG4gIGlucHV0U3R5bGU6IHtcbiAgICAuLi5zdGF0ZS5pbnB1dFN0eWxlLFxuICAgIC8vIHN0eWxlIGpzb24gYW5kIGljb24gd2lsbCBsb2FkIGFzeW5jaHJvbm91c2x5XG4gICAgLi4uKHN0eWxlID8ge1xuICAgICAgaWQ6IHN0eWxlLmlkIHx8IGdlbmVyYXRlSGFzaElkKCksXG4gICAgICAvLyBtYWtlIGEgY29weSBvZiB0aGUgc3R5bGUgb2JqZWN0XG4gICAgICBzdHlsZTogSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShzdHlsZSkpLFxuICAgICAgbGFiZWw6IHN0eWxlLm5hbWUsXG4gICAgICAvLyBnYXRoZXJpbmcgbGF5ZXIgZ3JvdXAgaW5mbyBmcm9tIHN0eWxlIGpzb25cbiAgICAgIGxheWVyR3JvdXBzOiBnZXRMYXllckdyb3Vwc0Zyb21TdHlsZShzdHlsZSlcbiAgICB9IDoge30pLFxuICAgIC4uLihpY29uID8ge2ljb259IDoge30pLFxuICAgIC4uLihlcnJvciAhPT0gdW5kZWZpbmVkID8ge2Vycm9yfSA6IHt9KVxuICB9XG59KTtcblxuZXhwb3J0IGNvbnN0IGlucHV0TWFwU3R5bGVVcGRhdGVyID0gKHN0YXRlLCB7cGF5bG9hZDogaW5wdXRTdHlsZX0pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBpbnB1dFN0eWxlOiB7XG4gICAgLi4uaW5wdXRTdHlsZSxcbiAgICBpc1ZhbGlkOiBpc1ZhbGlkU3R5bGVVcmwoaW5wdXRTdHlsZS51cmwpXG4gIH1cbn0pO1xuXG5leHBvcnQgY29uc3QgYWRkQ3VzdG9tTWFwU3R5bGVVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgY29uc3Qgc3R5bGVJZCA9IHN0YXRlLmlucHV0U3R5bGUuaWQ7XG4gIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIG1hcFN0eWxlczoge1xuICAgICAgLi4uc3RhdGUubWFwU3R5bGVzLFxuICAgICAgW3N0eWxlSWRdOiBzdGF0ZS5pbnB1dFN0eWxlXG4gICAgfSxcbiAgICAvLyBzZXQgdG8gZGVmYXVsdFxuICAgIGlucHV0U3R5bGU6IGdldEluaXRpYWxJbnB1dFN0eWxlKClcbiAgfTtcbiAgLy8gc2V0IG5ldyBzdHlsZVxuICByZXR1cm4gbWFwU3R5bGVDaGFuZ2VVcGRhdGVyKG5ld1N0YXRlLCB7cGF5bG9hZDogc3R5bGVJZH0pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEluaXRpYWxJbnB1dFN0eWxlKCkge1xuICByZXR1cm4ge1xuICAgIGFjY2Vzc1Rva2VuOiBudWxsLFxuICAgIGVycm9yOiBmYWxzZSxcbiAgICBpc1ZhbGlkOiBmYWxzZSxcbiAgICBsYWJlbDogbnVsbCxcbiAgICBzdHlsZTogbnVsbCxcbiAgICB1cmw6IG51bGwsXG4gICAgY3VzdG9tOiB0cnVlXG4gIH07XG59XG4iXX0=