UNPKG

kepler.gl

Version:

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

990 lines (955 loc) 137 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.VIS_STATE_MERGERS = void 0; exports.createLayerFromConfig = createLayerFromConfig; exports.insertLayerAtRightOrder = insertLayerAtRightOrder; exports.isSavedLayerConfigV1 = isSavedLayerConfigV1; exports.mergeAnimationConfig = mergeAnimationConfig; exports.mergeDatasetsByOrder = mergeDatasetsByOrder; exports.mergeEditor = mergeEditor; exports.mergeEffects = mergeEffects; exports.mergeFilters = mergeFilters; exports.mergeInteractionTooltipConfig = mergeInteractionTooltipConfig; exports.mergeInteractions = mergeInteractions; exports.mergeLayerBlending = mergeLayerBlending; exports.mergeLayers = mergeLayers; exports.mergeOverlayBlending = mergeOverlayBlending; exports.mergeSplitMaps = mergeSplitMaps; exports.parseLayerConfig = parseLayerConfig; exports.replaceFilterDatasetIds = replaceFilterDatasetIds; exports.serializeEffect = serializeEffect; exports.serializeFilter = serializeFilter; exports.serializeLayer = serializeLayer; exports.serializeVisState = serializeVisState; exports.validateColumn = validateColumn; exports.validateLayerWithData = validateLayerWithData; exports.validateLayersByDatasets = validateLayersByDatasets; exports.validateSavedLayerColumns = validateSavedLayerColumns; exports.validateSavedTextLabel = validateSavedTextLabel; exports.validateSavedVisualChannels = validateSavedVisualChannels; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = _interopRequireDefault(require("lodash.uniq")); var _lodash2 = _interopRequireDefault(require("lodash.pick")); var _lodash3 = _interopRequireDefault(require("lodash.flattendeep")); var _deepmerge = _interopRequireDefault(require("deepmerge")); var _utils = require("@kepler.gl/utils"); var _effects = require("@kepler.gl/effects"); var _commonUtils = require("@kepler.gl/common-utils"); var _constants = require("@kepler.gl/constants"); var _schemas = require("@kepler.gl/schemas"); var _table = require("@kepler.gl/table"); var _layerUtils = require("./layer-utils"); var _excluded = ["enabled"]; function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project /** * Merge loaded filters with current state, if no fields or data are loaded * save it for later * */ function mergeFilters(state, filtersToMerge, fromConfig) { var preserveFilterOrder = fromConfig ? filtersToMerge === null || filtersToMerge === void 0 ? void 0 : filtersToMerge.map(function (l) { return l.id; }) : state.preserveFilterOrder; if (!Array.isArray(filtersToMerge) || !filtersToMerge.length) { return state; } var _validateFiltersUpdat = (0, _utils.validateFiltersUpdateDatasets)(state, filtersToMerge), validated = _validateFiltersUpdat.validated, failed = _validateFiltersUpdat.failed, updatedDatasets = _validateFiltersUpdat.updatedDatasets; var updatedFilters = insertItemBasedOnPreservedOrder(state.filters, validated, preserveFilterOrder); // merge filter with existing updatedFilters = (0, _table.resetFilterGpuMode)(updatedFilters); updatedFilters = (0, _table.assignGpuChannels)(updatedFilters); // filter data var datasetsToFilter = (0, _lodash["default"])((0, _lodash3["default"])(validated.map(function (f) { return f.dataId; }))); var filtered = (0, _utils.applyFiltersToDatasets)(datasetsToFilter, updatedDatasets, updatedFilters, state.layers); return _objectSpread(_objectSpread({}, state), {}, { filters: updatedFilters, datasets: filtered, preserveFilterOrder: preserveFilterOrder, filterToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.filterToBeMerged), (0, _toConsumableArray2["default"])(failed)) }); } // replace dataId in saved Filter function replaceFilterDatasetIds(savedFilter, dataId, dataIdToUse) { var replaced = []; savedFilter.forEach(function (filter) { if (filter.dataId.includes(dataId)) { var _filter$plotType; var newDataId = filter.dataId.map(function (d) { return d === dataId ? dataIdToUse : d; }); var plotType; // TODO: more generic approach to save plotType.colorsByDataId if ((_filter$plotType = filter.plotType) !== null && _filter$plotType !== void 0 && (_filter$plotType = _filter$plotType.colorsByDataId) !== null && _filter$plotType !== void 0 && _filter$plotType[dataId]) { var _filter$plotType2; // replace colorByDataId in filter.plotType var _ref = ((_filter$plotType2 = filter.plotType) === null || _filter$plotType2 === void 0 ? void 0 : _filter$plotType2.colorsByDataId) || {}, color = _ref[dataId], rest = (0, _objectWithoutProperties2["default"])(_ref, [dataId].map(_toPropertyKey)); plotType = _objectSpread(_objectSpread({}, filter.plotType), {}, { colorsByDataId: _objectSpread(_objectSpread({}, rest), {}, (0, _defineProperty2["default"])({}, dataIdToUse, color)) }); } replaced.push(_objectSpread(_objectSpread({}, filter), {}, { dataId: newDataId }, plotType ? { plotType: plotType } : {})); } }); return replaced.length ? replaced : null; } function isSavedLayerConfigV1(layerConfig) { // exported layer configuration contains visualChannels property return layerConfig === null || layerConfig === void 0 ? void 0 : layerConfig.visualChannels; } function parseLayerConfig(schema, layerConfig) { var _schema$parseSavedCon; // assume the layer config is current version var savedConfig = { version: _schemas.CURRENT_VERSION, config: { visState: { layers: [layerConfig], layerOrder: [layerConfig.id] } } }; return (_schema$parseSavedCon = schema.parseSavedConfig(savedConfig)) === null || _schema$parseSavedCon === void 0 || (_schema$parseSavedCon = _schema$parseSavedCon.visState) === null || _schema$parseSavedCon === void 0 || (_schema$parseSavedCon = _schema$parseSavedCon.layers) === null || _schema$parseSavedCon === void 0 ? void 0 : _schema$parseSavedCon[0]; } function insertItemBasedOnPreservedOrder(currentItems, items) { var preservedOrder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var defaultStart = arguments.length > 3 ? arguments[3] : undefined; var newItems = (0, _toConsumableArray2["default"])(currentItems); var _iterator = _createForOfIteratorHelper(items), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; var expectedIdx = preservedOrder.indexOf(item.id); // insertAt the end by default var insertAt = defaultStart ? 0 : newItems.length; if (expectedIdx > 0) { // look for layer to insert after var i = expectedIdx + 1; var preceedIdx = -1; var _loop = function _loop() { // keep looking for preceed layer that is already loaded var preceedItemId = preservedOrder[i - 1]; preceedIdx = newItems.findIndex(function (d) { return d.id === preceedItemId; }); }; while (i-- > 0 && preceedIdx < 0) { _loop(); } if (preceedIdx > -1) { // if found insertAt = preceedIdx + 1; } } newItems = (0, _utils.arrayInsert)(newItems, insertAt, item); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return newItems; } function createLayerFromConfig(state, layerConfig) { // check if the layer config is parsed var parsedLayerConfig = isSavedLayerConfigV1(layerConfig) ? parseLayerConfig(state.schema, layerConfig) : layerConfig; if (!parsedLayerConfig) { return null; } // first validate config against dataset var _validateLayersByData = validateLayersByDatasets(state.datasets, state.layerClasses, [parsedLayerConfig], { allowEmptyColumn: true }), validated = _validateLayersByData.validated, failed = _validateLayersByData.failed; if (failed !== null && failed !== void 0 && failed.length || !validated.length) { // failed return null; } var newLayer = validated[0]; newLayer.updateLayerDomain(state.datasets); return newLayer; } /** * Get loaded filter from state */ function serializeFilter(newFilter, schema) { var _serializedVisState$f; var serializedVisState = serializeVisState({ filters: [newFilter] }, schema); return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$f = serializedVisState.filters) === null || _serializedVisState$f === void 0 ? void 0 : _serializedVisState$f[0]; } /** * Get loaded layer from state */ function serializeLayer(newLayer, schema) { var _serializedVisState$l; var serializedVisState = serializeVisState({ layers: [newLayer], layerOrder: [newLayer.id] }, schema); return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$l = serializedVisState.layers) === null || _serializedVisState$l === void 0 ? void 0 : _serializedVisState$l[0]; } /** * Get loaded effect from state */ function serializeEffect(newEffect, schema) { var _serializedVisState$e; var serializedVisState = serializeVisState({ effects: [newEffect], effectOrder: [newEffect.id] }, schema); return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$e = serializedVisState.effects) === null || _serializedVisState$e === void 0 ? void 0 : _serializedVisState$e[0]; } /** * Get vis state config */ function serializeVisState(visState, schema) { var _schema$parseSavedCon2; var savedState = schema.getConfigToSave({ visState: visState }); return savedState ? (_schema$parseSavedCon2 = schema.parseSavedConfig(savedState)) === null || _schema$parseSavedCon2 === void 0 ? void 0 : _schema$parseSavedCon2.visState : undefined; } /** * Merge layers from de-serialized state, if no fields or data are loaded * save it for later * */ function mergeLayers(state) { var layersToMerge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var fromConfig = arguments.length > 2 ? arguments[2] : undefined; var preserveLayerOrder = fromConfig ? (0, _layerUtils.getLayerOrderFromLayers)(layersToMerge) : state.preserveLayerOrder; if (!Array.isArray(layersToMerge) || !layersToMerge.length) { return state; } // don't merge layer if dataset is being merged var unmerged = []; var toMerge = []; layersToMerge.forEach(function (l) { var _l$config; if (l !== null && l !== void 0 && (_l$config = l.config) !== null && _l$config !== void 0 && _l$config.dataId && state.isMergingDatasets[l.config.dataId]) { unmerged.push(l); } else { toMerge.push(l); } }); var _validateLayersByData2 = validateLayersByDatasets(state.datasets, state.layerClasses, toMerge), mergedLayer = _validateLayersByData2.validated, failed = _validateLayersByData2.failed; unmerged.push.apply(unmerged, (0, _toConsumableArray2["default"])(failed)); // put new layers in front of current layers var _insertLayerAtRightOr = insertLayerAtRightOrder(state.layers, mergedLayer, state.layerOrder, preserveLayerOrder), newLayerOrder = _insertLayerAtRightOr.newLayerOrder, newLayers = _insertLayerAtRightOr.newLayers; return _objectSpread(_objectSpread({}, state), {}, { layers: newLayers, layerOrder: newLayerOrder, preserveLayerOrder: preserveLayerOrder, layerToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.layerToBeMerged), unmerged) }); } function insertLayerAtRightOrder(currentLayers, layersToInsert, currentOrder) { var preservedOrder = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; if (!(layersToInsert !== null && layersToInsert !== void 0 && layersToInsert.length)) { return { newLayers: currentLayers, newLayerOrder: currentOrder }; } // perservedOrder ['a', 'b', 'c']; // layerOrder ['a', 'b', 'c'] var currentLayerQueue = currentOrder.map(function (id) { return (0, _utils.findById)(id)(currentLayers); }).filter(function (layer) { return Boolean(layer); }); var newLayers = currentLayers.concat(layersToInsert); var newLayerOrderQueue = insertItemBasedOnPreservedOrder(currentLayerQueue, layersToInsert, preservedOrder, true); // reconstruct layerOrder after insert var newLayerOrder = (0, _layerUtils.getLayerOrderFromLayers)(newLayerOrderQueue); return { newLayerOrder: newLayerOrder, newLayers: newLayers }; } /** * Merge interactions with saved config * */ function mergeInteractions(state, interactionToBeMerged) { var merged = {}; var unmerged = {}; if (interactionToBeMerged) { Object.keys(interactionToBeMerged).forEach(function (key) { if (!state.interactionConfig[key]) { return; } var currentConfig = key === 'tooltip' || key === 'brush' ? state.interactionConfig[key].config : null; var _ref2 = interactionToBeMerged[key] || {}, enabled = _ref2.enabled, configSaved = (0, _objectWithoutProperties2["default"])(_ref2, _excluded); var configToMerge = configSaved; if (key === 'tooltip') { var _mergeInteractionTool = mergeInteractionTooltipConfig(state, configSaved), mergedTooltip = _mergeInteractionTool.mergedTooltip, unmergedTooltip = _mergeInteractionTool.unmergedTooltip; // merge new dataset tooltips with original dataset tooltips configToMerge = { fieldsToShow: _objectSpread(_objectSpread({}, currentConfig.fieldsToShow), mergedTooltip) }; if (Object.keys(unmergedTooltip).length) { // @ts-expect-error unmerged.tooltip = { fieldsToShow: unmergedTooltip, enabled: Boolean(enabled) }; } } merged[key] = _objectSpread(_objectSpread({}, state.interactionConfig[key]), {}, { enabled: Boolean(enabled) }, currentConfig ? { config: (0, _lodash2["default"])(_objectSpread(_objectSpread({}, currentConfig), configToMerge), Object.keys(currentConfig)) } : {}); }); } var nextState = _objectSpread(_objectSpread({}, state), {}, { interactionConfig: _objectSpread(_objectSpread({}, state.interactionConfig), merged), interactionToBeMerged: savedUnmergedInteraction(state, unmerged) }); return nextState; } function combineInteractionConfigs(configs) { var combined = _objectSpread({}, configs[0]); // handle each property key of an `InteractionConfig`, e.g. tooltip, geocoder, brush, coordinate // by combining values for each among all passed in configs var _loop2 = function _loop2(key) { var toBeCombinedProps = configs.map(function (c) { return c[key]; }); // all of these have an enabled boolean combined[key] = { // are any of the configs' enabled values true? enabled: toBeCombinedProps.some(function (p) { return p === null || p === void 0 ? void 0 : p.enabled; }) }; if (key === 'tooltip') { // are any of the configs' compareMode values true? combined[key].compareMode = toBeCombinedProps.some(function (p) { return p === null || p === void 0 ? void 0 : p.compareMode; }); // return the compare type mode, it will be either absolute or relative combined[key].compareType = getValueWithHighestOccurrence(toBeCombinedProps.map(function (p) { return p.compareType; })); // combine fieldsToShow among all dataset ids combined[key].fieldsToShow = toBeCombinedProps.map(function (p) { return p.fieldsToShow; }).reduce(function (acc, nextFieldsToShow) { var _loop3 = function _loop3(nextDataIdKey) { var nextTooltipFields = nextFieldsToShow[nextDataIdKey]; if (!acc[nextDataIdKey]) { // if the dataset id is not present in the accumulator // then add it with its tooltip fields acc[nextDataIdKey] = nextTooltipFields; } else { // otherwise the dataset id is already present in the accumulator // so only add the next tooltip fields for this dataset's array if they are not already present, // using the tooltipField.name property for uniqueness nextTooltipFields.forEach(function (nextTF) { if (!acc[nextDataIdKey].find(function (_ref3) { var name = _ref3.name; return nextTF.name === name; })) { acc[nextDataIdKey].push(nextTF); } }); } }; for (var nextDataIdKey in nextFieldsToShow) { _loop3(nextDataIdKey); } return acc; }, {}); } if (key === 'brush') { var _aggregate; // keep the biggest brush size combined[key].size = (_aggregate = (0, _utils.aggregate)(toBeCombinedProps, _constants.AGGREGATION_TYPES.maximum, function (p) { return p.size; })) !== null && _aggregate !== void 0 ? _aggregate : null; } }; for (var key in combined) { _loop2(key); } return combined; } function savedUnmergedInteraction(state, unmerged) { var _unmerged$tooltip, _unmerged$tooltip2, _state$interactionToB, _unmerged$tooltip3; if (!(unmerged !== null && unmerged !== void 0 && (_unmerged$tooltip = unmerged.tooltip) !== null && _unmerged$tooltip !== void 0 && _unmerged$tooltip.fieldsToShow)) { return state.interactionToBeMerged; } return { tooltip: _objectSpread(_objectSpread(_objectSpread({}, state.interactionToBeMerged.tooltip), typeof (unmerged === null || unmerged === void 0 || (_unmerged$tooltip2 = unmerged.tooltip) === null || _unmerged$tooltip2 === void 0 ? void 0 : _unmerged$tooltip2.enabled) === 'boolean' ? { enabled: unmerged.tooltip.enabled } : {}), {}, { fieldsToShow: _objectSpread(_objectSpread({}, (_state$interactionToB = state.interactionToBeMerged) === null || _state$interactionToB === void 0 || (_state$interactionToB = _state$interactionToB.tooltip) === null || _state$interactionToB === void 0 ? void 0 : _state$interactionToB.fieldsToShow), unmerged === null || unmerged === void 0 || (_unmerged$tooltip3 = unmerged.tooltip) === null || _unmerged$tooltip3 === void 0 ? void 0 : _unmerged$tooltip3.fieldsToShow) }) }; } function replaceInteractionDatasetIds(interactionConfig, dataId, dataIdToReplace) { var _interactionConfig$to; if (interactionConfig !== null && interactionConfig !== void 0 && (_interactionConfig$to = interactionConfig.tooltip) !== null && _interactionConfig$to !== void 0 && _interactionConfig$to.fieldsToShow[dataId]) { var _interactionConfig$to2; return _objectSpread(_objectSpread({}, interactionConfig), {}, { tooltip: _objectSpread(_objectSpread({}, interactionConfig.tooltip), {}, { fieldsToShow: (0, _defineProperty2["default"])({}, dataIdToReplace, interactionConfig === null || interactionConfig === void 0 || (_interactionConfig$to2 = interactionConfig.tooltip) === null || _interactionConfig$to2 === void 0 ? void 0 : _interactionConfig$to2.fieldsToShow[dataId]) }) }); } return null; } /** * Merge splitMaps config with current visStete. * 1. if current map is split, but splitMap DOESNOT contain maps * : don't merge anything * 2. if current map is NOT split, but splitMaps contain maps * : add to splitMaps, and add current layers to splitMaps */ function mergeSplitMaps(state) { var splitMaps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var merged = (0, _toConsumableArray2["default"])(state.splitMaps); var unmerged = []; splitMaps.forEach(function (sm, i) { var entries = Object.entries(sm.layers); if (entries.length > 0) { entries.forEach(function (_ref4) { var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2), id = _ref5[0], value = _ref5[1]; // check if layer exists var pushTo = state.layers.find(function (l) { return l.id === id; }) ? merged : unmerged; // create map panel if current map is not split pushTo[i] = pushTo[i] || _objectSpread(_objectSpread({}, sm), {}, { layers: pushTo === merged ? (0, _utils.getInitialMapLayersForSplitMap)(state.layers) : [] }); pushTo[i].layers = _objectSpread(_objectSpread({}, pushTo[i].layers), {}, (0, _defineProperty2["default"])({}, id, value)); }); } else { // We are merging if there are no layers in both split map merged.push(sm); } }); return _objectSpread(_objectSpread({}, state), {}, { splitMaps: merged, splitMapsToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.splitMapsToBeMerged), unmerged) }); } /** * Merge effects with saved config */ function mergeEffects(state, effects, fromConfig) { var newEffects = [].concat((0, _toConsumableArray2["default"])(state.effects), (0, _toConsumableArray2["default"])((effects || []).map(function (effect) { return fromConfig ? (0, _effects.createEffect)(_deepmerge["default"].all([effect, { // collapse all panels when loading effects isConfigActive: false }])) : effect; }).filter(function (effect) { return Boolean(effect && effect.isValidToSave()); }))); return _objectSpread(_objectSpread({}, state), {}, { effects: newEffects, effectOrder: newEffects.map(function (effect) { return effect.id; }) }); } /** * Merge interactionConfig.tooltip with saved config, * validate fieldsToShow * * @param state * @param tooltipConfig * @return - {mergedTooltip: {}, unmergedTooltip: {}} */ function mergeInteractionTooltipConfig(state) { var tooltipConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var unmergedTooltip = {}; var mergedTooltip = {}; if (!tooltipConfig || !tooltipConfig.fieldsToShow || !Object.keys(tooltipConfig.fieldsToShow).length) { return { mergedTooltip: mergedTooltip, unmergedTooltip: unmergedTooltip }; } var _loop4 = function _loop4() { if (!state.datasets[dataId] || state.isMergingDatasets[dataId]) { // is not yet loaded unmergedTooltip[dataId] = tooltipConfig.fieldsToShow[dataId]; } else { // if dataset is loaded var allFields = state.datasets[dataId].fields.map(function (d) { return d.name; }); var foundFieldsToShow = tooltipConfig.fieldsToShow[dataId].filter(function (field) { return allFields.includes(field.name); }); mergedTooltip[dataId] = foundFieldsToShow; } }; for (var dataId in tooltipConfig.fieldsToShow) { _loop4(); } return { mergedTooltip: mergedTooltip, unmergedTooltip: unmergedTooltip }; } /** * Merge layerBlending with saved * */ function mergeLayerBlending(state, layerBlending) { if (layerBlending && _constants.LAYER_BLENDINGS[layerBlending]) { return _objectSpread(_objectSpread({}, state), {}, { layerBlending: layerBlending }); } return state; } /** * Combines multiple layer blending configs into a single string * by returning the one with the highest occurrence */ function combineLayerBlendingConfigs(configs) { // return the mode of the layer blending type return getValueWithHighestOccurrence(configs); } /** * Merge overlayBlending with saved */ function mergeOverlayBlending(state, overlayBlending) { if (overlayBlending && _constants.OVERLAY_BLENDINGS[overlayBlending]) { return _objectSpread(_objectSpread({}, state), {}, { overlayBlending: overlayBlending }); } return state; } /** * Combines multiple overlay blending configs into a single string * by returning the one with the highest occurrence **/ function combineOverlayBlendingConfigs(configs) { // return the mode of the overlay blending type return getValueWithHighestOccurrence(configs); } /** * Merge animation config */ function mergeAnimationConfig(state, animation) { if (animation && animation.currentTime) { return _objectSpread(_objectSpread({}, state), {}, { animationConfig: _objectSpread(_objectSpread(_objectSpread({}, state.animationConfig), animation), {}, { domain: null }) }); } return state; } function combineAnimationConfigs(configs) { var _aggregate2, _aggregate3; // get the smallest values of currentTime and speed among all configs return { currentTime: (_aggregate2 = (0, _utils.aggregate)(configs, _constants.AGGREGATION_TYPES.minimum, function (c) { return c.currentTime; })) !== null && _aggregate2 !== void 0 ? _aggregate2 : null, speed: (_aggregate3 = (0, _utils.aggregate)(configs, _constants.AGGREGATION_TYPES.minimum, function (c) { return c.speed; })) !== null && _aggregate3 !== void 0 ? _aggregate3 : null }; } /** * Validate saved layer columns with new data, * update fieldIdx based on new fields * * @param fields * @param savedCols * @param emptyCols * @param options * @return - validated columns or null */ function validateSavedLayerColumns(fields) { var savedCols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var emptyCols = arguments.length > 2 ? arguments[2] : undefined; var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; // Prepare columns for the validator var columns = {}; var _loop5 = function _loop5() { var key = _Object$keys[_i]; columns[key] = _objectSpread({}, emptyCols[key]); var saved = savedCols[key]; if (saved) { var fieldIdx = fields.findIndex(function (_ref6) { var name = _ref6.name; return name === saved; }); if (fieldIdx > -1) { // update found columns columns[key].fieldIdx = fieldIdx; columns[key].value = saved; } } }; for (var _i = 0, _Object$keys = Object.keys(emptyCols); _i < _Object$keys.length; _i++) { _loop5(); } // find actual column fieldIdx, in case it has changed var allColFound = Object.keys(columns).every(function (key) { return validateColumn(columns[key], columns, fields); }); var rv = allColFound ? columns : null; if (options.throwOnError) { var requiredColumns = Object.keys(emptyCols).filter(function (k) { return !emptyCols[k].optional; }); var missingColumns = requiredColumns.filter(function (k) { return !(columns !== null && columns !== void 0 && columns[k].value); }); if (missingColumns.length) { throw new Error("Layer has missing or invalid columns: ".concat(missingColumns.join(', '))); } var configColumns = Object.keys(savedCols); var invalidColumns = configColumns.filter(function (k) { var _columns$k; return !(columns !== null && columns !== void 0 && (_columns$k = columns[k]) !== null && _columns$k !== void 0 && _columns$k.value); }); if (invalidColumns.length) { throw new Error("Layer has invalid columns: ".concat(invalidColumns.join(', '))); } } return rv; } /** * Validate layer column */ function validateColumn(column, columns, allFields) { if (column.optional || column.value) { return true; } if (column.validator) { return column.validator(column, columns, allFields); } return false; } /** * Validate saved text label config with new data * refer to vis-state-schema.js TextLabelSchemaV1 * * @param {Array<Object>} fields * @param {Object} savedTextLabel * @param {Object} options * @return {Object} - validated textlabel */ function validateSavedTextLabel(fields, _ref7, savedTextLabel) { var _ref8 = (0, _slicedToArray2["default"])(_ref7, 1), layerTextLabel = _ref8[0]; var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var savedTextLabels = Array.isArray(savedTextLabel) ? savedTextLabel : [savedTextLabel]; // validate field return savedTextLabels.map(function (textLabel) { var field = textLabel.field ? fields.find(function (fd) { return Object.keys(textLabel.field).every(function (key) { return textLabel.field[key] === fd[key]; }); }) : null; if (field === undefined && options.throwOnError) { throw new Error("Layer has invalid text label field: ".concat(JSON.stringify(textLabel.field))); } return Object.keys(layerTextLabel).reduce(function (accu, key) { return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, key === 'field' ? field : textLabel[key] || layerTextLabel[key])); }, {}); }); } /** * Validate saved visual channels config with new data, * refer to vis-state-schema.js VisualChannelSchemaV1 */ function validateSavedVisualChannels(fields, newLayer, savedLayer) { var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; Object.values(newLayer.visualChannels).forEach(function (_ref9) { var field = _ref9.field, scale = _ref9.scale, key = _ref9.key; var foundField; if (savedLayer.config) { if (savedLayer.config[field]) { foundField = fields.find(function (fd) { return savedLayer.config && fd.name === savedLayer.config[field].name; }); } var foundChannel = _objectSpread(_objectSpread({}, foundField ? (0, _defineProperty2["default"])({}, field, foundField) : {}), savedLayer.config[scale] ? (0, _defineProperty2["default"])({}, scale, savedLayer.config[scale]) : {}); if (Object.keys(foundChannel).length) { newLayer.updateLayerConfig(foundChannel); } newLayer.validateVisualChannel(key); if (options.throwOnError) { var _savedLayer$config, _newLayer$config$fiel; var fieldName = (_savedLayer$config = savedLayer.config) === null || _savedLayer$config === void 0 || (_savedLayer$config = _savedLayer$config[field]) === null || _savedLayer$config === void 0 ? void 0 : _savedLayer$config.name; if (fieldName && fieldName !== ((_newLayer$config$fiel = newLayer.config[field]) === null || _newLayer$config$fiel === void 0 ? void 0 : _newLayer$config$fiel.name)) { throw new Error("Layer has invalid visual channel field: ".concat(field)); } } } }); return newLayer; } function validateLayersByDatasets(datasets, layerClasses) { var layers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var options = arguments.length > 3 ? arguments[3] : undefined; var validated = []; var failed = []; layers.forEach(function (layer) { var _layer$config; var validateLayer = null; if (layer !== null && layer !== void 0 && (_layer$config = layer.config) !== null && _layer$config !== void 0 && _layer$config.dataId) { if (datasets[layer.config.dataId]) { // datasets are already loaded validateLayer = validateLayerWithData(datasets[layer.config.dataId], layer, layerClasses, options); } } if (validateLayer) { validated.push(validateLayer); } else { // datasets not yet loaded failed.push(layer); } }); return { validated: validated, failed: failed }; } /** * Get required columns for validation based on column mode */ function _getColumnConfigForValidation(newLayer) { // find column fieldIdx var columnConfig = newLayer.getLayerColumns(); // if columnMode is defined, find column mode config var colModeConfig = newLayer.config.columnMode ? (newLayer.supportedColumnModes || []).find(function (colMode) { return colMode.key === newLayer.config.columnMode; }) : null; if (colModeConfig) { // only validate columns in column mode columnConfig = [].concat((0, _toConsumableArray2["default"])(colModeConfig.requiredColumns || []), (0, _toConsumableArray2["default"])(colModeConfig.optionalColumns || [])).reduce(function (accu, key) { return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, columnConfig[key])); }, {}); } return columnConfig; } /** * Validate saved layer config with new data, * update fieldIdx based on new fields */ // eslint-disable-next-line complexity function validateLayerWithData(dataset, savedLayer, layerClasses) { var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var fields = dataset.fields, dataId = dataset.id; var type = savedLayer.type; var throwOnError = options.throwOnError; // layer doesnt have a valid type if (!type || !Object.prototype.hasOwnProperty.call(layerClasses, type) || !savedLayer.config) { if (throwOnError) { throw new Error("Layer has invalid type \"".concat(type, "\" or config is missing")); } return null; } var newLayer = new layerClasses[type]({ id: savedLayer.id, dataId: dataId, label: savedLayer.config.label, color: savedLayer.config.color, isVisible: savedLayer.config.isVisible, hidden: savedLayer.config.hidden, columnMode: savedLayer.config.columnMode, highlightColor: savedLayer.config.highlightColor }); var columnConfig = _getColumnConfigForValidation(newLayer); if (Object.keys(columnConfig)) { var columns = validateSavedLayerColumns(fields, savedLayer.config.columns, columnConfig, options); if (columns) { newLayer.updateLayerConfig({ columns: _objectSpread(_objectSpread({}, newLayer.config.columns), columns) }); } else if (!options.allowEmptyColumn) { return null; } } var textLabel = savedLayer.config.textLabel && newLayer.config.textLabel ? validateSavedTextLabel(fields, newLayer.config.textLabel, savedLayer.config.textLabel, options) : newLayer.config.textLabel; // copy visConfig over to emptyLayer to make sure it has all the props var copiedVisConfig = newLayer.copyLayerConfig(newLayer.config.visConfig, savedLayer.config.visConfig || {}, { shallowCopy: ['colorRange', 'strokeColorRange'] }); // call layer methods to validate visConfig when switching dataset var visConfig = newLayer.validateVisConfig ? newLayer.validateVisConfig(dataset, copiedVisConfig) : copiedVisConfig; newLayer.updateLayerConfig({ visConfig: visConfig, textLabel: textLabel }); // visual channel field is saved to be {name, type} // find visual channel field by matching both name and type // refer to vis-state-schema.js VisualChannelSchemaV1 newLayer = validateSavedVisualChannels(fields, newLayer, savedLayer, options); if (throwOnError) { if (!newLayer.isValidToSave()) { throw new Error("Layer is not valid to save: ".concat(newLayer.id)); } } return newLayer; } function mergeEditor(state, savedEditor) { var _savedEditor$visible; if (!savedEditor) { return state; } return _objectSpread(_objectSpread({}, state), {}, { editor: _objectSpread(_objectSpread({}, state.editor), {}, { features: [].concat((0, _toConsumableArray2["default"])(state.editor.features), (0, _toConsumableArray2["default"])(savedEditor.features || [])), // if savedEditor.visible is undefined keep state.editor.visible visible: (_savedEditor$visible = savedEditor.visible) !== null && _savedEditor$visible !== void 0 ? _savedEditor$visible : state.editor.visible }) }); } function combineEditorConfigs(configs) { return configs.reduce(function (acc, nextConfig) { return _objectSpread(_objectSpread({}, acc), {}, { features: [].concat((0, _toConsumableArray2["default"])(acc.features), (0, _toConsumableArray2["default"])(nextConfig.features || [])) }); }, { // start with: // - empty array for features accumulation // - and are any of the configs' visible values true? features: [], visible: configs.some(function (c) { return c === null || c === void 0 ? void 0 : c.visible; }) }); } /** * Validate saved layer config with new data, * update fieldIdx based on new fields */ function mergeDatasetsByOrder(state, newDataEntries) { var merged = _objectSpread(_objectSpread({}, state.datasets), newDataEntries); if (Array.isArray(state.preserveDatasetOrder)) { // preserveDatasetOrder might not include the new datasets var newDatasetIds = Object.keys(merged).filter(function (id) { var _state$preserveDatase; return !((_state$preserveDatase = state.preserveDatasetOrder) !== null && _state$preserveDatase !== void 0 && _state$preserveDatase.includes(id)); }); return [].concat((0, _toConsumableArray2["default"])(state.preserveDatasetOrder), (0, _toConsumableArray2["default"])(newDatasetIds)).reduce(function (accu, dataId) { return _objectSpread(_objectSpread({}, accu), merged[dataId] ? (0, _defineProperty2["default"])({}, dataId, merged[dataId]) : {}); }, {}); } return merged; } /** * Simliar purpose to aggregation utils `getMode` function, * but returns the mode in the same value type without coercing to a string. * It ignores `undefined` or `null` values, but returns `null` if no mode could be calculated. */ function getValueWithHighestOccurrence(arr) { var _ref13; var tallys = new Map(); arr.forEach(function (value) { if ((0, _commonUtils.notNullorUndefined)(value)) { if (!tallys.has(value)) { tallys.set(value, 1); } else { tallys.set(value, tallys.get(value) + 1); } } }); // return the value with the highest total occurrence count if (tallys.size === 0) { return null; } return (_ref13 = (0, _toConsumableArray2["default"])(tallys.entries())) === null || _ref13 === void 0 ? void 0 : _ref13.reduce(function (acc, next) { return next[1] > acc[1] ? next : acc; })[0]; } var VIS_STATE_MERGERS = exports.VIS_STATE_MERGERS = [{ merge: mergeLayers, prop: 'layers', toMergeProp: 'layerToBeMerged', preserveOrder: 'preserveLayerOrder' }, { merge: mergeFilters, prop: 'filters', toMergeProp: 'filterToBeMerged', preserveOrder: 'preserveFilterOrder', replaceParentDatasetIds: replaceFilterDatasetIds }, { merge: mergeEffects, prop: 'effects' }, { merge: mergeInteractions, prop: 'interactionConfig', toMergeProp: 'interactionToBeMerged', replaceParentDatasetIds: replaceInteractionDatasetIds, saveUnmerged: savedUnmergedInteraction, combineConfigs: combineInteractionConfigs }, { merge: mergeLayerBlending, prop: 'layerBlending', combineConfigs: combineLayerBlendingConfigs }, { merge: mergeOverlayBlending, prop: 'overlayBlending', combineConfigs: combineOverlayBlendingConfigs }, { merge: mergeSplitMaps, prop: 'splitMaps', toMergeProp: 'splitMapsToBeMerged' }, { merge: mergeAnimationConfig, prop: 'animationConfig', combineConfigs: combineAnimationConfigs }, { merge: mergeEditor, prop: 'editor', combineConfigs: combineEditorConfigs }]; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfbG9kYXNoMiIsIl9sb2Rhc2gzIiwiX2RlZXBtZXJnZSIsIl91dGlscyIsIl9lZmZlY3RzIiwiX2NvbW1vblV0aWxzIiwiX2NvbnN0YW50cyIsIl9zY2hlbWFzIiwiX3RhYmxlIiwiX2xheWVyVXRpbHMiLCJfZXhjbHVkZWQiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsInIiLCJlIiwidCIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiQXJyYXkiLCJpc0FycmF5IiwiX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IiwibGVuZ3RoIiwiX24iLCJGIiwicyIsIm4iLCJkb25lIiwidmFsdWUiLCJmIiwiVHlwZUVycm9yIiwibyIsImEiLCJ1IiwiY2FsbCIsIm5leHQiLCJfYXJyYXlMaWtlVG9BcnJheSIsInRvU3RyaW5nIiwic2xpY2UiLCJjb25zdHJ1Y3RvciIsIm5hbWUiLCJmcm9tIiwidGVzdCIsIl90b1Byb3BlcnR5S2V5IiwiaSIsIl90b1ByaW1pdGl2ZSIsIl90eXBlb2YiLCJ0b1ByaW1pdGl2ZSIsIlN0cmluZyIsIk51bWJlciIsIm93bktleXMiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJtZXJnZUZpbHRlcnMiLCJzdGF0ZSIsImZpbHRlcnNUb01lcmdlIiwiZnJvbUNvbmZpZyIsInByZXNlcnZlRmlsdGVyT3JkZXIiLCJtYXAiLCJsIiwiaWQiLCJfdmFsaWRhdGVGaWx0ZXJzVXBkYXQiLCJ2YWxpZGF0ZUZpbHRlcnNVcGRhdGVEYXRhc2V0cyIsInZhbGlkYXRlZCIsImZhaWxlZCIsInVwZGF0ZWREYXRhc2V0cyIsInVwZGF0ZWRGaWx0ZXJzIiwiaW5zZXJ0SXRlbUJhc2VkT25QcmVzZXJ2ZWRPcmRlciIsImZpbHRlcnMiLCJyZXNldEZpbHRlckdwdU1vZGUiLCJhc3NpZ25HcHVDaGFubmVscyIsImRhdGFzZXRzVG9GaWx0ZXIiLCJ1bmlxIiwiZmxhdHRlbkRlZXAiLCJkYXRhSWQiLCJmaWx0ZXJlZCIsImFwcGx5RmlsdGVyc1RvRGF0YXNldHMiLCJsYXllcnMiLCJkYXRhc2V0cyIsImZpbHRlclRvQmVNZXJnZWQiLCJjb25jYXQiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwicmVwbGFjZUZpbHRlckRhdGFzZXRJZHMiLCJzYXZlZEZpbHRlciIsImRhdGFJZFRvVXNlIiwicmVwbGFjZWQiLCJpbmNsdWRlcyIsIl9maWx0ZXIkcGxvdFR5cGUiLCJuZXdEYXRhSWQiLCJkIiwicGxvdFR5cGUiLCJjb2xvcnNCeURhdGFJZCIsIl9maWx0ZXIkcGxvdFR5cGUyIiwiX3JlZiIsImNvbG9yIiwicmVzdCIsIl9vYmplY3RXaXRob3V0UHJvcGVydGllczIiLCJpc1NhdmVkTGF5ZXJDb25maWdWMSIsImxheWVyQ29uZmlnIiwidmlzdWFsQ2hhbm5lbHMiLCJwYXJzZUxheWVyQ29uZmlnIiwic2NoZW1hIiwiX3NjaGVtYSRwYXJzZVNhdmVkQ29uIiwic2F2ZWRDb25maWciLCJ2ZXJzaW9uIiwiQ1VSUkVOVF9WRVJTSU9OIiwiY29uZmlnIiwidmlzU3RhdGUiLCJsYXllck9yZGVyIiwicGFyc2VTYXZlZENvbmZpZyIsImN1cnJlbnRJdGVtcyIsIml0ZW1zIiwicHJlc2VydmVkT3JkZXIiLCJ1bmRlZmluZWQiLCJkZWZhdWx0U3RhcnQiLCJuZXdJdGVtcyIsIl9pdGVyYXRvciIsIl9zdGVwIiwiaXRlbSIsImV4cGVjdGVkSWR4IiwiaW5kZXhPZiIsImluc2VydEF0IiwicHJlY2VlZElkeCIsIl9sb29wIiwicHJlY2VlZEl0ZW1JZCIsImZpbmRJbmRleCIsImFycmF5SW5zZXJ0IiwiZXJyIiwiY3JlYXRlTGF5ZXJGcm9tQ29uZmlnIiwicGFyc2VkTGF5ZXJDb25maWciLCJfdmFsaWRhdGVMYXllcnNCeURhdGEiLCJ2YWxpZGF0ZUxheWVyc0J5RGF0YXNldHMiLCJsYXllckNsYXNzZXMiLCJhbGxvd0VtcHR5Q29sdW1uIiwibmV3TGF5ZXIiLCJ1cGRhdGVMYXllckRvbWFpbiIsInNlcmlhbGl6ZUZpbHRlciIsIm5ld0ZpbHRlciIsIl9zZXJpYWxpemVkVmlzU3RhdGUkZiIsInNlcmlhbGl6ZWRWaXNTdGF0ZSIsInNlcmlhbGl6ZVZpc1N0YXRlIiwic2VyaWFsaXplTGF5ZXIiLCJfc2VyaWFsaXplZFZpc1N0YXRlJGwiLCJzZXJpYWxpemVFZmZlY3QiLCJuZXdFZmZlY3QiLCJfc2VyaWFsaXplZFZpc1N0YXRlJGUiLCJlZmZlY3RzIiwiZWZmZWN0T3JkZXIiLCJfc2NoZW1hJHBhcnNlU2F2ZWRDb24yIiwic2F2ZWRTdGF0ZSIsImdldENvbmZpZ1RvU2F2ZSIsIm1lcmdlTGF5ZXJzIiwibGF5ZXJzVG9NZXJnZSIsInByZXNlcnZlTGF5ZXJPcmRlciIsImdldExheWVyT3JkZXJGcm9tTGF5ZXJzIiwidW5tZXJnZWQiLCJ0b01lcmdlIiwiX2wkY29uZmlnIiwiaXNNZXJnaW5nRGF0YXNldHMiLCJfdmFsaWRhdGVMYXllcnNCeURhdGEyIiwibWVyZ2VkTGF5ZXIiLCJfaW5zZXJ0TGF5ZXJBdFJpZ2h0T3IiLCJpbnNlcnRMYXllckF0UmlnaHRPcmRlciIsIm5ld0xheWVyT3JkZXIiLCJuZXdMYXllcnMiLCJsYXllclRvQmVNZXJnZWQiLCJjdXJyZW50TGF5ZXJzIiwibGF5ZXJzVG9JbnNlcnQiLCJjdXJyZW50T3JkZXIiLCJjdXJyZW50TGF5ZXJRdWV1ZSIsImZpbmRCeUlkIiwibGF5ZXIiLCJCb29sZWFuIiwibmV3TGF5ZXJPcmRlclF1ZXVlIiwibWVyZ2VJbnRlcmFjdGlvbnMiLCJpbnRlcmFjdGlvblRvQmVNZXJnZWQiLCJtZXJnZWQiLCJrZXkiLCJpbnRlcmFjdGlvbkNvbmZpZyIsImN1cnJlbnRDb25maWciLCJfcmVmMiIsImVuYWJsZWQiLCJjb25maWdTYXZlZCIsImNvbmZpZ1RvTWVyZ2UiLCJfbWVyZ2VJbnRlcmFjdGlvblRvb2wiLCJtZXJnZUludGVyYWN0aW9uVG9vbHRpcENvbmZpZyIsIm1lcmdlZFRvb2x0aXAiLCJ1bm1lcmdlZFRvb2x0aXAiLCJmaWVsZHNUb1Nob3ciLCJ0b29sdGlwIiwicGljayIsIm5leHRTdGF0ZSIsInNhdmVkVW5tZXJnZWRJbnRlcmFjdGlvbiIsImNvbWJpbmVJbnRlcmFjdGlvbkNvbmZpZ3MiLCJjb25maWdzIiwiY29tYmluZWQiLCJfbG9vcDIiLCJ0b0JlQ29tYmluZWRQcm9wcyIsImMiLCJzb21lIiwicCIsImNvbXBhcmVNb2RlIiwiY29tcGFyZVR5cGUiLCJnZXRWYWx1ZVdpdGhIaWdoZXN0T2NjdXJyZW5jZSIsInJlZHVjZSIsImFjYyIsIm5leHRGaWVsZHNUb1Nob3ciLCJfbG9vcDMiLCJuZXh0RGF0YUlkS2V5IiwibmV4dFRvb2x0aXBGaWVsZHMiLCJuZXh0VEYiLCJmaW5kIiwiX3JlZjMiLCJfYWdncmVnYXRlIiwic2l6ZSIsImFnZ3JlZ2F0ZSIsIkFHR1JFR0FUSU9OX1RZUEVTIiwibWF4aW11bSIsIl91bm1lcmdlZCR0b29sdGlwIiwiX3VubWVyZ2VkJHRvb2x0aXAyIiwiX3N0YXRlJGludGVyYWN0aW9uVG9CIiwiX3VubWVyZ2VkJHRvb2x0aXAzIiwicmVwbGFjZUludGVyYWN0aW9uRGF0YXNldElkcyIsImRhdGFJZFRvUmVwbGFjZSIsIl9pbnRlcmFjdGlvbkNvbmZpZyR0byIsIl9pbnRlcmFjdGlvbkNvbmZpZyR0bzIiLCJtZXJnZVNwbGl0TWFwcyIsInNwbGl0TWFwcyIsInNtIiwiZW50cmllcyIsIl9yZWY0IiwiX3JlZjUiLCJfc2xpY2VkVG9BcnJheTIiLCJwdXNoVG8iLCJnZXRJbml0aWFsTWFwTGF5ZXJzRm9yU3BsaXRNYXAiLCJzcGxpdE1hcHNUb0JlTWVyZ2VkIiwibWVyZ2VFZmZlY3RzIiwibmV3RWZmZWN0cyIsImVmZmVjdCIsImNyZWF0ZUVmZmVjdCIsImRlZXBtZXJnZSIsImFsbCIsImlzQ29uZmlnQWN0aXZlIiwiaXNWYWxpZFRvU2F2ZSIsInRvb2x0aXBDb25maWciLCJfbG9vcDQiLCJhbGxGaWVsZHMiLCJmaWVsZHMiLCJmb3VuZEZpZWxkc1RvU2hvdyIsImZpZWxkIiwibWVyZ2VMYXllckJsZW5kaW5nIiwibGF5ZXJCbGVuZGluZyIsIkxBWUVSX0JMRU5ESU5HUyIsImNvbWJpbmVMYXllckJsZW5kaW5nQ29uZmlncyIsIm1lcmdlT3ZlcmxheUJsZW5kaW5nIiwib3ZlcmxheUJsZW5kaW5nIiwiT1ZFUkxBWV9CTEVORElOR1MiLCJjb21iaW5lT3ZlcmxheUJsZW5kaW5nQ29uZmlncyIsIm1lcmdlQW5pbWF0aW9uQ29uZmlnIiwiYW5pbWF0aW9uIiwiY3VycmVudFRpbWUiLCJhbmltYXRpb25Db25maWciLCJkb21haW4iLCJjb21iaW5lQW5pbWF0aW9uQ29uZmlncyIsIl9hZ2dyZWdhdGUyIiwiX2FnZ3JlZ2F0ZTMiLCJtaW5pbXVtIiwic3BlZWQiLCJ2YWxpZGF0ZVNhdmVkTGF5ZXJDb2x1bW5zIiwic2F2ZWRDb2xzIiwiZW1wdHlDb2xzIiwib3B0aW9ucyIsImNvbHVtbnMiLCJfbG9vcDUiLCJfT2JqZWN0JGtleXMiLCJfaSIsInNhdmVkIiwiZmllbGRJZHgiLCJfcmVmNiIsImFsbENvbEZvdW5kIiwiZXZlcnkiLCJ2YWxpZGF0ZUNvbHVtbiIsInJ2IiwidGhyb3dPbkVycm9yIiwicmVxdWlyZWRDb2x1bW5zIiwiayIsIm9wdGlvbmFsIiwibWlzc2luZ0NvbHVtbnMiLCJFcnJvciIsImpvaW4iLCJjb25maWdDb2x1bW5zIiwiaW52YWxpZENvbHVtbnMiLCJfY29sdW1ucyRrIiwiY29sdW1uIiwidmFsaWRhdG9yIiwidmFsaWRhdGVTYXZlZFRleHRMYWJlbCIsIl9yZWY3Iiwic2F2ZWRUZXh0TGFiZWwiLCJfcmVmOCIsImxheWVyVGV4dExhYmVsIiwic2F2ZWRUZXh0TGFiZWxzIiwidGV4dExhYmVsIiwiZmQiLCJKU09OIiwic3RyaW5naWZ5IiwiYWNjdSIsInZhbGlkYXRlU2F2ZWRWaXN1YWxDaGFubmVscyIsInNhdmVkTGF5ZXIiLCJ2YWx1ZXMiLCJfcmVmOSIsInNjYWxlIiwiZm91bmRGaWVsZCIsImZvdW5kQ2hhbm5lbCIsInVwZGF0ZUxheWVyQ29uZmlnIiwidmFsaWRhdGVWaXN1YWxDaGFubmVsIiwiX3NhdmVkTGF5ZXIkY29uZmlnIiwiX25ld0xheWVyJGNvbmZpZyRmaWVsIiwiZmllbGROYW1lIiwiX2xheWVyJGNvbmZpZyIsInZhbGlkYXRlTGF5ZXIiLCJ2YWxpZGF0ZUxheWVyV2l0aERhdGEiLCJfZ2V0Q29sdW1uQ29uZmlnRm9yVmFsaWRhdGlvbiIsImNvbHVtbkNvbmZpZyIsImdldExheWVyQ29sdW1ucyIsImNvbE1vZGVDb25maWciLCJjb2x1bW5Nb2RlIiwic3VwcG9ydGVkQ29sdW1uTW9kZXMiLCJjb2xNb2RlIiwib3B0aW9uYWxDb2x1bW5zIiwiZGF0YXNldCIsInR5cGUiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImxhYmVsIiwiaXNWaXNpYmxlIiwiaGlkZGVuIiwiaGlnaGxpZ2h0Q29sb3IiLCJjb3BpZWRWaXNDb25maWciLCJjb3B5TGF5ZXJDb25maWciLCJ2aXNDb25maWciLCJzaGFsbG93Q29weSIsInZhbGlkYXRlVmlzQ29uZmlnIiwibWVyZ2VFZGl0b3IiLCJzYXZlZEVkaXRvciIsIl9zYXZlZEVkaXRvciR2aXNpYmxlIiwiZWRpdG9yIiwiZmVhdHVyZXMiLCJ2aXNpYmxlIiwiY29tYmluZUVkaXRvckNvbmZpZ3MiLCJuZXh0Q29uZmlnIiwibWVyZ2VEYXRhc2V0c0J5T3JkZXIiLCJuZXdEYXRhRW50cmllcyIsInByZXNlcnZlRGF0YXNldE9yZGVyIiwibmV3RGF0YXNldElkcyIsIl9zdGF0ZSRwcmVzZXJ2ZURhdGFzZSIsImFyciIsIl9yZWYxMyIsInRhbGx5cyIsIk1hcCIsIm5vdE51bGxvclVuZGVmaW5lZCIsImhhcyIsInNldCIsImdldCIsIlZJU19TVEFURV9NRVJHRVJTIiwiZXhwb3J0cyIsIm1lcmdlIiwicHJvcCIsInRvTWVyZ2VQcm9wIiwicHJlc2VydmVPcmRlciIsInJlcGxhY2VQYXJlbnREYXRhc2V0SWRzIiwic2F2ZVVubWVyZ2VkIiwiY29tYmluZUNvbmZpZ3MiXSwic291cmNlcyI6WyIuLi9zcmMvdmlzLXN0YXRlLW1lcmdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgdW5pcSBmcm9tICdsb2Rhc2gudW5pcSc7XG5pbXBvcnQgcGljayBmcm9tICdsb2Rhc2gucGljayc7XG5pbXBvcnQgZmxhdHRlbkRlZXAgZnJvbSAnbG9kYXNoLmZsYXR0ZW5kZWVwJztcbmltcG9ydCBkZWVwbWVyZ2UgZnJvbSAnZGVlcG1lcmdlJztcbmltcG9ydCB7XG4gIGFycmF5SW5zZXJ0LFxuICBnZXRJbml0aWFsTWFwTGF5ZXJzRm9yU3BsaXRNYXAsXG4gIGFwcGx5RmlsdGVyc1RvRGF0YXNldHMsXG4gIHZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzLFxuICBmaW5kQnlJZCxcbiAgYWdncmVnYXRlXG59IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuXG5pbXBvcnQge0xheWVyfSBmcm9tICdAa2VwbGVyLmdsL2xheWVycyc7XG5pbXBvcnQge2NyZWF0ZUVmZmVjdH0gZnJvbSAnQGtlc