UNPKG

kepler.gl.geoiq

Version:

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

1,520 lines 157 kB
"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.widgetConfigChangeUpdater = widgetConfigChangeUpdater;
exports.widgetTypeChangeUpdater = widgetTypeChangeUpdater;
exports.layerConfigChangeUpdater = layerConfigChangeUpdater;
exports.layerTypeChangeUpdater = layerTypeChangeUpdater;
exports.layerVisualChannelChangeUpdater = layerVisualChannelChangeUpdater;
exports.layerVisConfigChangeUpdater = layerVisConfigChangeUpdater;
exports.interactionConfigChangeUpdater = interactionConfigChangeUpdater;
exports.setFilterUpdater = setFilterUpdater;
exports.addDefaultLayers = addDefaultLayers;
exports.addDefaultTooltips = addDefaultTooltips;
exports.updateAllLayerDomainData = updateAllLayerDomainData;
exports.updateWidgetAggregationData = updateWidgetAggregationData;
exports.updateStateWithLayerDataUpdater = updateStateWithLayerDataUpdater;
exports.apiCallData = apiCallData;
exports.loadFilesErrUpdater = exports.loadFilesUpdater = exports.updateVisDataUpdater = exports.toggleLayerForMapUpdater = exports.setVisibleLayersForMapUpdater = exports.toggleSplitMapUpdater = exports.mapClickUpdater = exports.layerClickUpdater = exports.layerHoverUpdater = exports.receiveMapConfigUpdater = exports.resetMapConfigVisStateUpdater = exports.showDatasetTableUpdater = exports.updateLayerBlendingUpdater = exports.removeDatasetUpdater = exports.reorderLayerUpdater = exports.removeLayerUpdater = exports.addLayerUpdater = exports.reorderWidgetUpdater = exports.removeWidgetUpdater = exports.addWidgetUpdater = exports.removeFilterUpdater = exports.enlargeFilterUpdater = exports.updateAnimationSpeedUpdater = exports.toggleFilterAnimationUpdater = exports.addFilterUpdater = exports.setFilterPlotUpdater = exports.INITIAL_VIS_STATE = void 0;

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

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

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

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

var _window = require("global/window");

var _tasks = _interopRequireWildcard(require("react-palm/tasks"));

var _tasks2 = require("../tasks/tasks");

var _visStateActions = require("../actions/vis-state-actions");

var _actions = require("../actions");

var _interactionUtils = require("../utils/interaction-utils");

var _filterUtils = require("../utils/filter-utils");

var _datasetUtils = require("../utils/dataset-utils");

var _layerUtils = require("../utils/layer-utils/layer-utils");

var _widgetUtils = require("../utils/widget-utils/widget-utils");

var _visStateMerger = require("./vis-state-merger");

var _simplifyGeojson = _interopRequireDefault(require("simplify-geojson"));

var _layers = require("../layers");

var _widgets = require("../widgets");

var _fileUtils = require("../utils/file-utils");

var _aggregateUtils = require("../utils/aggregate-utils");

var _helpers = require("@turf/helpers");

function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return (0, _typeof2["default"])(key) === "symbol" ? key : String(key); }

function _toPrimitive(input, hint) { if ((0, _typeof2["default"])(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if ((0, _typeof2["default"])(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }

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; }

// import WidgetConfigurator from 'components/side-panel/widget-panel/widget-configurator';
// react-palm
// disable capture exception for react-palm call to withTask
(0, _tasks.disableStackCapturing)();
var INITIAL_VIS_STATE = {
  // layers
  layers: [],
  layerData: [],
  layerToBeMerged: [],
  layerOrder: [],
  // filters
  filters: [],
  filterToBeMerged: [],
  //widgets
  widgets: [],
  widgetToBeMerged: [],
  widgetOrder: [],
  // a collection of multiple dataset
  datasets: {},
  editingDataset: undefined,
  interactionConfig: (0, _interactionUtils.getDefaultInteraction)(),
  interactionToBeMerged: undefined,
  layerBlending: 'normal',
  hoverInfo: undefined,
  clicked: undefined,
  fileLoading: false,
  fileLoadingErr: null,
  // this is used when user split maps
  splitMaps: [// this will contain a list of objects to
    // describe the state of layer availability and visibility for each map
    // [
    //   {
    //     layers: {
    //       layer_id: {
    //         isAvailable: true|false # this is driven by the left hand panel
    //         isVisible: true|false
    //       }
    //     }
    //   }
    // ]
  ],
  // defaults layer classes
  layerClasses: _layers.LayerClasses,
  //default widget classes
  widgetClasses: _widgets.WidgetClasses
};
exports.INITIAL_VIS_STATE = INITIAL_VIS_STATE;

function updateStateWithWidgetAndData(state, _ref) {
  var widget = _ref.widget,
      idx = _ref.idx;
  return _objectSpread({}, state, {
    widgets: state.widgets.map(function (wdgt, i) {
      return i === idx ? widget : wdgt;
    })
  });
}
/**
 * Called to update layer base config: dataId, label, column, isVisible
 *
 */


function widgetConfigChangeUpdater(state, action) {
  var oldWidget = action.oldWidget;
  var mapState = action.newConfig.mapState;
  var x = state.widgets.findIndex(function (w) {
    return w.id === oldWidget.id;
  });
  var props = Object.keys(action.newConfig);
  action.newConfig.mapState ? delete action.newConfig.mapState : null;
  var newWidget = oldWidget.updateWidgetConfig(action.newConfig);

  if (newWidget.shouldCalculateAggregatedData(props)) {
    var _newWidget$calculateA = newWidget.calculateAggregationData(newWidget, state, mapState),
        updatedState = _newWidget$calculateA.updatedState;

    return updateStateWithWidgetAndData(updatedState ? updatedState : state, {
      widget: newWidget,
      x: x
    });
  }

  var newState = _objectSpread({}, state, {
    splitMaps: 'isVisible' in action.newConfig ? toggleWidgetFromSplitMaps(state, widget) : state.splitMaps
  });

  return updateStateWithWidgetAndData(newState, {
    widget: newWidget,
    x: x
  });
}

function widgetTypeChangeUpdater(state, action) {
  var oldWidget = action.oldWidget,
      newType = action.newType;
  var oldId = oldWidget.id;
  var idx = state.widgets.findIndex(function (w) {
    return w.id === oldId;
  });

  if (!state.widgetClasses[newType]) {
    _window.console.error("".concat(newType, " is not a valid widget type"));

    return state;
  } // get a mint widget, with new id and type
  // because deck.gl uses id to match between new and old layer.
  // If type has changed but id is the same, it will break


  var newWidget = new state.widgetClasses[newType]();
  newWidget.config.aggregatedData = null;
  newWidget.assignConfigToWidget(oldWidget.config, oldWidget.visConfigSettings);
  var newState = state;
  var widget = newWidget;
  return updateStateWithWidgetAndData(newState, {
    widget: widget,
    idx: idx
  });
}

function updateStateWithLayerAndData(state, _ref2) {
  var layerData = _ref2.layerData,
      layer = _ref2.layer,
      idx = _ref2.idx;
  return _objectSpread({}, state, {
    layers: state.layers.map(function (lyr, i) {
      return i === idx ? layer : lyr;
    }),
    layerData: layerData ? state.layerData.map(function (d, i) {
      return i === idx ? layerData : d;
    }) : state.layerData
  });
}
/**
 * Called to update layer base config: dataId, label, column, isVisible
 *
 */


function layerConfigChangeUpdater(state, action) {
  var oldLayer = action.oldLayer;
  var idx = state.layers.findIndex(function (l) {
    return l.id === oldLayer.id;
  });
  var props = Object.keys(action.newConfig);
  var newLayer = oldLayer.updateLayerConfig(action.newConfig);

  if (newLayer.shouldCalculateLayerData(props)) {
    var oldLayerData = state.layerData[idx];

    var _calculateLayerData = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
      sameData: true
    }),
        layerData = _calculateLayerData.layerData,
        layer = _calculateLayerData.layer;

    return updateStateWithLayerAndData(state, {
      layerData: layerData,
      layer: layer,
      idx: idx
    });
  }

  var newState = _objectSpread({}, state, {
    splitMaps: 'isVisible' in action.newConfig ? toggleLayerFromSplitMaps(state, newLayer) : state.splitMaps
  });

  return updateStateWithLayerAndData(newState, {
    layer: newLayer,
    idx: idx
  });
}

function layerTypeChangeUpdater(state, action) {
  var oldLayer = action.oldLayer,
      newType = action.newType;
  var oldId = oldLayer.id;
  var idx = state.layers.findIndex(function (l) {
    return l.id === oldId;
  });

  if (!state.layerClasses[newType]) {
    _window.console.error("".concat(newType, " is not a valid layer type"));

    return state;
  } // get a mint layer, with new id and type
  // because deck.gl uses id to match between new and old layer.
  // If type has changed but id is the same, it will break


  var newLayer = new state.layerClasses[newType]();
  newLayer.assignConfigToLayer(oldLayer.config, oldLayer.visConfigSettings);

  if (newLayer.config.dataId) {
    var dataset = state.datasets[newLayer.config.dataId];
    newLayer.updateLayerDomain(dataset);
  }

  var _calculateLayerData2 = (0, _layerUtils.calculateLayerData)(newLayer, state),
      layerData = _calculateLayerData2.layerData,
      layer = _calculateLayerData2.layer;

  var newState = state; //update widgets layer id

  if (state.widgets) {
    state.widgets.map(function (widget) {
      var config = widget.config;
      var selectedLayer = config.selectedLayer;

      if (widget.type && selectedLayer.id === oldId) {
        widget.updateWidgetConfig({
          selectedLayer: _objectSpread({}, selectedLayer, {
            id: newLayer.id
          })
        });
      }
    });
  } // update splitMap layer id


  if (state.splitMaps) {
    newState = _objectSpread({}, newState, {
      splitMaps: state.splitMaps.map(function (settings) {
        var _settings$layers = settings.layers,
            oldLayerMap = _settings$layers[oldId],
            otherLayers = (0, _objectWithoutProperties2["default"])(_settings$layers, [oldId].map(_toPropertyKey));
        return _objectSpread({}, settings, {
          layers: _objectSpread({}, otherLayers, (0, _defineProperty2["default"])({}, layer.id, oldLayerMap))
        });
      })
    });
  }

  return updateStateWithLayerAndData(newState, {
    layerData: layerData,
    layer: layer,
    idx: idx
  });
}

function layerVisualChannelChangeUpdater(state, action) {
  var oldLayer = action.oldLayer,
      newConfig = action.newConfig,
      channel = action.channel;
  var dataset = state.datasets[oldLayer.config.dataId];
  var idx = state.layers.findIndex(function (l) {
    return l.id === oldLayer.id;
  });
  var newLayer = oldLayer.updateLayerConfig(newConfig);
  newLayer.updateLayerVisualChannel(dataset, channel);
  var oldLayerData = state.layerData[idx];

  var _calculateLayerData3 = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
    sameData: true
  }),
      layerData = _calculateLayerData3.layerData,
      layer = _calculateLayerData3.layer; // let data = layer.axiosApiCall();
  // if (layer.type === 'boundary') {
  //   data.then(function(result) {
  //     // const testData = layer.formatLayer();
  //     var {layerData, layer} = calculateLayerDataAfterAPICall(
  //       newLayer,
  //       state,
  //       layerData,
  //       result
  //     );
  //     layerData = {
  //       ...layerData,
  //       result
  //     };
  //     newLayers[i] = layer;
  //     newLayerDatas[i] = layerData;
  //     return {
  //       ...state,
  //       layers: newLayers,
  //       layerData: newLayerDatas
  //     };
  //   });
  // }


  return updateStateWithLayerAndData(state, {
    layerData: layerData,
    layer: layer,
    idx: idx
  });
}

function layerVisConfigChangeUpdater(state, action) {
  var oldLayer = action.oldLayer;
  var idx = state.layers.findIndex(function (l) {
    return l.id === oldLayer.id;
  });
  var props = Object.keys(action.newVisConfig);

  var newVisConfig = _objectSpread({}, oldLayer.config.visConfig, {}, action.newVisConfig);

  var newLayer = oldLayer.updateLayerConfig({
    visConfig: newVisConfig
  });

  if (newLayer.shouldCalculateLayerData(props)) {
    var oldLayerData = state.layerData[idx];

    var _calculateLayerData4 = (0, _layerUtils.calculateLayerData)(newLayer, state, oldLayerData, {
      sameData: true
    }),
        layerData = _calculateLayerData4.layerData,
        layer = _calculateLayerData4.layer;

    return updateStateWithLayerAndData(state, {
      layerData: layerData,
      layer: layer,
      idx: idx
    });
  }

  return updateStateWithLayerAndData(state, {
    layer: newLayer,
    idx: idx
  });
}
/* eslint-enable max-statements */


function interactionConfigChangeUpdater(state, action) {
  var config = action.config;

  var interactionConfig = _objectSpread({}, state.interactionConfig, {}, (0, _defineProperty2["default"])({}, config.id, config));

  if (config.enabled && !state.interactionConfig[config.id].enabled) {
    // only enable one interaction at a time
    Object.keys(interactionConfig).forEach(function (k) {
      if (k !== config.id) {
        interactionConfig[k] = _objectSpread({}, interactionConfig[k], {
          enabled: false
        });
      }
    });
  }

  return _objectSpread({}, state, {
    interactionConfig: interactionConfig
  });
}

function setFilterUpdater(state, action) {
  var idx = action.idx,
      prop = action.prop,
      value = action.value;
  var newState = state;

  var newFilter = _objectSpread({}, state.filters[idx], (0, _defineProperty2["default"])({}, prop, value));

  var _newFilter = newFilter,
      dataId = _newFilter.dataId;

  if (!dataId) {
    return state;
  }

  var _state$datasets$dataI = state.datasets[dataId],
      fields = _state$datasets$dataI.fields,
      allData = _state$datasets$dataI.allData;

  switch (prop) {
    case 'dataId':
      // if trying to update filter dataId. create an empty new filter
      newFilter = (0, _filterUtils.getDefaultFilter)(dataId);
      break;

    case 'name':
      // find the field
      var fieldIdx = fields.findIndex(function (f) {
        return f.name === value;
      });
      var field = fields[fieldIdx];

      if (!field.filterProp) {
        // get filter domain from field
        // save filterProps: {domain, steps, value} to field, avoid recalculate
        field = _objectSpread({}, field, {
          filterProp: (0, _filterUtils.getFilterProps)(allData, field)
        });
      }

      newFilter = _objectSpread({}, newFilter, {}, field.filterProp, {
        name: field.name,
        // can't edit dataId once name is selected
        freeze: true,
        fieldIdx: fieldIdx
      });
      var enlargedFilterIdx = state.filters.findIndex(function (f) {
        return f.enlarged;
      });

      if (enlargedFilterIdx > -1 && enlargedFilterIdx !== idx) {
        // there should be only one enlarged filter
        newFilter.enlarged = false;
      }

      newState = _objectSpread({}, state, {
        datasets: _objectSpread({}, state.datasets, (0, _defineProperty2["default"])({}, dataId, _objectSpread({}, state.datasets[dataId], {
          fields: fields.map(function (d, i) {
            return i === fieldIdx ? field : d;
          })
        })))
      });
      break;

    case 'value':
    default:
      break;
  } // save new filters to newState


  newState = _objectSpread({}, newState, {
    filters: state.filters.map(function (f, i) {
      return i === idx ? newFilter : f;
    })
  }); // filter data

  newState = _objectSpread({}, newState, {
    datasets: _objectSpread({}, newState.datasets, (0, _defineProperty2["default"])({}, dataId, _objectSpread({}, newState.datasets[dataId], {}, (0, _filterUtils.filterData)(allData, dataId, newState.filters))))
  });
  newState = updateAllLayerDomainData(newState, dataId, newFilter);
  newState = updateWidgetAggregationData(newState);
  return newState;
}

var setFilterPlotUpdater = function setFilterPlotUpdater(state, _ref3) {
  var idx = _ref3.idx,
      newProp = _ref3.newProp;

  var newFilter = _objectSpread({}, state.filters[idx], {}, newProp);

  var prop = Object.keys(newProp)[0];

  if (prop === 'yAxis') {
    var plotType = (0, _filterUtils.getDefaultFilterPlotType)(newFilter);

    if (plotType) {
      newFilter = _objectSpread({}, newFilter, {}, (0, _filterUtils.getFilterPlot)(_objectSpread({}, newFilter, {
        plotType: plotType
      }), state.datasets[newFilter.dataId].allData), {
        plotType: plotType
      });
    }
  }

  return _objectSpread({}, state, {
    filters: state.filters.map(function (f, i) {
      return i === idx ? newFilter : f;
    })
  });
};

exports.setFilterPlotUpdater = setFilterPlotUpdater;

var addFilterUpdater = function addFilterUpdater(state, action) {
  return !action.dataId ? state : _objectSpread({}, state, {
    filters: [].concat((0, _toConsumableArray2["default"])(state.filters), [(0, _filterUtils.getDefaultFilter)(action.dataId)])
  });
};

exports.addFilterUpdater = addFilterUpdater;

var toggleFilterAnimationUpdater = function toggleFilterAnimationUpdater(state, action) {
  return _objectSpread({}, state, {
    filters: state.filters.map(function (f, i) {
      return i === action.idx ? _objectSpread({}, f, {
        isAnimating: !f.isAnimating
      }) : f;
    })
  });
};

exports.toggleFilterAnimationUpdater = toggleFilterAnimationUpdater;

var updateAnimationSpeedUpdater = function updateAnimationSpeedUpdater(state, action) {
  return _objectSpread({}, state, {
    filters: state.filters.map(function (f, i) {
      return i === action.idx ? _objectSpread({}, f, {
        speed: action.speed
      }) : f;
    })
  });
};

exports.updateAnimationSpeedUpdater = updateAnimationSpeedUpdater;

var enlargeFilterUpdater = function enlargeFilterUpdater(state, action) {
  var isEnlarged = state.filters[action.idx].enlarged;
  return _objectSpread({}, state, {
    filters: state.filters.map(function (f, i) {
      f.enlarged = !isEnlarged && i === action.idx;
      return f;
    })
  });
};

exports.enlargeFilterUpdater = enlargeFilterUpdater;

var removeFilterUpdater = function removeFilterUpdater(state, action) {
  var idx = action.idx;
  var dataId = state.filters[idx].dataId;
  var newFilters = [].concat((0, _toConsumableArray2["default"])(state.filters.slice(0, idx)), (0, _toConsumableArray2["default"])(state.filters.slice(idx + 1, state.filters.length)));

  var newState = _objectSpread({}, state, {
    datasets: _objectSpread({}, state.datasets, (0, _defineProperty2["default"])({}, dataId, _objectSpread({}, state.datasets[dataId], {}, (0, _filterUtils.filterData)(state.datasets[dataId].allData, dataId, newFilters)))),
    filters: newFilters
  });

  newState = updateAllLayerDomainData(newState, dataId);
  return updateWidgetAggregationData(newState);
};

exports.removeFilterUpdater = removeFilterUpdater;

var addWidgetUpdater = function addWidgetUpdater(state, action) {
  var defaultDataset = Object.keys(state.datasets)[0];
  var newWidget = new _widgets.Widget(_objectSpread({
    isVisible: true,
    isConfigActive: true,
    dataId: defaultDataset
  }, action.props));
  return _objectSpread({}, state, {
    widgets: [].concat((0, _toConsumableArray2["default"])(state.widgets), [newWidget]),
    widgetOrder: [].concat((0, _toConsumableArray2["default"])(state.widgetOrder), [state.widgetOrder.length])
  });
};

exports.addWidgetUpdater = addWidgetUpdater;

var removeWidgetUpdater = function removeWidgetUpdater(state, _ref4) {
  var idx = _ref4.idx;
  var widgets = state.widgets;
  return _objectSpread({}, state, {
    widgets: [].concat((0, _toConsumableArray2["default"])(widgets.slice(0, idx)), (0, _toConsumableArray2["default"])(widgets.slice(idx + 1, widgets.length))),
    widgetOrder: state.widgetOrder.filter(function (i) {
      return i !== idx;
    }).map(function (pid) {
      return pid > idx ? pid - 1 : pid;
    })
  });
};

exports.removeWidgetUpdater = removeWidgetUpdater;

var reorderWidgetUpdater = function reorderWidgetUpdater(state, _ref5) {
  var order = _ref5.order;
  // console.log('reorderWidgetUpdater', order);
  return _objectSpread({}, state, {
    widgetOrder: order
  });
};

exports.reorderWidgetUpdater = reorderWidgetUpdater;

var addLayerUpdater = function addLayerUpdater(state, action) {
  var defaultDataset = Object.keys(state.datasets)[0]; // console.log(
  //   'inside add Layer updater  ',
  //   state,
  //   action.props,
  //   defaultDataset
  // );

  var newLayer = new _layers.Layer(_objectSpread({
    isVisible: true,
    isConfigActive: true,
    dataId: defaultDataset
  }, action.props));
  return _objectSpread({}, state, {
    layers: [].concat((0, _toConsumableArray2["default"])(state.layers), [newLayer]),
    layerData: [].concat((0, _toConsumableArray2["default"])(state.layerData), [{}]),
    layerOrder: [].concat((0, _toConsumableArray2["default"])(state.layerOrder), [state.layerOrder.length]),
    splitMaps: addNewLayersToSplitMap(state.splitMaps, newLayer)
  });
};

exports.addLayerUpdater = addLayerUpdater;

var removeLayerUpdater = function removeLayerUpdater(state, _ref6) {
  var idx = _ref6.idx;
  var _state = state,
      layers = _state.layers,
      layerData = _state.layerData,
      clicked = _state.clicked,
      hoverInfo = _state.hoverInfo;
  var layerToRemove = state.layers[idx];
  var newMaps = removeLayerFromSplitMaps(state, layerToRemove); // console.log(removeWidgetsOnLayer(state, layerToRemove));

  state = removeWidgetsOnLayer(state, layerToRemove);
  return _objectSpread({}, state, {
    layers: [].concat((0, _toConsumableArray2["default"])(layers.slice(0, idx)), (0, _toConsumableArray2["default"])(layers.slice(idx + 1, layers.length))),
    layerData: [].concat((0, _toConsumableArray2["default"])(layerData.slice(0, idx)), (0, _toConsumableArray2["default"])(layerData.slice(idx + 1, layerData.length))),
    layerOrder: state.layerOrder.filter(function (i) {
      return i !== idx;
    }).map(function (pid) {
      return pid > idx ? pid - 1 : pid;
    }),
    clicked: layerToRemove.isLayerHovered(clicked) ? undefined : clicked,
    hoverInfo: layerToRemove.isLayerHovered(hoverInfo) ? undefined : hoverInfo,
    splitMaps: newMaps
  });
};

exports.removeLayerUpdater = removeLayerUpdater;

var reorderLayerUpdater = function reorderLayerUpdater(state, _ref7) {
  var order = _ref7.order;
  return _objectSpread({}, state, {
    layerOrder: order
  });
};

exports.reorderLayerUpdater = reorderLayerUpdater;

var removeDatasetUpdater = function removeDatasetUpdater(state, action) {
  // extract dataset key
  var datasetKey = action.key;
  var datasets = state.datasets; // check if dataset is present

  if (!datasets[datasetKey]) {
    return state;
  }
  /* eslint-disable no-unused-vars */


  var layers = state.layers,
      _state$datasets = state.datasets,
      dataset = _state$datasets[datasetKey],
      newDatasets = (0, _objectWithoutProperties2["default"])(_state$datasets, [datasetKey].map(_toPropertyKey));
  /* eslint-enable no-unused-vars */

  var indexes = layers.reduce(function (listOfIndexes, layer, index) {
    if (layer.config.dataId === datasetKey) {
      listOfIndexes.push(index);
    }

    return listOfIndexes;
  }, []); // remove layers and datasets

  var _indexes$reduce = indexes.reduce(function (_ref8, idx) {
    var currentState = _ref8.newState,
        indexCounter = _ref8.indexCounter;
    var currentIndex = idx - indexCounter;
    currentState = removeLayerUpdater(currentState, {
      idx: currentIndex
    });
    indexCounter++;
    return {
      newState: currentState,
      indexCounter: indexCounter
    };
  }, {
    newState: _objectSpread({}, state, {
      datasets: newDatasets
    }),
    indexCounter: 0
  }),
      newState = _indexes$reduce.newState; // remove filters


  var filters = state.filters.filter(function (filter) {
    return filter.dataId !== datasetKey;
  }); // update interactionConfig

  var interactionConfig = state.interactionConfig;
  var _interactionConfig = interactionConfig,
      tooltip = _interactionConfig.tooltip;

  if (tooltip) {
    var config = tooltip.config;
    /* eslint-disable no-unused-vars */

    var _config$fieldsToShow = config.fieldsToShow,
        fields = _config$fieldsToShow[datasetKey],
        fieldsToShow = (0, _objectWithoutProperties2["default"])(_config$fieldsToShow, [datasetKey].map(_toPropertyKey));
    /* eslint-enable no-unused-vars */

    interactionConfig = _objectSpread({}, interactionConfig, {
      tooltip: _objectSpread({}, tooltip, {
        config: _objectSpread({}, config, {
          fieldsToShow: fieldsToShow
        })
      })
    });
  }

  return _objectSpread({}, newState, {
    filters: filters,
    interactionConfig: interactionConfig
  });
};

exports.removeDatasetUpdater = removeDatasetUpdater;

var updateLayerBlendingUpdater = function updateLayerBlendingUpdater(state, action) {
  return _objectSpread({}, state, {
    layerBlending: action.mode
  });
};

exports.updateLayerBlendingUpdater = updateLayerBlendingUpdater;

var showDatasetTableUpdater = function showDatasetTableUpdater(state, action) {
  return _objectSpread({}, state, {
    editingDataset: action.dataId
  });
};

exports.showDatasetTableUpdater = showDatasetTableUpdater;

var resetMapConfigVisStateUpdater = function resetMapConfigVisStateUpdater(state, action) {
  return _objectSpread({}, INITIAL_VIS_STATE, {}, state.initialState, {
    initialState: state.initialState
  });
};
/**
 * Loads custom configuration into state
 * @param state
 * @param action
 * @returns {*}
 */


exports.resetMapConfigVisStateUpdater = resetMapConfigVisStateUpdater;

var receiveMapConfigUpdater = function receiveMapConfigUpdater(state, action) {
  if (!action.payload.visState) {
    return state;
  }

  var _action$payload$visSt = action.payload.visState,
      filters = _action$payload$visSt.filters,
      layers = _action$payload$visSt.layers,
      widgets = _action$payload$visSt.widgets,
      interactionConfig = _action$payload$visSt.interactionConfig,
      layerBlending = _action$payload$visSt.layerBlending,
      splitMaps = _action$payload$visSt.splitMaps; // always reset config when receive a new config

  var resetState = resetMapConfigVisStateUpdater(state);

  var mergedState = _objectSpread({}, resetState, {
    splitMaps: splitMaps || [] // maps doesn't require any logic

  }); // console.log('Before MergeFilters', mergedState);
  // console.log(filters, layers, widgets);


  mergedState = (0, _visStateMerger.mergeFilters)(mergedState, filters); // console.log('After MergeFilters', mergedState);

  mergedState = (0, _visStateMerger.mergeLayers)(mergedState, layers); // console.log('After MergeLayers', mergedState);

  mergedState = (0, _visStateMerger.mergeInteractions)(mergedState, interactionConfig);
  mergedState = (0, _visStateMerger.mergeLayerBlending)(mergedState, layerBlending);
  mergedState = (0, _visStateMerger.mergeWidgets)(mergedState, widgets); // console.log('After MergeWidgets', mergedState);

  return mergedState;
};

exports.receiveMapConfigUpdater = receiveMapConfigUpdater;

var layerHoverUpdater = function layerHoverUpdater(state, action) {
  return _objectSpread({}, state, {
    hoverInfo: action.info
  });
};

exports.layerHoverUpdater = layerHoverUpdater;

var layerClickUpdater = function layerClickUpdater(state, action) {
  return _objectSpread({}, state, {
    clicked: action.info && action.info.picked ? action.info : null
  });
};

exports.layerClickUpdater = layerClickUpdater;

var mapClickUpdater = function mapClickUpdater(state, action) {
  return _objectSpread({}, state, {
    clicked: null
  });
};

exports.mapClickUpdater = mapClickUpdater;

var toggleSplitMapUpdater = function toggleSplitMapUpdater(state, action) {
  return state.splitMaps && state.splitMaps.length === 0 ? _objectSpread({}, state, {
    // maybe we should use an array to store state for a single map as well
    // if current maps length is equal to 0 it means that we are about to split the view
    splitMaps: computeSplitMapLayers(state.layers)
  }) : closeSpecificMapAtIndex(state, action);
};
/**
 * This is triggered when view is split into multiple maps.
 * It will only update layers that belong to the map layer dropdown
 * the user is interacting wit
 * @param state
 * @param action
 */


exports.toggleSplitMapUpdater = toggleSplitMapUpdater;

var setVisibleLayersForMapUpdater = function setVisibleLayersForMapUpdater(state, action) {
  var mapIndex = action.mapIndex,
      layerIds = action.layerIds;

  if (!layerIds) {
    return state;
  }

  var _state$splitMaps = state.splitMaps,
      splitMaps = _state$splitMaps === void 0 ? [] : _state$splitMaps;

  if (splitMaps.length === 0) {
    // we should never get into this state
    // because this action should only be triggered
    // when map view is split
    // but something may have happened
    return state;
  } // need to check if maps is populated otherwise will create


  var _splitMaps$mapIndex = splitMaps[mapIndex],
      map = _splitMaps$mapIndex === void 0 ? {} : _splitMaps$mapIndex;
  var layers = map.layers || []; // we set visibility to true for all layers included in our input list

  var newLayers = (Object.keys(layers) || []).reduce(function (currentLayers, idx) {
    return _objectSpread({}, currentLayers, (0, _defineProperty2["default"])({}, idx, _objectSpread({}, layers[idx], {
      isVisible: layerIds.includes(idx)
    })));
  }, {});
  var newMaps = (0, _toConsumableArray2["default"])(splitMaps);
  newMaps[mapIndex] = _objectSpread({}, splitMaps[mapIndex], {
    layers: newLayers
  });
  return _objectSpread({}, state, {
    splitMaps: newMaps
  });
};

exports.setVisibleLayersForMapUpdater = setVisibleLayersForMapUpdater;

var toggleLayerForMapUpdater = function toggleLayerForMapUpdater(state, action) {
  if (!state.splitMaps[action.mapIndex]) {
    return state;
  }

  var mapSettings = state.splitMaps[action.mapIndex];
  var layers = mapSettings.layers;

  if (!layers || !layers[action.layerId]) {
    return state;
  }

  var layer = layers[action.layerId];

  var newLayer = _objectSpread({}, layer, {
    isVisible: !layer.isVisible
  });

  var newLayers = _objectSpread({}, layers, (0, _defineProperty2["default"])({}, action.layerId, newLayer)); // const splitMaps = state.splitMaps;


  var newSplitMaps = (0, _toConsumableArray2["default"])(state.splitMaps);
  newSplitMaps[action.mapIndex] = _objectSpread({}, mapSettings, {
    layers: newLayers
  });
  return _objectSpread({}, state, {
    splitMaps: newSplitMaps
  });
};
/* eslint-disable max-statements */


exports.toggleLayerForMapUpdater = toggleLayerForMapUpdater;

var updateVisDataUpdater = function updateVisDataUpdater(state, action) {
  // datasets can be a single data entries or an array of multiple data entries
  var datasets = Array.isArray(action.datasets) ? action.datasets : [action.datasets];

  if (action.config) {
    // apply config if passed from action
    state = receiveMapConfigUpdater(state, {
      payload: {
        visState: action.config
      }
    });
  }

  var newDateEntries = datasets.reduce(function (accu, _ref9) {
    var _ref9$info = _ref9.info,
        info = _ref9$info === void 0 ? {} : _ref9$info,
        data = _ref9.data;
    return _objectSpread({}, accu, {}, (0, _datasetUtils.createNewDataEntry)({
      info: info,
      data: data
    }, state.datasets) || {});
  }, {});

  if (!Object.keys(newDateEntries).length) {
    return state;
  }

  var stateWithNewData = _objectSpread({}, state, {
    datasets: _objectSpread({}, state.datasets, {}, newDateEntries)
  }); // previously saved config before data loaded


  var _stateWithNewData$fil = stateWithNewData.filterToBeMerged,
      filterToBeMerged = _stateWithNewData$fil === void 0 ? [] : _stateWithNewData$fil,
      _stateWithNewData$lay = stateWithNewData.layerToBeMerged,
      layerToBeMerged = _stateWithNewData$lay === void 0 ? [] : _stateWithNewData$lay,
      _stateWithNewData$wid = stateWithNewData.widgetToBeMerged,
      widgetToBeMerged = _stateWithNewData$wid === void 0 ? [] : _stateWithNewData$wid,
      _stateWithNewData$int = stateWithNewData.interactionToBeMerged,
      interactionToBeMerged = _stateWithNewData$int === void 0 ? {} : _stateWithNewData$int; // merge state with saved filters
  // console.log('FilterToBeMerged', filterToBeMerged);

  var mergedState = (0, _visStateMerger.mergeFilters)(stateWithNewData, filterToBeMerged); // merge state with saved layers

  mergedState = (0, _visStateMerger.mergeLayers)(mergedState, layerToBeMerged);
  var options = action.options;

  if (mergedState.layers.length === state.layers.length && !options.disabledAddDefaultLayers) {
    // no layer merged, find defaults
    mergedState = addDefaultLayers(mergedState, newDateEntries);
  } // if (mergedState.widgets.length === state.widgets.length) {
  //   mergedState = addDefaultWidget(mergedState, newDateEntries);
  // }


  if (mergedState.splitMaps.length) {
    var newLayers = mergedState.layers.filter(function (l) {
      return l.config.dataId in newDateEntries;
    }); // if map is splited, add new layers to splitMaps

    mergedState = _objectSpread({}, mergedState, {
      splitMaps: addNewLayersToSplitMap(mergedState.splitMaps, newLayers)
    });
  } // console.log(mergedState);
  // merge state with saved interactions


  mergedState = (0, _visStateMerger.mergeInteractions)(mergedState, interactionToBeMerged); // if no tooltips merged add default tooltips

  Object.keys(newDateEntries).forEach(function (dataId) {
    var tooltipFields = mergedState.interactionConfig.tooltip.config.fieldsToShow[dataId];

    if (!Array.isArray(tooltipFields) || !tooltipFields.length) {
      mergedState = addDefaultTooltips(mergedState, newDateEntries[dataId]);
    }
  });
  mergedState = updateAllLayerDomainData(mergedState, Object.keys(newDateEntries));
  mergedState = (0, _visStateMerger.mergeWidgets)(mergedState, widgetToBeMerged);
  return mergedState;
};
/* eslint-enable max-statements */


exports.updateVisDataUpdater = updateVisDataUpdater;

function generateLayerMetaForSplitViews(layer) {
  return {
    isAvailable: layer.config.isVisible,
    isVisible: layer.config.isVisible
  };
}
/**
 * This method will compute the default maps custom list
 * based on the current layers status
 * @param layers
 * @returns {[*,*]}
 */


function computeSplitMapLayers(layers) {
  var mapLayers = layers.reduce(function (newLayers, currentLayer) {
    return _objectSpread({}, newLayers, (0, _defineProperty2["default"])({}, currentLayer.id, generateLayerMetaForSplitViews(currentLayer)));
  }, {});
  return [{
    layers: mapLayers
  }, {
    layers: mapLayers
  }];
}
/**
 * Remove an existing layer from custom map layer objects
 * @param state
 * @param layer
 * @returns {[*,*]} Maps of custom layer objects
 */


function removeLayerFromSplitMaps(state, layer) {
  return state.splitMaps.map(function (settings) {
    var layers = settings.layers;
    /* eslint-disable no-unused-vars */

    var _layer$id = layer.id,
        _ = layers[_layer$id],
        newLayers = (0, _objectWithoutProperties2["default"])(layers, [_layer$id].map(_toPropertyKey));
    /* eslint-enable no-unused-vars */

    return _objectSpread({}, settings, {
      layers: newLayers
    });
  });
}
/**
 * Remove an existing layer from custom map layer objects
 * @param state
 * @param layer
 * @returns {*} state
 */


function removeWidgetsOnLayer(state, layer) {
  var widgets = state.widgets; // // check if dataset is present
  // if (!datasets[datasetKey]) {
  //   return state;
  // }

  var indexes = widgets.reduce(function (listOfIndexes, widget, index) {
    if (widget.config.selectedLayer.id === layer.id) {
      listOfIndexes.push(index);
    }

    return listOfIndexes;
  }, []); // remove layers and datasets

  var _indexes$reduce2 = indexes.reduce(function (_ref10, idx) {
    var currentState = _ref10.newState,
        indexCounter = _ref10.indexCounter;
    var currentIndex = idx - indexCounter;
    currentState = removeWidgetUpdater(currentState, {
      idx: currentIndex
    });
    indexCounter++;
    return {
      newState: currentState,
      indexCounter: indexCounter
    };
  }, {
    newState: _objectSpread({}, state),
    indexCounter: 0
  }),
      newState = _indexes$reduce2.newState;

  return newState;
}
/**
 * Remove an existing layer from custom map layer objects
 * @param state
 * @param layer
 * @returns {*} state
 */

/**
 * Add new layers to both existing maps
 * @param splitMaps
 * @param layers
 * @returns {[*,*]} new splitMaps
 */


function addNewLayersToSplitMap(splitMaps, layers) {
  var newLayers = Array.isArray(layers) ? layers : [layers];

  if (!splitMaps || !splitMaps.length || !newLayers.length) {
    return splitMaps;
  } // add new layer to both maps,
  //  don't override, if layer.id is already in splitMaps.settings.layers


  return splitMaps.map(function (settings) {
    return _objectSpread({}, settings, {
      layers: _objectSpread({}, settings.layers, {}, newLayers.reduce(function (accu, newLayer) {
        return newLayer.config.isVisible ? _objectSpread({}, accu, (0, _defineProperty2["default"])({}, newLayer.id, settings.layers[newLayer.id] ? settings.layers[newLayer.id] : generateLayerMetaForSplitViews(newLayer))) : accu;
      }, {}))
    });
  });
}
/**
 * Add new widgets to both existing maps
 * @param splitMaps
 * @param widgets
 * @returns {[*,*]} new splitMaps
 */


function addNewWidgetsToSplitMap(splitMaps, widgets) {
  // console.log('0');
  var newWidgets = Array.isArray(widgets) ? widgets : [widgets];

  if (!splitMaps || !splitMaps.length || !newWidgets.length) {
    return splitMaps;
  } // add new layer to both maps,
  //  don't override, if layer.id is already in splitMaps.settings.layers


  return splitMaps.map(function (settings) {
    return _objectSpread({}, settings, {
      widgets: _objectSpread({}, settings.widgets, {}, newWidgets.reduce(function (accu, newWidget) {
        return newWidget.config.isVisible ? _objectSpread({}, accu, (0, _defineProperty2["default"])({}, newWidget.id, settings.widgets[newWidgets.id] ? settings.widgets[newWidget.id] : generateLayerMetaForSplitViews(newWidget))) : accu;
      }, {}))
    });
  });
}
/**
 * Hide an existing layers from custom map layer objects
 * @param state
 * @param layer
 * @returns {[*,*]} Maps of custom layer objects
 */


function toggleLayerFromSplitMaps(state, layer) {
  return state.splitMaps.map(function (settings) {
    var layers = settings.layers;

    var newLayers = _objectSpread({}, layers, (0, _defineProperty2["default"])({}, layer.id, generateLayerMetaForSplitViews(layer)));

    return _objectSpread({}, settings, {
      layers: newLayers
    });
  });
}
/**
 * Hide an existing layers from custom map layer objects
 * @param state
 * @param widget
 * @returns {[*,*]} Maps of custom layer objects
 */


function toggleWidgetFromSplitMaps(state, layer) {
  // console.log('0');
  return state.splitMaps.map(function (settings) {
    var widgets = settings.widgets;

    var newWidgets = _objectSpread({}, widgets, (0, _defineProperty2["default"])({}, widget.id, generateLayerMetaForSplitViews(widget)));

    return _objectSpread({}, settings, {
      widgets: newWidgets
    });
  });
}
/**
 * When a user clicks on the specific map closing icon
 * the application will close the selected map
 * and will merge the remaining one with the global state
 * TODO: i think in the future this action should be called merge map layers with global settings
 * @param state
 * @param action
 * @returns {*}
 */


function closeSpecificMapAtIndex(state, action) {
  // retrieve layers meta data from the remaining map that we need to keep
  var indexToRetrieve = 1 - action.payload;
  var metaSettings = state.splitMaps[indexToRetrieve];

  if (!metaSettings || !metaSettings.layers) {
    // if we can't find the meta settings we simply clean up splitMaps and
    // keep global state as it is
    // but why does this ever happen?
    return _objectSpread({}, state, {
      splitMaps: []
    });
  }

  var layers = state.layers; // update layer visibility

  var newLayers = layers.map(function (layer) {
    return layer.updateLayerConfig({
      isVisible: metaSettings.layers[layer.id] ? metaSettings.layers[layer.id].isVisible : layer.config.isVisible
    });
  }); // delete map

  return _objectSpread({}, state, {
    layers: newLayers,
    splitMaps: []
  });
} // TODO: redo write handler to not use tasks


var loadFilesUpdater = function loadFilesUpdater(state, action) {
  var files = action.files;
  var filesToLoad = files.map(function (fileBlob) {
    return (0, _fileUtils.processFileToLoad)(fileBlob, fileBlob.id);
  }); // reader -> parser -> augment -> receiveVisData

  var loadFileTasks = [_tasks["default"].all(filesToLoad.map(_tasks2.LOAD_FILE_TASK)).bimap(function (results) {
    var data = results.reduce(function (f, c) {
      return {
        // using concat here because the current datasets could be an array or a single item
        datasets: f.datasets.concat(c.datasets),
        // we need to deep merge this thing unless we find a better solution
        // this case will only happen if we allow to load multiple keplergl json files
        config: _objectSpread({}, f.config, {}, c.config || {})
      };
    }, {
      datasets: [],
      config: {},
      options: {
        centerMap: true
      }
    });
    return (0, _actions.addDataToMap)(data);
  }, function (error) {
    return (0, _visStateActions.loadFilesErr)(error);
  })];
  return (0, _tasks.withTask)(_objectSpread({}, state, {
    fileLoading: true
  }), loadFileTasks);
};

exports.loadFilesUpdater = loadFilesUpdater;

var loadFilesErrUpdater = function loadFilesErrUpdater(state, _ref11) {
  var error = _ref11.error;
  return _objectSpread({}, state, {
    fileLoading: false,
    fileLoadingErr: error
  });
};
/**
 * helper function to update All layer domain and layer data of state
 *
 * @param {object} state
 * @param {string} datasets
 * @returns {object} state
 */


exports.loadFilesErrUpdater = loadFilesErrUpdater;

function addDefaultLayers(state, datasets) {
  var defaultLayers = Object.values(datasets).reduce(function (accu, dataset) {
    return [].concat((0, _toConsumableArray2["default"])(accu), (0, _toConsumableArray2["default"])((0, _layerUtils.findDefaultLayer)(dataset, state.layerClasses) || []));
  }, []);
  return _objectSpread({}, state, {
    layers: [].concat((0, _toConsumableArray2["default"])(state.layers), (0, _toConsumableArray2["default"])(defaultLayers)),
    layerOrder: [].concat((0, _toConsumableArray2["default"])(defaultLayers.map(function (_, i) {
      return state.layers.length + i;
    })), (0, _toConsumableArray2["default"])(state.layerOrder))
  });
}
/**
 * helper function to update All layer domain and layer data of state
 *
 * @param {object} state
 * @param {string} datasets
 * @returns {object} state
 */
// export function addDefaultWidget(state, datasets) {
//   const defaultWidget = Object.values(datasets).reduce(
//     (accu, dataset) => [
//       ...accu,
//       ...(findDefaultLayer(dataset, state.widgetClasses) || [])
//     ],
//     []
//   );
//   return {
//     ...state,
//     widgets: [...state.widgets, ...defaultWidget],
//     layerOrder: [
//       // put new layers on top of old ones
//       ...defaultWidget.map((_, i) => state.widgets.length + i),
//       ...state.widgetOrder
//     ]
//   };
// }

/**
 * helper function to find default tooltips
 *
 * @param {object} state
 * @param {object} dataset
 * @returns {object} state
 */


function addDefaultTooltips(state, dataset) {
  var tooltipFields = (0, _interactionUtils.findFieldsToShow)(dataset);
  return _objectSpread({}, state, {
    interactionConfig: _objectSpread({}, state.interactionConfig, {
      tooltip: _objectSpread({}, state.interactionConfig.tooltip, {
        config: {
          // find default fields to show in tooltip
          fieldsToShow: _objectSpread({}, state.interactionConfig.tooltip.config.fieldsToShow, {}, tooltipFields)
        }
      })
    })
  });
}
/**
 * helper function to update layer domains for an array of datsets
 *
 * @param {object} state
 * @param {array | string} dataId
 * @param {object} newFilter - if is called by setFilter, the filter that has changed
 * @returns {object} state
 */


function updateAllLayerDomainData(state, dataId, newFilter) {
  var dataIds = typeof dataId === 'string' ? [dataId] : dataId;
  var newLayers = [];
  var newLayerDatas = [];
  state.layers.forEach(function (oldLayer, i) {
    if (oldLayer.config.dataId && dataIds.includes(oldLayer.config.dataId)) {
      // No need to recalculate layer domain if filter has fixed domain
      var newLayer;

      if (oldLayer.type === 'boundary') {
        newLayer = newFilter && newFilter.fixedDomain ? oldLayer : oldLayer.updateLayerDomain(state.datasets[oldLayer.config.dataId], state.layerData[i], newFilter);
      } else {
        newLayer = newFilter && newFilter.fixedDomain ? oldLayer : oldLayer.updateLayerDomain(state.datasets[oldLayer.config.dataId], newFilter);
      }

      var _calculateLayerData5 = (0, _layerUtils.calculateLayerData)(newLayer, state, state.layerData[i]),
          layerData = _calculateLayerData5.layerData,
          layer = _calculateLayerData5.layer; // let data = layer.axiosApiCall();
      // console.log(data);
      //   if (layer.type === 'boundary') {
      //     // console.log('reaching data');
      //     data.then(function(result) {
      //       // console.log('promise result', result);
      //       // const testData = layer.formatLayer();
      //       var {layerData, layer} = calculateLayerDataAfterAPICall(
      //         newLayer,
      //         state,
      //         layerData,
      //         result
      //       );
      //       // console.log('filtered layerData and layer', layerData, layer);
      //       layerData = {
      //         ...layerData,
      //         result
      //       };
      //       newLayers[i] = layer;
      //       newLayerDatas[i] = layerData;
      //       // console.log('return inside api call', newLayers, newLayerDatas);
      //       // return {
      //       //   ...state,
      //       //   layers: {
      //       //     ...state.layers,
      //       //     [state.layers[i]]: layer
      //       //   },
      //       //   layerData: {
      //       //     ...state.layerData,
      //       //     [state.layerData[i]]: layerData
      //       //   }
      //       // };
      //     });
      //   }
      //   // console.log('filtered State', state);
      //   // console.log(layerData);


      newLayers.push(layer);
      newLayerDatas.push(layerData);
    } else {
      newLayers.push(oldLayer);
      newLayerDatas.push(state.layerData[i]);
    }
  }); // console.log('new layers and layer data', newLayers, newLayerDatas);
  // console.log('return inside updateAllDataDomain ');

  return _objectSpread({}, state, {
    layers: newLayers,
    layerData: newLayerDatas
  });
}
/**
 * helper function to recalculte widget aggregationData everytime layerData is updated
 *
 * @param {object} state
 * @returns {object} state
 */


function updateWidgetAggregationData(state) {
  var widgets = state.widgets;
  var newWidgets = [];
  widgets.map(function (w) {
    var _w$calculateAggregati = w.calculateAggregationData(w, state),
        newWidget = _w$calculateAggregati.newWidget;

    newWidgets.push(newWidget);
  });
  return _objectSpread({}, state, {
    widgets: newWidgets
  });
}
/**
 * helper function to update states
 *
 * @param {object} state
 * @returns {object} state
 */


function updateStateWithLayerDataUpdater(state, action) {
  var collected = action.collected;
  var newLayer = action.layer;
  var idx = state.layers.findIndex(function (l) {
    return l.id === newLayer.id;
  });

  var _calculateLayerDataAf = (0, _layerUtils.calculateLayerDataAfterAPICall)(newLayer, state, state.layerData[idx], collected, {
    sameData: true
  }),
      layerData = _calculateLayerDataAf.layerData,
      layer = _calculateLayerDataAf.layer;

  return _objectSpread({}, state, {
    layerData: state.layerData.map(function (lyrData, i) {
      return i === idx ? layerData : lyrData;
    })
  });
}
/**
 * helper function for async API call
 *
 * @param {object} state
 * @returns {object} data
 */


function apiCallData(state, action) {
  // console.log(state, action);
  var layer = action.layer;
  var allData = state.datasets[layer.config.dataId].allData; // console.log(allData);

  return state;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy92aXMtc3RhdGUtdXBkYXRlcnMuanMiXSwibmFtZXMiOlsiSU5JVElBTF9WSVNfU1RBVEUiLCJsYXllcnMiLCJsYXllckRhdGEiLCJsYXllclRvQmVNZXJnZWQiLCJsYXllck9yZGVyIiwiZmlsdGVycyIsImZpbHRlclRvQmVNZXJnZWQiLCJ3aWRnZXRzIiwid2lkZ2V0VG9CZU1lcmdlZCIsIndpZGdldE9yZGVyIiwiZGF0YXNldHMiLCJlZGl0aW5nRGF0YXNldCIsInVuZGVmaW5lZCIsImludGVyYWN0aW9uQ29uZmlnIiwiaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkIiwibGF5ZXJCbGVuZGluZyIsImhvdmVySW5mbyIsImNsaWNrZWQiLCJmaWxlTG9hZGluZyIsImZpbGVMb2FkaW5nRXJyIiwic3BsaXRNYXBzIiwibGF5ZXJDbGFzc2VzIiwiTGF5ZXJDbGFzc2VzIiwid2lkZ2V0Q2xhc3NlcyIsIldpZGdldENsYXNzZXMiLCJ1cGRhdGVTdGF0ZVdpdGhXaWRnZXRBbmREYXRhIiwic3RhdGUiLCJ3aWRnZXQiLCJpZHgiLCJtYXAiLCJ3ZGd0IiwiaSIsIndpZGdldENvbmZpZ0NoYW5nZVVwZGF0ZXIiLCJhY3Rpb24iLCJvbGRXaWRnZXQiLCJtYXBTdGF0ZSIsIm5ld0NvbmZpZyIsIngiLCJmaW5kSW5kZXgiLCJ3IiwiaWQiLCJwcm9wcyIsIk9iamVjdCIsImtleXMiLCJuZXdXaWRnZXQiLCJ1cGRhdGVXaWRnZXRDb25maWciLCJzaG91bGRDYWxjdWxhdGVBZ2dyZWdhdGVkRGF0YSIsImNhbGN1bGF0ZUFnZ3JlZ2F0aW9uRGF0YSIsInVwZGF0ZWRTdGF0ZSIsIm5ld1N0YXRlIiwidG9nZ2xlV2lkZ2V0RnJvbVNwbGl0TWFwcyIsIndpZGdldFR5cGVDaGFuZ2VVcGRhdGVyIiwibmV3VHlwZSIsIm9sZElkIiwiQ29uc29sZSIsImVycm9yIiwiY29uZmlnIiwiYWdncmVnYXRlZERhdGEiLCJhc3NpZ25Db25maWdUb1dpZGdldCIsInZpc0NvbmZpZ1NldHRpbmdzIiwidXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhIiwibGF5ZXIiLCJseXIiLCJkIiwibGF5ZXJDb25maWdDaGFuZ2VVcGRhdGVyIiwib2xkTGF5ZXIiLCJsIiwibmV3TGF5ZXIiLCJ1cGRhdGVMYXllckNvbmZpZyIsInNob3VsZENhbGN1bGF0ZUxheWVyRGF0YSIsIm9sZExheWVyRGF0YSIsInNhbWVEYXRhIiwidG9nZ2xlTGF5ZXJGcm9tU3BsaXRNYXBzIiwibGF5ZXJUeXBlQ2hhbmdlVXBkYXRlciIsImFzc2lnbkNvbmZpZ1RvTGF5ZXIiLCJkYXRhSWQiLCJkYXRhc2V0IiwidXBkYXRlTGF5ZXJEb21haW4iLCJzZWxlY3RlZExheWVyIiwidHlwZSIsInNldHRpbmdzIiwib2xkTGF5ZXJNYXAiLCJvdGhlckxheWVycyIsImxheWVyVmlzdWFsQ2hhbm5lbENoYW5nZVVwZGF0ZXIiLCJjaGFubmVsIiwidXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsIiwibGF5ZXJWaXNDb25maWdDaGFuZ2VVcGRhdGVyIiwibmV3VmlzQ29uZmlnIiwidmlzQ29uZmlnIiwiaW50ZXJhY3Rpb25Db25maWdDaGFuZ2VVcGRhdGVyIiwiZW5hYmxlZCIsImZvckVhY2giLCJrIiwic2V0RmlsdGVyVXBkYXRlciIsInByb3AiLCJ2YWx1ZSIsIm5ld0ZpbHRlciIsImZpZWxkcyIsImFsbERhdGEiLCJmaWVsZElkeCIsImYiLCJuYW1lIiwiZmllbGQiLCJmaWx0ZXJQcm9wIiwiZnJlZXplIiwiZW5sYXJnZWRGaWx0ZXJJZHgiLCJlbmxhcmdlZCIsInVwZGF0ZUFsbExheWVyRG9tYWluRGF0YSIsInVwZGF0ZVdpZGdldEFnZ3JlZ2F0aW9uRGF0YSIsInNldEZpbHRlclBsb3RVcGRhdGVyIiwibmV3UHJvcCIsInBsb3RUeXBlIiwiYWRkRmlsdGVyVXBkYXRlciIsInRvZ2dsZUZpbHRlckFuaW1hdGlvblVwZGF0ZXIiLCJpc0FuaW1hdGluZyIsInVwZGF0ZUFuaW1hdGlvblNwZWVkVXBkYXRlciIsInNwZWVkIiwiZW5sYXJnZUZpbHRlclVwZGF0ZXIiLCJpc0VubGFyZ2VkIiwicmVtb3ZlRmlsdGVyVXBkYXRlciIsIm5ld0ZpbHRlcnMiLCJzbGljZSIsImxlbmd0aCIsImFkZFdpZGdldFVwZGF0ZXIiLCJkZWZhdWx0RGF0YXNldCIsIldpZGdldCIsImlzVmlzaWJsZSIsImlzQ29uZmlnQWN0aXZlIiwicmVtb3ZlV2lkZ2V0VXBkYXRlciIsImZpbHRlciIsInBpZCIsInJlb3JkZXJXaWRnZXRVcGRhdGVyIiwib3JkZXIiLCJhZGRMYXllclVwZGF0ZXIiLCJMYXllciIsImFkZE5ld0xheWVyc1RvU3BsaXRNYXAiLCJyZW1vdmVMYXllclVwZGF0ZXIiLCJsYXllclRvUmVtb3ZlIiwibmV3TWFwcyIsInJlbW92ZUxheWVyRnJvbVNwbGl0TWFwcyIsInJlbW92ZVdpZGdldHNPbkxheWVyIiwiaXNMYXllckhvdmVyZWQiLCJyZW9yZGVyTGF5ZXJVcGRhdGVyIiwicmVtb3ZlRGF0YXNldFVwZGF0ZXIiLCJkYXRhc2V0S2V5Iiwia2V5IiwibmV3RGF0YXNldHMiLCJpbmRleGVzIiwicmVkdWNlIiwibGlzdE9mSW5kZXhlcyIsImluZGV4IiwicHVzaCIsImN1cnJlbnRTdGF0ZSIsImluZGV4Q291bnRlciIsImN1cnJlbnRJbmRleCIsInRvb2x0aXAiLCJmaWVsZHNUb1Nob3ciLCJ1cGRhdGVMYXllckJsZW5kaW5nVXBkYXRlciIsIm1vZGUiLCJzaG93RGF0YXNldFRhYmxlVXBkYXRlciIsInJlc2V0TWFwQ29uZmlnVmlzU3RhdGVVcGRhdGVyIiwiaW5pdGlhbFN0YXRlIiwicmVjZWl2ZU1hcENvbmZpZ1VwZGF0ZXIiLCJwYXlsb2FkIiwidmlzU3RhdGUiLCJyZXNldFN0YXRlIiwibWVyZ2VkU3RhdGUiLCJsYXllckhvdmVyVXBkYXRlciIsImluZm8iLCJsYXllckNsaWNrVXBkYXRlciIsInBpY2tlZCIsIm1hcENsaWNrVXBkYXRlciIsInRvZ2dsZVNwbGl0TWFwVXBkYXRlciIsImNvbXB1dGVTcGxpdE1hcExheWVycyIsImNsb3NlU3BlY2lmaWNNYXBBdEluZGV4Iiwic2V0VmlzaWJsZUxheWVyc0Zvck1hcFVwZGF0ZXIiLCJtYXBJbmRleCIsImxheWVySWRzIiwibmV3TGF5ZXJzIiwiY3VycmVudExheWVycyIsImluY2x1ZGVzIiwidG9nZ2xlTGF5ZXJGb3JNYXBVcGRhdGVyIiwibWFwU2V0dGluZ3MiLCJsYXllcklkIiwibmV3U3BsaXRNYXBzIiwidXBkYXRlVmlzRGF0YVVwZGF0ZXIiLCJBcnJheSIsImlzQXJyYXkiLCJuZXdEYXRlRW50cmllcyIsImFjY3UiLCJkYXRhIiwic3RhdGVXaXRoTmV3RGF0YSIsIm9wdGlvbnMiLCJkaXNhYmxlZEFkZERlZmF1bHRMYXllcnMiLCJhZGREZWZhdWx0TGF5ZXJzIiwidG9vbHRpcEZpZWxkcyIsImFkZERlZmF1bHRUb29sdGlwcyIsImdlbmVyYXRlTGF5ZXJNZXRhRm9yU3BsaXRWaWV3cyIsImlzQXZhaWxhYmxlIiwibWFwTGF5ZXJzIiwiY3VycmVudExheWVyIiwiXyIsImFkZE5ld1dpZGdldHNUb1NwbGl0TWFwIiwibmV3V2lkZ2V0cyIsImluZGV4VG9SZXRyaWV2ZSIsIm1ldGFTZXR0aW5ncyIsImxvYWRGaWxlc1VwZGF0ZXIiLCJmaWxlcyIsImZpbGVzVG9Mb2FkIiwiZmlsZUJsb2IiLCJsb2FkRmlsZVRhc2tzIiwiVGFzayIsImFsbCIsIkxPQURfRklMRV9UQVNLIiwiYmltYXAiLCJyZXN1bHRzIiwiYyIsImNvbmNhdCIsImNlbnRlck1hcCIsImxvYWRGaWxlc0VyclVwZGF0ZXIiLCJkZWZhdWx0TGF5ZXJzIiwidmFsdWVzIiwiZGF0YUlkcyIsIm5ld0xheWVyRGF0YXMiLCJmaXhlZERvbWFpbiIsInVwZGF0ZVN0YXRlV2l0aExheWVyRGF0YVVwZGF0ZXIiLCJjb2xsZWN0ZWQiLCJseXJEYXRhIiwiYXBpQ2FsbERhdGEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFHQTs7QUFHQTs7QUFDQTs7QUFHQTs7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QUFDQSxTQUFPeEUsS0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDE5IFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHtjb25zb2xlIGFzIENvbnNvbGV9IGZyb20gJ2dsb2JhbC93aW5kb3cnO1xuaW1wb3J0IFRhc2ssIHtkaXNhYmxlU3RhY2tDYXB0dXJpbmcsIHdpdGhUYXNrfSBmcm9tICdyZWFjdC1wYWxtL3Rhc2tzJztcblxuLy8gVGFza3NcbmltcG9ydCB7TE9BRF9GSUxFX1RBU0t9IGZyb20gJ3Rhc2tzL3Rhc2tzJztcblxuLy8gQWN0aW9uc1xuaW1wb3J0IHtsb2FkRmlsZXNFcnJ9IGZyb20gJ2FjdGlvbnMvdmlzLXN0YXRlLWFjdGlvbnMnO1xuaW1wb3J0IHthZGREYXRhVG9NYXB9IGZyb20gJ2FjdGlvbnMnO1xuXG4vLyBVdGlsc1xuaW1wb3J0IHtnZXREZWZhdWx0SW50ZXJhY3Rpb24sIGZpbmRGaWVsZHNUb1Nob3d9IGZyb20gJ3V0aWxzL2ludGVyYWN0aW9uLXV0aWxzJztcbmltcG9ydCB7XG4gIGdldERlZmF1bHRGaWx0ZXIsXG4gIGdldEZpbHRlclByb3BzLFxuICBnZXRGaWx0ZXJQbG90LFxuICBnZXREZWZhdWx0RmlsdGVyUGxvdFR5cGUsXG4gIGZpbHRlckRhdGFcbn0gZnJvbSAndXRpbHMvZmlsdGVyLXV0aWxzJztcbmltcG9ydCB7Y3JlYXRlTmV3RGF0YUVudHJ5fSBmcm9tICd1dGlscy9kYXRhc2V0LXV0aWxzJztcblxuaW1wb3J0IHtcbiAgZmluZERlZmF1bHRMYXllcixcbiAgY2FsY3VsYXRlTGF5ZXJEYXRhLFxuICBjYWxjdWxhdGVMYXllckRhdGFBZnRlckFQSUNhbGxcbn0gZnJvbSAndXRpbHMvbGF5ZXItdXRpbHMvbGF5ZXItdXRpbHMnO1xuXG5pbXBvcnQge2NhbGN1bGF0ZUFnZ3JlZ2F0aW9uRGF0YX0gZnJvbSAndXRpbHMvd2lkZ2V0LXV0aWxzL3dpZGdldC11dGlscyc7XG5cbmltcG9ydCB7XG4gIG1lcmdlRmlsdGVycyxcbiAgbWVyZ2VMYXllcnMsXG4gIG1lcmdlSW50ZXJhY3Rpb25zLFxuICBtZXJnZVdpZGdldHMsXG4gIG1lcmdlTGF5ZXJCbGVuZGluZ1xufSBmcm9tICcuL3Zpcy1zdGF0ZS1tZXJnZXInO1xuXG4vLyBMYXllckNsYXNzZXMgY29udGFpbiBFUzYgQ2xhc3MsIGRvIG5vdCBpbnN0YXRpYXRlIGluIGlzbyByZW5kZXJpbmdcbi8vIGNvbnN0IHtMYXllckNsYXNzZXN9ID0gaXNCcm93c2VyIHx8IGlzVGVzdGluZyA/XG4vLyAgIHJlcXVpcmUoJ2xheWVycycpIDoge1xuLy8gICAgIExheWVyQ2xhc3Nlczoge31cbi8vICAgfTtcblxuaW1wb3J0IHNpbXBsaWZ5IGZyb20gJ3NpbXBsaWZ5LWdlb2pzb24nO1xuXG5pbXBvcnQge0xheWVyLCBMYXllckNsYXNzZXN9IGZyb20gJ2xheWVycyc7XG5pbXBvcnQge1dpZGdldCwgV2lkZ2V0Q2xhc3Nlc30gZnJvbSAnd2lkZ2V0cyc7XG5pbXBvcnQge3Byb2Nlc3NGaWxlVG9Mb2FkfSBmcm9tICcvdXRpbHMvZmlsZS11dGlscyc7XG5pbXBvcnQge2FnZ3JlZ2F0ZX0gZnJvbSAndXRpbHMvYWdncmVnYXRlLXV0aWxzJztcbmltcG9ydCB7dmFsaWRhdGVJZH0gZnJvbSAnQHR1cmYvaGVscGVycyc7XG4vLyBpbXBvcnQgV2lkZ2V0Q29uZmlndXJhdG9yIGZyb20gJ2NvbXBvbmVudHMvc2lkZS1wYW5lbC93aWRnZXQtcGFuZWwvd2lkZ2V0LWNvbmZpZ3VyYXRvcic7XG5cbi8vIHJlYWN0LXBhbG1cbi8vIGRpc2FibGUgY2FwdHVyZSBleGNlcHRpb24gZm9yIHJlYWN0LXBhbG0gY2FsbCB0byB3aXRoVGFza1xuZGlzYWJsZVN0YWNrQ2FwdHVyaW5nKCk7XG5cbmV4cG9ydCBjb25zdCBJTklUSUFMX1ZJU19TVEFURSA9IHtcbiAgLy8gbGF5ZXJzXG4gIGxheWVyczogW10sXG4gIGxheWVyRGF0YTogW10sXG4gIGxheWVyVG9CZU1lcmdlZDogW10sXG4gIGxheWVyT3JkZXI6IFtdLFxuXG4gIC8vIGZpbHRlcnNcbiAgZmlsdGVyczogW10sXG4gIGZpbHRlclRvQmVNZXJnZWQ6IFtdLFxuXG4gIC8vd2lkZ2V0c1xuICB3aWRnZXRzOiBbXSxcbiAgd2lkZ2V0VG9CZU1lcmdlZDogW10sXG4gIHdpZGdldE9yZGVyOiBbXSxcblxuICAvLyBhIGNvbGxlY3Rpb24gb2YgbXVsdGlwbGUgZGF0YXNldFxuICBkYXRhc2V0czoge30sXG4gIGVkaXRpbmdEYXRhc2V0OiB1bmRlZmluZWQsXG5cbiAgaW50ZXJhY3Rpb25Db25maWc6IGdldERlZmF1bHRJbnRlcmFjdGlvbigpLFxuICBpbnRlcmFjdGlvblRvQmVNZXJnZWQ6IHVuZGVmaW5lZCxcblxuICBsYXllckJsZW5kaW5nOiAnbm9ybWFsJyxcbiAgaG92ZXJJbmZvOiB1bmRlZmluZWQsXG4gIGNsaWNrZWQ6IHVuZGVmaW5lZCxcblxuICBmaWxlTG9hZGluZzogZmFsc2UsXG4gIGZpbGVMb2FkaW5nRXJyOiBudWxsLFxuXG4gIC8vIHRoaXMgaXMgdXNlZCB3aGVuIHVzZXIgc3BsaXQgbWFwc1xuICBzcGxpdE1hcHM6IFtcbiAgICAvLyB0aGlzIHdpbGwgY29udGFpbiBhIGxpc3Qgb2Ygb2JqZWN0cyB0b1xuICAgIC8vIGRlc2NyaWJlIHRoZSBzdGF0ZSBvZiBsYXllciBhdmFpbGFiaWxpdHkgYW5kIHZpc2liaWxpdHkgZm9yIGVhY2ggbWFwXG4gICAgLy8gW1xuICAgIC8vICAge1xuICAgIC8vICAgICBsYXllcnM6IHtcbiAgICAvLyAgICAgICBsYXllcl9pZDoge1xuICAgIC8vICAgICAgICAgaXNBdmFpbGFibGU6IHRydWV8ZmFsc2UgIyB0aGlzIGlzIGRyaXZlbiBieSB0aGUgbGVmdCBoYW5kIHBhbmVsXG4gICAgLy8gICAgICAgICBpc1Zpc2libGU6IHRydWV8ZmFsc2VcbiAgICAvLyAgICAgICB9XG4gICAgLy8gICAgIH1cbiAgICAvLyAgIH1cbiAgICAvLyBdXG4gIF0sXG5cbiAgLy8gZGVmYXVsdHMgbGF5ZXIgY2xhc3Nlc1xuICBsYXllckNsYXNzZXM6IExheWVyQ2xhc3NlcyxcblxuICAvL2RlZmF1bHQgd2lkZ2V0IGNsYXNzZXNcbiAgd2lkZ2V0Q2xhc3NlczogV2lkZ2V0Q2xhc3Nlc1xufTtcblxuZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoV2lkZ2V0QW5kRGF0YShzdGF0ZSwge3dpZGdldCwgaWR4fSkge1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIHdpZGdldHM6IHN0YXRlLndpZGdldHMubWFwKCh3ZGd0LCBpKSA9PiAoaSA9PT0gaWR4ID8gd2lkZ2V0IDogd2RndCkpXG4gIH07XG59XG5cbi8qKlxuICogQ2FsbGVkIHRvIHVwZGF0ZSBsYXllciBiYXNlIGNvbmZpZzogZGF0YUlkLCBsYWJlbCwgY29sdW1uLCBpc1Zpc2libGVcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aWRnZXRDb25maWdDaGFuZ2VVcGRhdGVyKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge29sZFdpZGdldH0gPSBhY3Rpb247XG4gIGNvbnN0IHttYXBTdGF0ZX0gPSBhY3Rpb24ubmV3Q29uZmlnO1xuICBjb25zdCB4ID0gc3RhdGUud2lkZ2V0cy5maW5kSW5kZXgodyA9PiB3LmlkID09PSBvbGRXaWRnZXQuaWQpO1xuICBjb25zdCBwcm9wcyA9IE9iamVjdC5rZXlzKGFjdGlvbi5uZXdDb25maWcpO1xuICBhY3Rpb24ubmV3Q29uZmlnLm1hcFN0YXRlID8gZGVsZXRlIGFjdGlvbi5uZXdDb25maWcubWFwU3RhdGUgOiBudWxsO1xuICBjb25zdCBuZXdXaWRnZXQgPSBvbGRXaWRnZXQudXBkYXRlV2lkZ2V0Q29uZmlnKGFjdGlvbi5uZXdDb25maWcpO1xuICBpZiAobmV3V2lkZ2V0LnNob3VsZENhbGN1bGF0ZUFnZ3JlZ2F0ZWREYXRhKHByb3BzKSkge1xuICAgIGNvbnN0IHt1cGRhdGVkU3RhdGV9ID0gbmV3V2lkZ2V0LmNhbGN1bGF0ZUFnZ3JlZ2F0aW9uRGF0YShcbiAgICAgIG5ld1dpZGdldCxcbiAgICAgIHN0YXRlLFxuICAgICAgbWFwU3RhdGVcbiAgICApO1xuICAgIHJldHVybiB1cGRhdGVTdGF0ZVdpdGhXaWRnZXRBbmREYXRhKHVwZGF0ZWRTdGF0ZSA/IHVwZGF0ZWRTdGF0ZSA6IHN0YXRlLCB7XG4gICAgICB3aWRnZXQ6IG5ld1dpZGdldCxcbiAgICAgIHhcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIHNwbGl0TWFwczpcbiAgICAgICdpc1Zpc2libGUnIGluIGFjdGlvbi5uZXdDb25maWdcbiAgICAgICAgPyB0b2dnbGVXaWRnZXRGcm9tU3BsaXRNYXBzKHN0YXRlLCB3aWRnZXQpXG4gICAgICAgIDogc3RhdGUuc3BsaXRNYXBzXG4gIH07XG4gIHJldHVybiB1cGRhdGVTdGF0ZVdpdGhXaWRnZXRBbmREYXRhKG5ld1N0YXRlLCB7d2lkZ2V0OiBuZXdXaWRnZXQsIHh9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdpZGdldFR5cGVDaGFuZ2VVcGRhdGVyKHN0YXRlLCBhY3Rpb24pIHtcbiAgY29uc3Qge29sZFdpZGdldCwgbmV3VHlwZX0gPSBhY3Rpb247XG4gIGNvbnN0IG9sZElkID0gb2xkV2lkZ2V0LmlkO1xuICBjb25zdCBpZHggPSBzdGF0ZS53aWRnZXRzLmZpbmRJbmRleCh3ID0+IHcuaWQgPT09IG9sZElkKTtcbiAgaWYgKCFzdGF0ZS53aWRnZXRDbGFzc2VzW25ld1R5cGVdKSB7XG4gICAgQ29uc29sZS5lcnJvcihgJHtuZXdUeXBlfSBpcyBub3QgYSB2YWxpZCB3aWRnZXQgdHlwZWApO1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuICAvLyBnZXQgYSBtaW50IHdpZGdldCwgd2l0aCBuZXcgaWQgYW5kIHR5cGVcbiAgLy8gYmVjYXVzZSBkZWNrLmdsIHVzZXMgaWQgdG8gbWF0Y2ggYmV0d2VlbiBuZXcgYW5kIG9sZCBsYXllci5cbiAgLy8gSWYgdHlwZSBoYXMgY2hhbmdlZCBidXQgaWQgaXMgdGhlIHNhbWUsIGl0IHdpbGwgYnJlYWtcbiAgdmFyIG5ld1dpZGdldCA9IG5ldyBzdGF0ZS53aWRnZXRDbGFzc2VzW25ld1R5cGVdKCk7XG4gIG5ld1dpZGdldC5jb25maWcuYWdncmVnYXRlZERhdGEgPSBudWxsO1xuICBuZXdXaWRnZXQuYXNzaWduQ29uZmlnVG9XaWRnZXQob2xkV2lkZ2V0LmNvbmZpZywgb2xkV2lkZ2V0LnZpc0NvbmZpZ1NldHRpbmdzKTtcblxuICBsZXQgbmV3U3RhdGUgPSBzdGF0ZTtcbiAgY29uc3Qgd2lkZ2V0ID0gbmV3V2lkZ2V0O1xuICByZXR1cm4gdXBkYXRlU3RhdGVXaXRoV2lkZ2V0QW5kRGF0YShuZXdTdGF0ZSwge3dpZGdldCwgaWR4fSk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN0YXRlV2l0aExheWVyQW5kRGF0YShzdGF0ZSwge2xheWVyRGF0YSwgbGF5ZXIsIGlkeH0pIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBsYXllcnM6IHN0YXRlLmxheWVycy5tYXAoKGx5ciwgaSkgPT4gKGkgPT09IGlkeCA/IGxheWVyIDogbHlyKSksXG4gICAgbGF5ZXJEYXRhOiBsYXllckRhdGFcbiAgICAgID8gc3RhdGUubGF5ZXJEYXRhLm1hcCgoZCwgaSkgPT4gKGkgPT09IGlkeCA/IGxheWVyRGF0YSA6IGQpKVxuICAgICAgOiBzdGF0ZS5sYXllckRhdGFcbiAgfTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgdG8gdXBkYXRlIGxheWVyIGJhc2UgY29uZmlnOiBkYXRhSWQsIGxhYmVsLCBjb2x1bW4sIGlzVmlzaWJsZVxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxheWVyQ29uZmlnQ2hhbmdlVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtvbGRMYXllcn0gPSBhY3Rpb247XG4gIGNvbnN0IGlkeCA9IHN0YXRlLmxheWVycy5maW5kSW5kZXgobCA9PiBsLmlkID09PSBvbGRMYXllci5pZCk7XG4gIGNvbnN0IHByb3BzID0gT2JqZWN0LmtleXMoYWN0aW9uLm5ld0NvbmZpZyk7XG4gIGNvbnN0IG5ld0xheWVyID0gb2xkTGF5ZXIudXBkYXRlTGF5ZXJDb25maWcoYWN0aW9uLm5ld0NvbmZpZyk7XG5cbiAgaWYgKG5ld0xheWVyLnNob3VsZENhbGN1bGF0ZUxheWVyRGF0YShwcm9wcykpIHtcbiAgICBjb25zdCBvbGRMYXllckRhdGEgPSBzdGF0ZS5sYXllckRhdGFbaWR4XTtcbiAgICBjb25zdCB7bGF5ZXJEYXRhLCBsYXllcn0gPSBjYWxjdWxhdGVMYXllckRhdGEoXG4gICAgICBuZXdMYXllcixcbiAgICAgIHN0YXRlLFxuICAgICAgb2xkTGF5ZXJEYXRhLFxuICAgICAge3NhbWVEYXRhOiB0cnVlfVxuICAgICk7XG4gICAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aExheWVyQW5kRGF0YShzdGF0ZSwge2xheWVyRGF0YSwgbGF5ZXIsIGlkeH0pO1xuICB9XG5cbiAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgc3BsaXRNYXBzOlxuICAgICAgJ2lzVmlzaWJsZScgaW4gYWN0aW9uLm5ld0NvbmZpZ1xuICAgICAgICA/IHRvZ2dsZUxheWVyRnJvbVNwbGl0TWFwcyhzdGF0ZSwgbmV3TGF5ZXIpXG4gICAgICAgIDogc3RhdGUuc3BsaXRNYXBzXG4gIH07XG4gIHJldHVybiB1cGRhdGVTdGF0ZVdpdGhMYXllckFuZERhdGEobmV3U3RhdGUsIHtsYXllcjogbmV3TGF5ZXIsIGlkeH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJUeXBlQ2hhbmdlVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtvbGRMYXllciwgbmV3VHlwZX0gPSBhY3Rpb247XG4gIGNvbnN0IG9sZElkID0gb2xkTGF5ZXIuaWQ7XG4gIGNvbnN0IGlkeCA9IHN0YXRlLmxheWVycy5maW5kSW5kZXgobCA9PiBsLmlkID09PSBvbGRJZCk7XG4gIGlmICghc3RhdGUubGF5ZXJDbGFzc2VzW25ld1R5cGVdKSB7XG4gICAgQ29uc29sZS5lcnJvcihgJHtuZXdUeXBlfSBpcyBub3QgYSB2YWxpZCBsYXllciB0eXBlYCk7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLy8gZ2V0IGEgbWludCBsYXllciwgd2l0aCBuZXcgaWQgYW5kIHR5cGVcbiAgLy8gYmVjYXVzZSBkZWNrLmdsIHVzZXMgaWQgdG8gbWF0Y2ggYmV0d2VlbiBuZXcgYW5kIG9sZCBsYXllci5cbiAgLy8gSWYgdHlwZSBoYXMgY2hhbmdlZCBidXQgaWQgaXMgdGhlIHNhbWUsIGl0IHdpbGwgYnJlYWtcbiAgY29uc3QgbmV3TGF5ZXIgPSBuZXcgc3RhdGUubGF5ZXJDbGFzc2VzW25ld1R5cGVdKCk7XG4gIG5ld0xheWVyLmFzc2lnbkNvbmZpZ1RvTGF5ZXIob2xkTGF5ZXIuY29uZmlnLCBvbGRMYXllci52aXNDb25maWdTZXR0aW5ncyk7XG5cbiAgaWYgKG5ld0xheWVyLmNvbmZpZy5kYXRhSWQpIHtcbiAgICBjb25zdCBkYXRhc2V0ID0gc3RhdGUuZGF0YXNldHNbbmV3TGF5ZXIuY29uZmlnLmRhdGFJZF07XG4gICAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oZGF0YXNldCk7XG4gIH1cblxuICBjb25zdCB7bGF5ZXJEYXRhLCBsYXllcn0gPSBjYWxjdWxhdGVMYXllckRhdGEobmV3TGF5ZXIsIHN0YXRlKTtcblxuICBsZXQgbmV3U3RhdGUgPSBzdGF0ZTtcblxuICAvL3VwZGF0ZSB3aWRnZXRzIGxheWVyIGlkXG4gIGlmIChzdGF0ZS53aWRnZXRzKSB7XG4gICAgc3RhdGUud2lkZ2V0cy5tYXAod2lkZ2V0ID0+IHtcbiAgICAgIGNvbnN0IHtjb25maWd9ID0gd2lkZ2V0O1xuICAgICAgY29uc3Qge3NlbGVjdGVkTGF5ZXJ9ID0gY29uZmlnO1xuICAgICAgaWYgKHdpZGdldC50eXBlICYmIHNlbGVjdGVkTGF5ZXIuaWQgPT09IG9sZElkKSB7XG4gICAgICAgIHdpZGdldC51cGRhdGVXaWRnZXRDb25maWcoe1xuICAgICAgICAgIHNlbGVjdGVkTGF5ZXI6IHsuLi5zZWxlY3RlZExheWVyLCBpZDogbmV3TGF5ZXIuaWR9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gdXBkYXRlIHNwbGl0TWFwIGxheWVyIGlkXG4gIGlmIChzdGF0ZS5zcGxpdE1hcHMpIHtcbiAgICBuZXdTdGF0ZSA9IHtcbiAgICAgIC4uLm5ld1N0YXRlLFxuICAgICAgc3BsaXRNYXBzOiBzdGF0ZS5zcGxpdE1hcHMubWFwKHNldHRpbmdzID0+IHtcbiAgICAgICAgY29uc3Qge1tvbGRJZF06IG9sZExheWVyTWFwLCAuLi5vdGhlckxheWVyc30gPSBzZXR0aW5ncy5sYXllcnM7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uc2V0dGluZ3MsXG4gICAgICAgICAgbGF5ZXJzOiB7XG4gICAgICAgICAgICAuLi5vdGhlckxheWVycyxcbiAgICAgICAgICAgIFtsYXllci5pZF06IG9sZExheWVyTWFwXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aExheWVyQW5kRGF0YShuZXdTdGF0ZSwge2xheWVyRGF0YSwgbGF5ZXIsIGlkeH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJWaXN1YWxDaGFubmVsQ2hhbmdlVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtvbGRMYXllciwgbmV3Q29uZmlnLCBjaGFubmVsfSA9IGFjdGlvbjtcbiAgY29uc3QgZGF0YXNldCA9IHN0YXRlLmRhdGFzZXRzW29sZExheWVyLmNvbmZpZy5kYXRhSWRdO1xuXG4gIGNvbnN0IGlkeCA9IHN0YXRlLmxheWVycy5maW5kSW5kZXgobCA9PiBsLmlkID09PSBvbGRMYXllci5pZCk7XG4gIGNvbnN0IG5ld0xheWVyID0gb2xkTGF5ZXIudXBkYXRlTGF5ZXJDb25maWcobmV3Q29uZmlnKTtcblxuICBuZXdMYXllci51cGRhdGVMYXllclZpc3VhbENoYW5uZWwoZGF0YXNldCwgY2hhbm5lbCk7XG5cbiAgY29uc3Qgb2xkTGF5ZXJEYXRhID0gc3RhdGUubGF5ZXJEYXRhW2lkeF07XG4gIGNvbnN0IHtsYXllckRhdGEsIGxheWVyfSA9IGNhbGN1bGF0ZUxheWVyRGF0YShuZXdMYXllciwgc3RhdGUsIG9sZExheWVyRGF0YSwge1xuICAgIHNhbWVEYXRhOiB0cnVlXG4gIH0pO1xuICAvLyBsZXQgZGF0YSA9IGxheWVyLmF4aW9zQXBpQ2FsbCgpO1xuICAvLyBpZiAobGF5ZXIudHlwZSA9PT0gJ2JvdW5kYXJ5Jykge1xuICAvLyAgIGRhdGEudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgLy8gICAgIC8vIGNvbnN0IHRlc3REYXRhID0gbGF5ZXIuZm9ybWF0TGF5ZXIoKTtcbiAgLy8gICAgIHZhciB7bGF5ZXJEYXRhLCBsYXllcn0gPSBjYWxjdWxhdGVMYXllckRhdGFBZnRlckFQSUNhbGwoXG4gIC8vICAgICAgIG5ld0xheWVyLFxuICAvLyAgICAgICBzdGF0ZSxcbiAgLy8gICAgICAgbGF5ZXJEYXRhLFxuICAvLyAgICAgICByZXN1bHRcbiAgLy8gICAgICk7XG4gIC8vICAgICBsYXllckRhdGEgPSB7XG4gIC8vICAgICAgIC4uLmxheWVyRGF0YSxcbiAgLy8gICAgICAgcmVzdWx0XG4gIC8vICAgICB9O1xuICAvLyAgICAgbmV3TGF5ZXJzW2ldID0gbGF5ZXI7XG4gIC8vICAgICBuZXdMYXllckRhdGFzW2ldID0gbGF5ZXJEYXRhO1xuICAvLyAgICAgcmV0dXJuIHtcbiAgLy8gICAgICAgLi4uc3RhdGUsXG4gIC8vICAgICAgIGxheWVyczogbmV3TGF5ZXJzLFxuICAvLyAgICAgICBsYXllckRhdGE6IG5ld0xheWVyRGF0YXNcbiAgLy8gICAgIH07XG4gIC8vICAgfSk7XG4gIC8vIH1cblxuICByZXR1cm4gdXBkYXRlU3RhdGVXaXRoTGF5ZXJBbmREYXRhKHN0YXRlLCB7bGF5ZXJEYXRhLCBsYXllciwgaWR4fSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsYXllclZpc0NvbmZpZ0NoYW5nZVVwZGF0ZXIoc3RhdGUsIGFjdGlvbikge1xuICBjb25zdCB7b2xkTGF5ZXJ9ID0gYWN0aW9uO1xuICBjb25zdCBpZHggPSBzdGF0ZS5sYXllcnMuZmluZEluZGV4KGwgPT4gbC5pZCA9PT0gb2xkTGF5ZXIuaWQpO1xuICBjb25zdCBwcm9wcyA9IE9iamVjdC5rZXlzKGFjdGlvbi5uZXdWaXNDb25maWcpO1xuXG4gIGNvbnN0IG5ld1Zpc0NvbmZpZyA9IHtcbiAgICAuLi5vbGRMYXllci5jb25maWcudmlzQ29uZmlnLFxuICAgIC4uLmFjdGlvbi5uZXdWaXNDb25maWdcbiAgfTtcbiAgY29uc3QgbmV3TGF5ZXIgPSBvbGRMYXllci51cGRhdGVMYXllckNvbmZpZyh7dmlzQ29uZmlnOiBuZXdWaXNDb25maWd9KTtcbiAgaWYgKG5ld0xheWVyLnNob3VsZENhbGN1bGF0ZUxheWVyRGF0YShwcm9wcykpIHtcbiAgICBjb25zdCBvbGRMYXllckRhdGEgPSBzdGF0ZS5sYXllckRhdGFbaWR4XTtcbiAgICBjb25zdCB7bGF5ZXJEYXRhLCBsYXllcn0gPSBjYWxjdWxhdGVMYXllckRhdGEoXG4gICAgICBuZXdMYXllcixcbiAgICAgIHN0YXRlLFxuICAgICAgb2xkTGF5ZXJEYXRhLFxuICAgICAge3NhbWVEYXRhOiB0cnVlfVxuICAgICk7XG4gICAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aExheWVyQW5kRGF0YShzdGF0ZSwge2xheWVyRGF0YSwgbGF5ZXIsIGlkeH0pO1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aExheWVyQW5kRGF0YShzdGF0ZSwge2xheWVyOiBuZXdMYXllciwgaWR4fSk7XG59XG5cbi8qIGVzbGludC1lbmFibGUgbWF4LXN0YXRlbWVudHMgKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyYWN0aW9uQ29uZmlnQ2hhbmdlVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtjb25maWd9ID0gYWN0aW9uO1xuXG4gIGNvbnN0IGludGVyYWN0aW9uQ29uZmlnID0ge1xuICAgIC4uLnN0YXRlLmludGVyYWN0aW9uQ29uZmlnLFxuICAgIC4uLntbY29uZmlnLmlkXTogY29uZmlnfVxuICB9O1xuXG4gIGlmIChjb25maWcuZW5hYmxlZCAmJiAhc3RhdGUuaW50ZXJhY3Rpb25Db25maWdbY29uZmlnLmlkXS5lbmFibGVkKSB7XG4gICAgLy8gb25seSBlbmFibGUgb25lIGludGVyYWN0aW9uIGF0IGEgdGltZVxuICAgIE9iamVjdC5rZXlzKGludGVyYWN0aW9uQ29uZmlnKS5mb3JFYWNoKGsgPT4ge1xuICAgICAgaWYgKGsgIT09IGNvbmZpZy5pZCkge1xuICAgICAgICBpbnRlcmFjdGlvbkNvbmZpZ1trXSA9IHsuLi5pbnRlcmFjdGlvbkNvbmZpZ1trXSwgZW5hYmxlZDogZmFsc2V9O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBpbnRlcmFjdGlvbkNvbmZpZ1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0RmlsdGVyVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtpZHgsIHByb3AsIHZhbHVlfSA9IGFjdGlvbjtcbiAgbGV0IG5ld1N0YXRlID0gc3RhdGU7XG4gIGxldCBuZXdGaWx0ZXIgPSB7XG4gICAgLi4uc3RhdGUuZmlsdGVyc1tpZHhdLFxuICAgIFtwcm9wXTogdmFsdWVcbiAgfTtcblxuICBjb25zdCB7ZGF0YUlkfSA9IG5ld0ZpbHRlcjtcbiAgaWYgKCFkYXRhSWQpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cbiAgY29uc3Qge2ZpZWxkcywgYWxsRGF0YX0gPSBzdGF0ZS5kYXRhc2V0c1tkYXRhSWRdO1xuXG4gIHN3aXRjaCAocHJvcCkge1xuICAgIGNhc2UgJ2RhdGFJZCc6XG4gICAgICAvLyBpZiB0cnlpbmcgdG8gdXBkYXRlIGZpbHRlciBkYXRhSWQuIGNyZWF0ZSBhbiBlbXB0eSBuZXcgZmlsdGVyXG4gICAgICBuZXdGaWx0ZXIgPSBnZXREZWZhdWx0RmlsdGVyKGRhdGFJZCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ25hbWUnOlxuICAgICAgLy8gZmluZCB0aGUgZmllbGRcbiAgICAgIGNvbnN0IGZpZWxkSWR4ID0gZmllbGRzLmZpbmRJbmRleChmID0+IGYubmFtZSA9PT0gdmFsdWUpO1xuICAgICAgbGV0IGZpZWxkID0gZmllbGRzW2ZpZWxkSWR4XTtcblxuICAgICAgaWYgKCFmaWVsZC5maWx0ZXJQcm9wKSB7XG4gICAgICAgIC8vIGdldCBmaWx0ZXIgZG9tYWluIGZyb20gZmllbGRcbiAgICAgICAgLy8gc2F2ZSBmaWx0ZXJQcm9wczoge2RvbWFpbiwgc3RlcHMsIHZhbHVlfSB0byBmaWVsZCwgYXZvaWQgcmVjYWxjdWxhdGVcbiAgICAgICAgZmllbGQgPSB7XG4gICAgICAgICAgLi4uZmllbGQsXG4gICAgICAgICAgZmlsdGVyUHJvcDogZ2V0RmlsdGVyUHJvcHMoYWxsRGF0YSwgZmllbGQpXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIG5ld0ZpbHRlciA9IHtcbiAgICAgICAgLi4ubmV3RmlsdGVyLFxuICAgICAgICAuLi5maWVsZC5maWx0ZXJQcm9wLFxuICAgICAgICBuYW1lOiBmaWVsZC5uYW1lLFxuICAgICAgICAvLyBjYW4ndCBlZGl0IGRhdGFJZCBvbmNlIG5hbWUgaXMgc2VsZWN0ZWRcbiAgICAgICAgZnJlZXplOiB0cnVlLFxuICAgICAgICBmaWVsZElkeFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGVubGFyZ2VkRmlsdGVySWR4ID0gc3RhdGUuZmlsdGVycy5maW5kSW5kZXgoZiA9PiBmLmVubGFyZ2VkKTtcbiAgICAgIGlmIChlbmxhcmdlZEZpbHRlcklkeCA+IC0xICYmIGVubGFyZ2VkRmlsdGVySWR4ICE9PSBpZHgpIHtcbiAgICAgICAgLy8gdGhlcmUgc2hvdWxkIGJlIG9ubHkgb25lIGVubGFyZ2VkIGZpbHRlclxuICAgICAgICBuZXdGaWx0ZXIuZW5sYXJnZWQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBkYXRhc2V0czoge1xuICAgICAgICAgIC4uLnN0YXRlLmRhdGFzZXRzLFxuICAgICAgICAgIFtkYXRhSWRdOiB7XG4gICAgICAgICAgICAuLi5zdGF0ZS5kYXRhc2V0c1tkYXRhSWRdLFxuICAgICAgICAgICAgZmllbGRzOiBmaWVsZHMubWFwKChkLCBpKSA9PiAoaSA9PT0gZmllbGRJZHggPyBmaWVsZCA6IGQpKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3ZhbHVlJzpcbiAgICBkZWZhdWx0OlxuICAgICAgYnJlYWs7XG4gIH1cblxuICAvLyBzYXZlIG5ldyBmaWx0ZXJzIHRvIG5ld1N0YXRlXG4gIG5ld1N0YXRlID0ge1xuICAgIC4uLm5ld1N0YXRlLFxuICAgIGZpbHRlcnM6IHN0YXRlLmZpbHRlcnMubWFwKChmLCBpKSA9PiAoaSA9PT0gaWR4ID8gbmV3RmlsdGVyIDogZikpXG4gIH07XG5cbiAgLy8gZmlsdGVyIGRhdGFcbiAgbmV3U3RhdGUgPSB7XG4gICAgLi4ubmV3U3RhdGUsXG4gICAgZGF0YXNldHM6IHtcbiAgICAgIC4uLm5ld1N0YXRlLmRhdGFzZXRzLFxuICAgICAgW2RhdGFJZF06IHtcbiAgICAgICAgLi4ubmV3U3RhdGUuZGF0YXNldHNbZGF0YUlkXSxcbiAgICAgICAgLi4uZmlsdGVyRGF0YShhbGxEYXRhLCBkYXRhSWQsIG5ld1N0YXRlLmZpbHRlcnMpXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIG5ld1N0YXRlID0gdXBkYXRlQWxsTGF5ZXJEb21haW5EYXRhKG5ld1N0YXRlLCBkYXRhSWQsIG5ld0ZpbHRlcik7XG4gIG5ld1N0YXRlID0gdXBkYXRlV2lkZ2V0QWdncmVnYXRpb25EYXRhKG5ld1N0YXRlKTtcblxuICByZXR1cm4gbmV3U3RhdGU7XG59XG5cbmV4cG9ydCBjb25zdCBzZXRGaWx0ZXJQbG90VXBkYXRlciA9IChzdGF0ZSwge2lkeCwgbmV3UHJvcH0pID0+IHtcbiAgbGV0IG5ld0ZpbHRlciA9IHsuLi5zdGF0ZS5maWx0ZXJzW2lkeF0sIC4uLm5ld1Byb3B9O1xuICBjb25zdCBwcm9wID0gT2JqZWN0LmtleXMobmV3UHJvcClbMF07XG4gIGlmIChwcm9wID09PSAneUF4aXMnKSB7XG4gICAgY29uc3QgcGxvdFR5cGUgPSBnZXREZWZhdWx0RmlsdGVyUGxvdFR5cGUobmV3RmlsdGVyKTtcblxuICAgIGlmIChwbG90VHlwZSkge1xuICAgICAgbmV3RmlsdGVyID0ge1xuICAgICAgICAuLi5uZXdGaWx0ZXIsXG4gICAgICAgIC4uLmdldEZpbHRlclBsb3QoXG4gICAgICAgICAgey4uLm5ld0ZpbHRlciwgcGxvdFR5cGV9LFxuICAgICAgICAgIHN0YXRlLmRhdGFzZXRzW25ld0ZpbHRlci5kYXRhSWRdLmFsbERhdGFcbiAgICAgICAgKSxcbiAgICAgICAgcGxvdFR5cGVcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBmaWx0ZXJzOiBzdGF0ZS5maWx0ZXJzLm1hcCgoZiwgaSkgPT4gKGkgPT09IGlkeCA/IG5ld0ZpbHRlciA6IGYpKVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZEZpbHRlclVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT5cbiAgIWFjdGlvbi5kYXRhSWRcbiAgICA/IHN0YXRlXG4gICAgOiB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBmaWx0ZXJzOiBbLi4uc3RhdGUuZmlsdGVycywgZ2V0RGVmYXVsdEZpbHRlcihhY3Rpb24uZGF0YUlkKV1cbiAgICAgIH07XG5cbmV4cG9ydCBjb25zdCB0b2dnbGVGaWx0ZXJBbmltYXRpb25VcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBmaWx0ZXJzOiBzdGF0ZS5maWx0ZXJzLm1hcCgoZiwgaSkgPT5cbiAgICBpID09PSBhY3Rpb24uaWR4ID8gey4uLmYsIGlzQW5pbWF0aW5nOiAhZi5pc0FuaW1hdGluZ30gOiBmXG4gIClcbn0pO1xuXG5leHBvcnQgY29uc3QgdXBkYXRlQW5pbWF0aW9uU3BlZWRVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBmaWx0ZXJzOiBzdGF0ZS5maWx0ZXJzLm1hcCgoZiwgaSkgPT5cbiAgICBpID09PSBhY3Rpb24uaWR4ID8gey4uLmYsIHNwZWVkOiBhY3Rpb24uc3BlZWR9IDogZlxuICApXG59KTtcblxuZXhwb3J0IGNvbnN0IGVubGFyZ2VGaWx0ZXJVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgY29uc3QgaXNFbmxhcmdlZCA9IHN0YXRlLmZpbHRlcnNbYWN0aW9uLmlkeF0uZW5sYXJnZWQ7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBmaWx0ZXJzOiBzdGF0ZS5maWx0ZXJzLm1hcCgoZiwgaSkgPT4ge1xuICAgICAgZi5lbmxhcmdlZCA9ICFpc0VubGFyZ2VkICYmIGkgPT09IGFjdGlvbi5pZHg7XG4gICAgICByZXR1cm4gZjtcbiAgICB9KVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHJlbW92ZUZpbHRlclVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICBjb25zdCB7aWR4fSA9IGFjdGlvbjtcbiAgY29uc3Qge2RhdGFJZH0gPSBzdGF0ZS5maWx0ZXJzW2lkeF07XG5cbiAgY29uc3QgbmV3RmlsdGVycyA9IFtcbiAgICAuLi5zdGF0ZS5maWx0ZXJzLnNsaWNlKDAsIGlkeCksXG4gICAgLi4uc3RhdGUuZmlsdGVycy5zbGljZShpZHggKyAxLCBzdGF0ZS5maWx0ZXJzLmxlbmd0aClcbiAgXTtcblxuICBsZXQgbmV3U3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgZGF0YXNldHM6IHtcbiAgICAgIC4uLnN0YXRlLmRhdGFzZXRzLFxuICAgICAgW2RhdGFJZF06IHtcbiAgICAgICAgLi4uc3RhdGUuZGF0YXNldHNbZGF0YUlkXSxcbiAgICAgICAgLi4uZmlsdGVyRGF0YShzdGF0ZS5kYXRhc2V0c1tkYXRhSWRdLmFsbERhdGEsIGRhdGFJZCwgbmV3RmlsdGVycylcbiAgICAgIH1cbiAgICB9LFxuICAgIGZpbHRlcnM6IG5ld0ZpbHRlcnNcbiAgfTtcblxuICBuZXdTdGF0ZSA9IHVwZGF0ZUFsbExheWVyRG9tYWluRGF0YShuZXdTdGF0ZSwgZGF0YUlkKTtcbiAgcmV0dXJuIHVwZGF0ZVdpZGdldEFnZ3JlZ2F0aW9uRGF0YShuZXdTdGF0ZSk7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkV2lkZ2V0VXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiB7XG4gIGNvbnN0IGRlZmF1bHREYXRhc2V0ID0gT2JqZWN0LmtleXMoc3RhdGUuZGF0YXNldHMpWzBdO1xuICBjb25zdCBuZXdXaWRnZXQgPSBuZXcgV2lkZ2V0KHtcbiAgICBpc1Zpc2libGU6IHRydWUsXG4gICAgaXNDb25maWdBY3RpdmU6IHRydWUsXG4gICAgZGF0YUlkOiBkZWZhdWx0RGF0YXNldCxcbiAgICAuLi5hY3Rpb24ucHJvcHNcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICB3aWRnZXRzOiBbLi4uc3RhdGUud2lkZ2V0cywgbmV3V2lkZ2V0XSxcbiAgICB3aWRnZXRPcmRlcjogWy4uLnN0YXRlLndpZGdldE9yZGVyLCBzdGF0ZS53aWRnZXRPcmRlci5sZW5ndGhdXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlV2lkZ2V0VXBkYXRlciA9IChzdGF0ZSwge2lkeH0pID0+IHtcbiAgY29uc3Qge3dpZGdldHN9ID0gc3RhdGU7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgd2lkZ2V0czogW1xuICAgICAgLi4ud2lkZ2V0cy5zbGljZSgwLCBpZHgpLFxuICAgICAgLi4ud2lkZ2V0cy5zbGljZShpZHggKyAxLCB3aWRnZXRzLmxlbmd0aClcbiAgICBdLFxuICAgIHdpZGdldE9yZGVyOiBzdGF0ZS53aWRnZXRPcmRlclxuICAgICAgLmZpbHRlcihpID0+IGkgIT09IGlkeClcbiAgICAgIC5tYXAocGlkID0+IChwaWQgPiBpZHggPyBwaWQgLSAxIDogcGlkKSlcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZW9yZGVyV2lkZ2V0VXBkYXRlciA9IChzdGF0ZSwge29yZGVyfSkgPT4ge1xuICAvLyBjb25zb2xlLmxvZygncmVvcmRlcldpZGdldFVwZGF0ZXInLCBvcmRlcik7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgd2lkZ2V0T3JkZXI6IG9yZGVyXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgYWRkTGF5ZXJVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgY29uc3QgZGVmYXVsdERhdGFzZXQgPSBPYmplY3Qua2V5cyhzdGF0ZS5kYXRhc2V0cylbMF07XG4gIC8vIGNvbnNvbGUubG9nKFxuICAvLyAgICdpbnNpZGUgYWRkIExheWVyIHVwZGF0ZXIgICcsXG4gIC8vICAgc3RhdGUsXG4gIC8vICAgYWN0aW9uLnByb3BzLFxuICAvLyAgIGRlZmF1bHREYXRhc2V0XG4gIC8vICk7XG5cbiAgY29uc3QgbmV3TGF5ZXIgPSBuZXcgTGF5ZXIoe1xuICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICBpc0NvbmZpZ0FjdGl2ZTogdHJ1ZSxcbiAgICBkYXRhSWQ6IGRlZmF1bHREYXRhc2V0LFxuICAgIC4uLmFjdGlvbi5wcm9wc1xuICB9KTtcblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyczogWy4uLnN0YXRlLmxheWVycywgbmV3TGF5ZXJdLFxuICAgIGxheWVyRGF0YTogWy4uLnN0YXRlLmxheWVyRGF0YSwge31dLFxuICAgIGxheWVyT3JkZXI6IFsuLi5zdGF0ZS5sYXllck9yZGVyLCBzdGF0ZS5sYXllck9yZGVyLmxlbmd0aF0sXG4gICAgc3BsaXRNYXBzOiBhZGROZXdMYXllcnNUb1NwbGl0TWFwKHN0YXRlLnNwbGl0TWFwcywgbmV3TGF5ZXIpXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlTGF5ZXJVcGRhdGVyID0gKHN0YXRlLCB7aWR4fSkgPT4ge1xuICBjb25zdCB7bGF5ZXJzLCBsYXllckRhdGEsIGNsaWNrZWQsIGhvdmVySW5mb30gPSBzdGF0ZTtcbiAgY29uc3QgbGF5ZXJUb1JlbW92ZSA9IHN0YXRlLmxheWVyc1tpZHhdO1xuICBjb25zdCBuZXdNYXBzID0gcmVtb3ZlTGF5ZXJGcm9tU3BsaXRNYXBzKHN0YXRlLCBsYXllclRvUmVtb3ZlKTtcbiAgLy8gY29uc29sZS5sb2cocmVtb3ZlV2lkZ2V0c09uTGF5ZXIoc3RhdGUsIGxheWVyVG9SZW1vdmUpKTtcbiAgc3RhdGUgPSByZW1vdmVXaWRnZXRzT25MYXllcihzdGF0ZSwgbGF5ZXJUb1JlbW92ZSk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBsYXllcnM6IFsuLi5sYXllcnMuc2xpY2UoMCwgaWR4KSwgLi4ubGF5ZXJzLnNsaWNlKGlkeCArIDEsIGxheWVycy5sZW5ndGgpXSxcbiAgICBsYXllckRhdGE6IFtcbiAgICAgIC4uLmxheWVyRGF0YS5zbGljZSgwLCBpZHgpLFxuICAgICAgLi4ubGF5ZXJEYXRhLnNsaWNlKGlkeCArIDEsIGxheWVyRGF0YS5sZW5ndGgpXG4gICAgXSxcbiAgICBsYXllck9yZGVyOiBzdGF0ZS5sYXllck9yZGVyXG4gICAgICAuZmlsdGVyKGkgPT4gaSAhPT0gaWR4KVxuICAgICAgLm1hcChwaWQgPT4gKHBpZCA+IGlkeCA/IHBpZCAtIDEgOiBwaWQpKSxcbiAgICBjbGlja2VkOiBsYXllclRvUmVtb3ZlLmlzTGF5ZXJIb3ZlcmVkKGNsaWNrZWQpID8gdW5kZWZpbmVkIDogY2xpY2tlZCxcbiAgICBob3ZlckluZm86IGxheWVyVG9SZW1vdmUuaXNMYXllckhvdmVyZWQoaG92ZXJJbmZvKSA/IHVuZGVmaW5lZCA6IGhvdmVySW5mbyxcbiAgICBzcGxpdE1hcHM6IG5ld01hcHNcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZW9yZGVyTGF5ZXJVcGRhdGVyID0gKHN0YXRlLCB7b3JkZXJ9KSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgbGF5ZXJPcmRlcjogb3JkZXJcbn0pO1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlRGF0YXNldFVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICAvLyBleHRyYWN0IGRhdGFzZXQga2V5XG4gIGNvbnN0IHtrZXk6IGRhdGFzZXRLZXl9ID0gYWN0aW9uO1xuICBjb25zdCB7ZGF0YXNldHN9ID0gc3RhdGU7XG5cbiAgLy8gY2hlY2sgaWYgZGF0YXNldCBpcyBwcmVzZW50XG4gIGlmICghZGF0YXNldHNbZGF0YXNldEtleV0pIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuICBjb25zdCB7XG4gICAgbGF5ZXJzLFxuICAgIGRhdGFzZXRzOiB7W2RhdGFzZXRLZXldOiBkYXRhc2V0LCAuLi5uZXdEYXRhc2V0c31cbiAgfSA9IHN0YXRlO1xuICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC12YXJzICovXG5cbiAgY29uc3QgaW5kZXhlcyA9IGxheWVycy5yZWR1Y2UoKGxpc3RPZkluZGV4ZXMsIGxheWVyLCBpbmRleCkgPT4ge1xuICAgIGlmIChsYXllci5jb25maWcuZGF0YUlkID09PSBkYXRhc2V0S2V5KSB7XG4gICAgICBsaXN0T2ZJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gbGlzdE9mSW5kZXhlcztcbiAgfSwgW10pO1xuXG4gIC8vIHJlbW92ZSBsYXllcnMgYW5kIGRhdGFzZXRzXG4gIGNvbnN0IHtuZXdTdGF0ZX0gPSBpbmRleGVzLnJlZHVjZShcbiAgICAoe25ld1N0YXRlOiBjdXJyZW50U3RhdGUsIGluZGV4Q291bnRlcn0sIGlkeCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gaWR4IC0gaW5kZXhDb3VudGVyO1xuICAgICAgY3VycmVudFN0YXRlID0gcmVtb3ZlTGF5ZXJVcGRhdGVyKGN1cnJlbnRTdGF0ZSwge2lkeDogY3VycmVudEluZGV4fSk7XG4gICAgICBpbmRleENvdW50ZXIrKztcbiAgICAgIHJldHVybiB7bmV3U3RhdGU6IGN1cnJlbnRTdGF0ZSwgaW5kZXhDb3VudGVyfTtcbiAgICB9LFxuICAgIHtuZXdTdGF0ZTogey4uLnN0YXRlLCBkYXRhc2V0czogbmV3RGF0YXNldHN9LCBpbmRleENvdW50ZXI6IDB9XG4gICk7XG5cbiAgLy8gcmVtb3ZlIGZpbHRlcnNcbiAgY29uc3QgZmlsdGVycyA9IHN0YXRlLmZpbHRlcnMuZmlsdGVyKGZpbHRlciA9PiBmaWx0ZXIuZGF0YUlkICE9PSBkYXRhc2V0S2V5KTtcblxuICAvLyB1cGRhdGUgaW50ZXJhY3Rpb25Db25maWdcbiAgbGV0IHtpbnRlcmFjdGlvbkNvbmZpZ30gPSBzdGF0ZTtcbiAgY29uc3Qge3Rvb2x0aXB9ID0gaW50ZXJhY3Rpb25Db25maWc7XG4gIGlmICh0b29sdGlwKSB7XG4gICAgY29uc3Qge2NvbmZpZ30gPSB0b29sdGlwO1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gICAgY29uc3Qge1tkYXRhc2V0S2V5XTogZmllbGRzLCAuLi5maWVsZHNUb1Nob3d9ID0gY29uZmlnLmZpZWxkc1RvU2hvdztcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC12YXJzICovXG4gICAgaW50ZXJhY3Rpb25Db25maWcgPSB7XG4gICAgICAuLi5pbnRlcmFjdGlvbkNvbmZpZyxcbiAgICAgIHRvb2x0aXA6IHsuLi50b29sdGlwLCBjb25maWc6IHsuLi5jb25maWcsIGZpZWxkc1RvU2hvd319XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7Li4ubmV3U3RhdGUsIGZpbHRlcnMsIGludGVyYWN0aW9uQ29uZmlnfTtcbn07XG5cbmV4cG9ydCBjb25zdCB1cGRhdGVMYXllckJsZW5kaW5nVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgbGF5ZXJCbGVuZGluZzogYWN0aW9uLm1vZGVcbn0pO1xuXG5leHBvcnQgY29uc3Qgc2hvd0RhdGFzZXRUYWJsZVVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGVkaXRpbmdEYXRhc2V0OiBhY3Rpb24uZGF0YUlkXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcmVzZXRNYXBDb25maWdWaXNTdGF0ZVVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4gKHtcbiAgLi4uSU5JVElBTF9WSVNfU1RBVEUsXG4gIC4uLnN0YXRlLmluaXRpYWxTdGF0ZSxcbiAgaW5pdGlhbFN0YXRlOiBzdGF0ZS5pbml0aWFsU3RhdGVcbn0pO1xuXG4vKipcbiAqIExvYWRzIGN1c3RvbSBjb25maWd1cmF0aW9uIGludG8gc3RhdGVcbiAqIEBwYXJhbSBzdGF0ZVxuICogQHBhcmFtIGFjdGlvblxuICogQHJldHVybnMgeyp9XG4gKi9cbmV4cG9ydCBjb25zdCByZWNlaXZlTWFwQ29uZmlnVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PiB7XG4gIGlmICghYWN0aW9uLnBheWxvYWQudmlzU3RhdGUpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBjb25zdCB7XG4gICAgZmlsdGVycyxcbiAgICBsYXllcnMsXG4gICAgd2lkZ2V0cyxcbiAgICBpbnRlcmFjdGlvbkNvbmZpZyxcbiAgICBsYXllckJsZW5kaW5nLFxuICAgIHNwbGl0TWFwc1xuICB9ID0gYWN0aW9uLnBheWxvYWQudmlzU3RhdGU7XG5cbiAgLy8gYWx3YXlzIHJlc2V0IGNvbmZpZyB3aGVuIHJlY2VpdmUgYSBuZXcgY29uZmlnXG4gIGNvbnN0IHJlc2V0U3RhdGUgPSByZXNldE1hcENvbmZpZ1Zpc1N0YXRlVXBkYXRlcihzdGF0ZSk7XG4gIGxldCBtZXJnZWRTdGF0ZSA9IHtcbiAgICAuLi5yZXNldFN0YXRlLFxuICAgIHNwbGl0TWFwczogc3BsaXRNYXBzIHx8IFtdIC8vIG1hcHMgZG9lc24ndCByZXF1aXJlIGFueSBsb2dpY1xuICB9O1xuXG4gIC8vIGNvbnNvbGUubG9nKCdCZWZvcmUgTWVyZ2VGaWx0ZXJzJywgbWVyZ2VkU3RhdGUpO1xuICAvLyBjb25zb2xlLmxvZyhmaWx0ZXJzLCBsYXllcnMsIHdpZGdldHMpO1xuICBtZXJnZWRTdGF0ZSA9IG1lcmdlRmlsdGVycyhtZXJnZWRTdGF0ZSwgZmlsdGVycyk7XG4gIC8vIGNvbnNvbGUubG9nKCdBZnRlciBNZXJnZUZpbHRlcnMnLCBtZXJnZWRTdGF0ZSk7XG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VMYXllcnMobWVyZ2VkU3RhdGUsIGxheWVycyk7XG4gIC8vIGNvbnNvbGUubG9nKCdBZnRlciBNZXJnZUxheWVycycsIG1lcmdlZFN0YXRlKTtcbiAgbWVyZ2VkU3RhdGUgPSBtZXJnZUludGVyYWN0aW9ucyhtZXJnZWRTdGF0ZSwgaW50ZXJhY3Rpb25Db25maWcpO1xuICBtZXJnZWRTdGF0ZSA9IG1lcmdlTGF5ZXJCbGVuZGluZyhtZXJnZWRTdGF0ZSwgbGF5ZXJCbGVuZGluZyk7XG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VXaWRnZXRzKG1lcmdlZFN0YXRlLCB3aWRnZXRzKTtcbiAgLy8gY29uc29sZS5sb2coJ0FmdGVyIE1lcmdlV2lkZ2V0cycsIG1lcmdlZFN0YXRlKTtcbiAgcmV0dXJuIG1lcmdlZFN0YXRlO1xufTtcblxuZXhwb3J0IGNvbnN0IGxheWVySG92ZXJVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBob3ZlckluZm86IGFjdGlvbi5pbmZvXG59KTtcblxuZXhwb3J0IGNvbnN0IGxheWVyQ2xpY2tVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBjbGlja2VkOiBhY3Rpb24uaW5mbyAmJiBhY3Rpb24uaW5mby5waWNrZWQgPyBhY3Rpb24uaW5mbyA6IG51bGxcbn0pO1xuXG5leHBvcnQgY29uc3QgbWFwQ2xpY2tVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+ICh7XG4gIC4uLnN0YXRlLFxuICBjbGlja2VkOiBudWxsXG59KTtcblxuZXhwb3J0IGNvbnN0IHRvZ2dsZVNwbGl0TWFwVXBkYXRlciA9IChzdGF0ZSwgYWN0aW9uKSA9PlxuICBzdGF0ZS5zcGxpdE1hcHMgJiYgc3RhdGUuc3BsaXRNYXBzLmxlbmd0aCA9PT0gMFxuICAgID8ge1xuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgLy8gbWF5YmUgd2Ugc2hvdWxkIHVzZSBhbiBhcnJheSB0byBzdG9yZSBzdGF0ZSBmb3IgYSBzaW5nbGUgbWFwIGFzIHdlbGxcbiAgICAgICAgLy8gaWYgY3VycmVudCBtYXBzIGxlbmd0aCBpcyBlcXVhbCB0byAwIGl0IG1lYW5zIHRoYXQgd2UgYXJlIGFib3V0IHRvIHNwbGl0IHRoZSB2aWV3XG4gICAgICAgIHNwbGl0TWFwczogY29tcHV0ZVNwbGl0TWFwTGF5ZXJzKHN0YXRlLmxheWVycylcbiAgICAgIH1cbiAgICA6IGNsb3NlU3BlY2lmaWNNYXBBdEluZGV4KHN0YXRlLCBhY3Rpb24pO1xuXG4vKipcbiAqIFRoaXMgaXMgdHJpZ2dlcmVkIHdoZW4gdmlldyBpcyBzcGxpdCBpbnRvIG11bHRpcGxlIG1hcHMuXG4gKiBJdCB3aWxsIG9ubHkgdXBkYXRlIGxheWVycyB0aGF0IGJlbG9uZyB0byB0aGUgbWFwIGxheWVyIGRyb3Bkb3duXG4gKiB0aGUgdXNlciBpcyBpbnRlcmFjdGluZyB3aXRcbiAqIEBwYXJhbSBzdGF0ZVxuICogQHBhcmFtIGFjdGlvblxuICovXG5leHBvcnQgY29uc3Qgc2V0VmlzaWJsZUxheWVyc0Zvck1hcFVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICBjb25zdCB7bWFwSW5kZXgsIGxheWVySWRzfSA9IGFjdGlvbjtcbiAgaWYgKCFsYXllcklkcykge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGNvbnN0IHtzcGxpdE1hcHMgPSBbXX0gPSBzdGF0ZTtcblxuICBpZiAoc3BsaXRNYXBzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIHdlIHNob3VsZCBuZXZlciBnZXQgaW50byB0aGlzIHN0YXRlXG4gICAgLy8gYmVjYXVzZSB0aGlzIGFjdGlvbiBzaG91bGQgb25seSBiZSB0cmlnZ2VyZWRcbiAgICAvLyB3aGVuIG1hcCB2aWV3IGlzIHNwbGl0XG4gICAgLy8gYnV0IHNvbWV0aGluZyBtYXkgaGF2ZSBoYXBwZW5lZFxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8vIG5lZWQgdG8gY2hlY2sgaWYgbWFwcyBpcyBwb3B1bGF0ZWQgb3RoZXJ3aXNlIHdpbGwgY3JlYXRlXG4gIGNvbnN0IHtbbWFwSW5kZXhdOiBtYXAgPSB7fX0gPSBzcGxpdE1hcHM7XG5cbiAgY29uc3QgbGF5ZXJzID0gbWFwLmxheWVycyB8fCBbXTtcblxuICAvLyB3ZSBzZXQgdmlzaWJpbGl0eSB0byB0cnVlIGZvciBhbGwgbGF5ZXJzIGluY2x1ZGVkIGluIG91ciBpbnB1dCBsaXN0XG4gIGNvbnN0IG5ld0xheWVycyA9IChPYmplY3Qua2V5cyhsYXllcnMpIHx8IFtdKS5yZWR1Y2UoKGN1cnJlbnRMYXllcnMsIGlkeCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5jdXJyZW50TGF5ZXJzLFxuICAgICAgW2lkeF06IHtcbiAgICAgICAgLi4ubGF5ZXJzW2lkeF0sXG4gICAgICAgIGlzVmlzaWJsZTogbGF5ZXJJZHMuaW5jbHVkZXMoaWR4KVxuICAgICAgfVxuICAgIH07XG4gIH0sIHt9KTtcblxuICBjb25zdCBuZXdNYXBzID0gWy4uLnNwbGl0TWFwc107XG5cbiAgbmV3TWFwc1ttYXBJbmRleF0gPSB7XG4gICAgLi4uc3BsaXRNYXBzW21hcEluZGV4XSxcbiAgICBsYXllcnM6IG5ld0xheWVyc1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgc3BsaXRNYXBzOiBuZXdNYXBzXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdG9nZ2xlTGF5ZXJGb3JNYXBVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgaWYgKCFzdGF0ZS5zcGxpdE1hcHNbYWN0aW9uLm1hcEluZGV4XSkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGNvbnN0IG1hcFNldHRpbmdzID0gc3RhdGUuc3BsaXRNYXBzW2FjdGlvbi5tYXBJbmRleF07XG4gIGNvbnN0IHtsYXllcnN9ID0gbWFwU2V0dGluZ3M7XG4gIGlmICghbGF5ZXJzIHx8ICFsYXllcnNbYWN0aW9uLmxheWVySWRdKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgY29uc3QgbGF5ZXIgPSBsYXllcnNbYWN0aW9uLmxheWVySWRdO1xuXG4gIGNvbnN0IG5ld0xheWVyID0ge1xuICAgIC4uLmxheWVyLFxuICAgIGlzVmlzaWJsZTogIWxheWVyLmlzVmlzaWJsZVxuICB9O1xuXG4gIGNvbnN0IG5ld0xheWVycyA9IHtcbiAgICAuLi5sYXllcnMsXG4gICAgW2FjdGlvbi5sYXllcklkXTogbmV3TGF5ZXJcbiAgfTtcblxuICAvLyBjb25zdCBzcGxpdE1hcHMgPSBzdGF0ZS5zcGxpdE1hcHM7XG4gIGNvbnN0IG5ld1NwbGl0TWFwcyA9IFsuLi5zdGF0ZS5zcGxpdE1hcHNdO1xuICBuZXdTcGxpdE1hcHNbYWN0aW9uLm1hcEluZGV4XSA9IHtcbiAgICAuLi5tYXBTZXR0aW5ncyxcbiAgICBsYXllcnM6IG5ld0xheWVyc1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgc3BsaXRNYXBzOiBuZXdTcGxpdE1hcHNcbiAgfTtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1zdGF0ZW1lbnRzICovXG5leHBvcnQgY29uc3QgdXBkYXRlVmlzRGF0YVVwZGF0ZXIgPSAoc3RhdGUsIGFjdGlvbikgPT4ge1xuICAvLyBkYXRhc2V0cyBjYW4gYmUgYSBzaW5nbGUgZGF0YSBlbnRyaWVzIG9yIGFuIGFycmF5IG9mIG11bHRpcGxlIGRhdGEgZW50cmllc1xuICBjb25zdCBkYXRhc2V0cyA9IEFycmF5LmlzQXJyYXkoYWN0aW9uLmRhdGFzZXRzKVxuICAgID8gYWN0aW9uLmRhdGFzZXRzXG4gICAgOiBbYWN0aW9uLmRhdGFzZXRzXTtcblxuICBpZiAoYWN0aW9uLmNvbmZpZykge1xuICAgIC8vIGFwcGx5IGNvbmZpZyBpZiBwYXNzZWQgZnJvbSBhY3Rpb25cbiAgICBzdGF0ZSA9IHJlY2VpdmVNYXBDb25maWdVcGRhdGVyKHN0YXRlLCB7XG4gICAgICBwYXlsb2FkOiB7dmlzU3RhdGU6IGFjdGlvbi5jb25maWd9XG4gICAgfSk7XG4gIH1cbiAgY29uc3QgbmV3RGF0ZUVudHJpZXMgPSBkYXRhc2V0cy5yZWR1Y2UoXG4gICAgKGFjY3UsIHtpbmZvID0ge30sIGRhdGF9KSA9PiAoe1xuICAgICAgLi4uYWNjdSxcbiAgICAgIC4uLihjcmVhdGVOZXdEYXRhRW50cnkoe2luZm8sIGRhdGF9LCBzdGF0ZS5kYXRhc2V0cykgfHwge30pXG4gICAgfSksXG4gICAge31cbiAgKTtcblxuICBpZiAoIU9iamVjdC5rZXlzKG5ld0RhdGVFbnRyaWVzKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICBjb25zdCBzdGF0ZVdpdGhOZXdEYXRhID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIGRhdGFzZXRzOiB7XG4gICAgICAuLi5zdGF0ZS5kYXRhc2V0cyxcbiAgICAgIC4uLm5ld0RhdGVFbnRyaWVzXG4gICAgfVxuICB9O1xuXG4gIC8vIHByZXZpb3VzbHkgc2F2ZWQgY29uZmlnIGJlZm9yZSBkYXRhIGxvYWRlZFxuICBjb25zdCB7XG4gICAgZmlsdGVyVG9CZU1lcmdlZCA9IFtdLFxuICAgIGxheWVyVG9CZU1lcmdlZCA9IFtdLFxuICAgIHdpZGdldFRvQmVNZXJnZWQgPSBbXSxcbiAgICBpbnRlcmFjdGlvblRvQmVNZXJnZWQgPSB7fVxuICB9ID0gc3RhdGVXaXRoTmV3RGF0YTtcblxuICAvLyBtZXJnZSBzdGF0ZSB3aXRoIHNhdmVkIGZpbHRlcnNcbiAgLy8gY29uc29sZS5sb2coJ0ZpbHRlclRvQmVNZXJnZWQnLCBmaWx0ZXJUb0JlTWVyZ2VkKTtcbiAgbGV0IG1lcmdlZFN0YXRlID0gbWVyZ2VGaWx0ZXJzKHN0YXRlV2l0aE5ld0RhdGEsIGZpbHRlclRvQmVNZXJnZWQpO1xuICAvLyBtZXJnZSBzdGF0ZSB3aXRoIHNhdmVkIGxheWVyc1xuICBtZXJnZWRTdGF0ZSA9IG1lcmdlTGF5ZXJzKG1lcmdlZFN0YXRlLCBsYXllclRvQmVNZXJnZWQpO1xuICBjb25zdCB7b3B0aW9uc30gPSBhY3Rpb247XG5cbiAgaWYgKFxuICAgIG1lcmdlZFN0YXRlLmxheWVycy5sZW5ndGggPT09IHN0YXRlLmxheWVycy5sZW5ndGggJiZcbiAgICAhb3B0aW9ucy5kaXNhYmxlZEFkZERlZmF1bHRMYXllcnNcbiAgKSB7XG4gICAgLy8gbm8gbGF5ZXIgbWVyZ2VkLCBmaW5kIGRlZmF1bHRzXG4gICAgbWVyZ2VkU3RhdGUgPSBhZGREZWZhdWx0TGF5ZXJzKG1lcmdlZFN0YXRlLCBuZXdEYXRlRW50cmllcyk7XG4gIH1cblxuICAvLyBpZiAobWVyZ2VkU3RhdGUud2lkZ2V0cy5sZW5ndGggPT09IHN0YXRlLndpZGdldHMubGVuZ3RoKSB7XG4gIC8vICAgbWVyZ2VkU3RhdGUgPSBhZGREZWZhdWx0V2lkZ2V0KG1lcmdlZFN0YXRlLCBuZXdEYXRlRW50cmllcyk7XG4gIC8vIH1cblxuICBpZiAobWVyZ2VkU3RhdGUuc3BsaXRNYXBzLmxlbmd0aCkge1xuICAgIGNvbnN0IG5ld0xheWVycyA9IG1lcmdlZFN0YXRlLmxheWVycy5maWx0ZXIoXG4gICAgICBsID0+IGwuY29uZmlnLmRhdGFJZCBpbiBuZXdEYXRlRW50cmllc1xuICAgICk7XG4gICAgLy8gaWYgbWFwIGlzIHNwbGl0ZWQsIGFkZCBuZXcgbGF5ZXJzIHRvIHNwbGl0TWFwc1xuICAgIG1lcmdlZFN0YXRlID0ge1xuICAgICAgLi4ubWVyZ2VkU3RhdGUsXG4gICAgICBzcGxpdE1hcHM6IGFkZE5ld0xheWVyc1RvU3BsaXRNYXAobWVyZ2VkU3RhdGUuc3BsaXRNYXBzLCBuZXdMYXllcnMpXG4gICAgfTtcbiAgfVxuICAvLyBjb25zb2xlLmxvZyhtZXJnZWRTdGF0ZSk7XG5cbiAgLy8gbWVyZ2Ugc3RhdGUgd2l0aCBzYXZlZCBpbnRlcmFjdGlvbnNcbiAgbWVyZ2VkU3RhdGUgPSBtZXJnZUludGVyYWN0aW9ucyhtZXJnZWRTdGF0ZSwgaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkKTtcblxuICAvLyBpZiBubyB0b29sdGlwcyBtZXJnZWQgYWRkIGRlZmF1bHQgdG9vbHRpcHNcbiAgT2JqZWN0LmtleXMobmV3RGF0ZUVudHJpZXMpLmZvckVhY2goZGF0YUlkID0+IHtcbiAgICBjb25zdCB0b29sdGlwRmllbGRzID1cbiAgICAgIG1lcmdlZFN0YXRlLmludGVyYWN0aW9uQ29uZmlnLnRvb2x0aXAuY29uZmlnLmZpZWxkc1RvU2hvd1tkYXRhSWRdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh0b29sdGlwRmllbGRzKSB8fCAhdG9vbHRpcEZpZWxkcy5sZW5ndGgpIHtcbiAgICAgIG1lcmdlZFN0YXRlID0gYWRkRGVmYXVsdFRvb2x0aXBzKG1lcmdlZFN0YXRlLCBuZXdEYXRlRW50cmllc1tkYXRhSWRdKTtcbiAgICB9XG4gIH0pO1xuXG4gIG1lcmdlZFN0YXRlID0gdXBkYXRlQWxsTGF5ZXJEb21haW5EYXRhKFxuICAgIG1lcmdlZFN0YXRlLFxuICAgIE9iamVjdC5rZXlzKG5ld0RhdGVFbnRyaWVzKVxuICApO1xuXG4gIG1lcmdlZFN0YXRlID0gbWVyZ2VXaWRnZXRzKG1lcmdlZFN0YXRlLCB3aWRnZXRUb0JlTWVyZ2VkKTtcblxuICByZXR1cm4gbWVyZ2VkU3RhdGU7XG59O1xuLyogZXNsaW50LWVuYWJsZSBtYXgtc3RhdGVtZW50cyAqL1xuXG5mdW5jdGlvbiBnZW5lcmF0ZUxheWVyTWV0YUZvclNwbGl0Vmlld3MobGF5ZXIpIHtcbiAgcmV0dXJuIHtcbiAgICBpc0F2YWlsYWJsZTogbGF5ZXIuY29uZmlnLmlzVmlzaWJsZSxcbiAgICBpc1Zpc2libGU6IGxheWVyLmNvbmZpZy5pc1Zpc2libGVcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCB3aWxsIGNvbXB1dGUgdGhlIGRlZmF1bHQgbWFwcyBjdXN0b20gbGlzdFxuICogYmFzZWQgb24gdGhlIGN1cnJlbnQgbGF5ZXJzIHN0YXR1c1xuICogQHBhcmFtIGxheWVyc1xuICogQHJldHVybnMge1sqLCpdfVxuICovXG5mdW5jdGlvbiBjb21wdXRlU3BsaXRNYXBMYXllcnMobGF5ZXJzKSB7XG4gIGNvbnN0IG1hcExheWVycyA9IGxheWVycy5yZWR1Y2UoXG4gICAgKG5ld0xheWVycywgY3VycmVudExheWVyKSA9PiAoe1xuICAgICAgLi4ubmV3TGF5ZXJzLFxuICAgICAgW2N1cnJlbnRMYXllci5pZF06IGdlbmVyYXRlTGF5ZXJNZXRhRm9yU3BsaXRWaWV3cyhjdXJyZW50TGF5ZXIpXG4gICAgfSksXG4gICAge31cbiAgKTtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBsYXllcnM6IG1hcExheWVyc1xuICAgIH0sXG4gICAge1xuICAgICAgbGF5ZXJzOiBtYXBMYXllcnNcbiAgICB9XG4gIF07XG59XG5cbi8qKlxuICogUmVtb3ZlIGFuIGV4aXN0aW5nIGxheWVyIGZyb20gY3VzdG9tIG1hcCBsYXllciBvYmplY3RzXG4gKiBAcGFyYW0gc3RhdGVcbiAqIEBwYXJhbSBsYXllclxuICogQHJldHVybnMge1sqLCpdfSBNYXBzIG9mIGN1c3RvbSBsYXllciBvYmplY3RzXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUxheWVyRnJvbVNwbGl0TWFwcyhzdGF0ZSwgbGF5ZXIpIHtcbiAgcmV0dXJuIHN0YXRlLnNwbGl0TWFwcy5tYXAoc2V0dGluZ3MgPT4ge1xuICAgIGNvbnN0IHtsYXllcnN9ID0gc2V0dGluZ3M7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgICBjb25zdCB7W2xheWVyLmlkXTogXywgLi4ubmV3TGF5ZXJzfSA9IGxheWVycztcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC12YXJzICovXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNldHRpbmdzLFxuICAgICAgbGF5ZXJzOiBuZXdMYXllcnNcbiAgICB9O1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZW1vdmUgYW4gZXhpc3RpbmcgbGF5ZXIgZnJvbSBjdXN0b20gbWFwIGxheWVyIG9iamVjdHNcbiAqIEBwYXJhbSBzdGF0ZVxuICogQHBhcmFtIGxheWVyXG4gKiBAcmV0dXJucyB7Kn0gc3RhdGVcbiAqL1xuXG5mdW5jdGlvbiByZW1vdmVXaWRnZXRzT25MYXllcihzdGF0ZSwgbGF5ZXIpIHtcbiAgY29uc3Qge3dpZGdldHN9ID0gc3RhdGU7XG5cbiAgLy8gLy8gY2hlY2sgaWYgZGF0YXNldCBpcyBwcmVzZW50XG4gIC8vIGlmICghZGF0YXNldHNbZGF0YXNldEtleV0pIHtcbiAgLy8gICByZXR1cm4gc3RhdGU7XG4gIC8vIH1cblxuICBjb25zdCBpbmRleGVzID0gd2lkZ2V0cy5yZWR1Y2UoKGxpc3RPZkluZGV4ZXMsIHdpZGdldCwgaW5kZXgpID0+IHtcbiAgICBpZiAod2lkZ2V0LmNvbmZpZy5zZWxlY3RlZExheWVyLmlkID09PSBsYXllci5pZCkge1xuICAgICAgbGlzdE9mSW5kZXhlcy5wdXNoKGluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIGxpc3RPZkluZGV4ZXM7XG4gIH0sIFtdKTtcblxuICAvLyByZW1vdmUgbGF5ZXJzIGFuZCBkYXRhc2V0c1xuICBjb25zdCB7bmV3U3RhdGV9ID0gaW5kZXhlcy5yZWR1Y2UoXG4gICAgKHtuZXdTdGF0ZTogY3VycmVudFN0YXRlLCBpbmRleENvdW50ZXJ9LCBpZHgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGlkeCAtIGluZGV4Q291bnRlcjtcbiAgICAgIGN1cnJlbnRTdGF0ZSA9IHJlbW92ZVdpZGdldFVwZGF0ZXIoY3VycmVudFN0YXRlLCB7aWR4OiBjdXJyZW50SW5kZXh9KTtcbiAgICAgIGluZGV4Q291bnRlcisrO1xuICAgICAgcmV0dXJuIHtuZXdTdGF0ZTogY3VycmVudFN0YXRlLCBpbmRleENvdW50ZXJ9O1xuICAgIH0sXG4gICAge25ld1N0YXRlOiB7Li4uc3RhdGV9LCBpbmRleENvdW50ZXI6IDB9XG4gICk7XG5cbiAgcmV0dXJuIG5ld1N0YXRlO1xufVxuXG4vKipcbiAqIFJlbW92ZSBhbiBleGlzdGluZyBsYXllciBmcm9tIGN1c3RvbSBtYXAgbGF5ZXIgb2JqZWN0c1xuICogQHBhcmFtIHN0YXRlXG4gKiBAcGFyYW0gbGF5ZXJcbiAqIEByZXR1cm5zIHsqfSBzdGF0ZVxuICovXG5cbi8qKlxuICogQWRkIG5ldyBsYXllcnMgdG8gYm90aCBleGlzdGluZyBtYXBzXG4gKiBAcGFyYW0gc3BsaXRNYXBzXG4gKiBAcGFyYW0gbGF5ZXJzXG4gKiBAcmV0dXJucyB7WyosKl19IG5ldyBzcGxpdE1hcHNcbiAqL1xuZnVuY3Rpb24gYWRkTmV3TGF5ZXJzVG9TcGxpdE1hcChzcGxpdE1hcHMsIGxheWVycykge1xuICBjb25zdCBuZXdMYXllcnMgPSBBcnJheS5pc0FycmF5KGxheWVycykgPyBsYXllcnMgOiBbbGF5ZXJzXTtcblxuICBpZiAoIXNwbGl0TWFwcyB8fCAhc3BsaXRNYXBzLmxlbmd0aCB8fCAhbmV3TGF5ZXJzLmxlbmd0aCkge1xuICAgIHJldHVybiBzcGxpdE1hcHM7XG4gIH1cblxuICAvLyBhZGQgbmV3IGxheWVyIHRvIGJvdGggbWFwcyxcbiAgLy8gIGRvbid0IG92ZXJyaWRlLCBpZiBsYXllci5pZCBpcyBhbHJlYWR5IGluIHNwbGl0TWFwcy5zZXR0aW5ncy5sYXllcnNcbiAgcmV0dXJuIHNwbGl0TWFwcy5tYXAoc2V0dGluZ3MgPT4gKHtcbiAgICAuLi5zZXR0aW5ncyxcbiAgICBsYXllcnM6IHtcbiAgICAgIC4uLnNldHRpbmdzLmxheWVycyxcbiAgICAgIC4uLm5ld0xheWVycy5yZWR1Y2UoXG4gICAgICAgIChhY2N1LCBuZXdMYXllcikgPT5cbiAgICAgICAgICBuZXdMYXllci5jb25maWcuaXNWaXNpYmxlXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAuLi5hY2N1LFxuICAgICAgICAgICAgICAgIFtuZXdMYXllci5pZF06IHNldHRpbmdzLmxheWVyc1tuZXdMYXllci5pZF1cbiAgICAgICAgICAgICAgICAgID8gc2V0dGluZ3MubGF5ZXJzW25ld0xheWVyLmlkXVxuICAgICAgICAgICAgICAgICAgOiBnZW5lcmF0ZUxheWVyTWV0YUZvclNwbGl0Vmlld3MobmV3TGF5ZXIpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogYWNjdSxcbiAgICAgICAge31cbiAgICAgIClcbiAgICB9XG4gIH0pKTtcbn1cblxuLyoqXG4gKiBBZGQgbmV3IHdpZGdldHMgdG8gYm90aCBleGlzdGluZyBtYXBzXG4gKiBAcGFyYW0gc3BsaXRNYXBzXG4gKiBAcGFyYW0gd2lkZ2V0c1xuICogQHJldHVybnMge1sqLCpdfSBuZXcgc3BsaXRNYXBzXG4gKi9cbmZ1bmN0aW9uIGFkZE5ld1dpZGdldHNUb1NwbGl0TWFwKHNwbGl0TWFwcywgd2lkZ2V0cykge1xuICAvLyBjb25zb2xlLmxvZygnMCcpO1xuICBjb25zdCBuZXdXaWRnZXRzID0gQXJyYXkuaXNBcnJheSh3aWRnZXRzKSA/IHdpZGdldHMgOiBbd2lkZ2V0c107XG5cbiAgaWYgKCFzcGxpdE1hcHMgfHwgIXNwbGl0TWFwcy5sZW5ndGggfHwgIW5ld1dpZGdldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHNwbGl0TWFwcztcbiAgfVxuXG4gIC8vIGFkZCBuZXcgbGF5ZXIgdG8gYm90aCBtYXBzLFxuICAvLyAgZG9uJ3Qgb3ZlcnJpZGUsIGlmIGxheWVyLmlkIGlzIGFscmVhZHkgaW4gc3BsaXRNYXBzLnNldHRpbmdzLmxheWVyc1xuICByZXR1cm4gc3BsaXRNYXBzLm1hcChzZXR0aW5ncyA9PiAoe1xuICAgIC4uLnNldHRpbmdzLFxuICAgIHdpZGdldHM6IHtcbiAgICAgIC4uLnNldHRpbmdzLndpZGdldHMsXG4gICAgICAuLi5uZXdXaWRnZXRzLnJlZHVjZShcbiAgICAgICAgKGFjY3UsIG5ld1dpZGdldCkgPT5cbiAgICAgICAgICBuZXdXaWRnZXQuY29uZmlnLmlzVmlzaWJsZVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgICAgICAgICBbbmV3V2lkZ2V0LmlkXTogc2V0dGluZ3Mud2lkZ2V0c1tuZXdXaWRnZXRzLmlkXVxuICAgICAgICAgICAgICAgICAgPyBzZXR0aW5ncy53aWRnZXRzW25ld1dpZGdldC5pZF1cbiAgICAgICAgICAgICAgICAgIDogZ2VuZXJhdGVMYXllck1ldGFGb3JTcGxpdFZpZXdzKG5ld1dpZGdldClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiBhY2N1LFxuICAgICAgICB7fVxuICAgICAgKVxuICAgIH1cbiAgfSkpO1xufVxuXG4vKipcbiAqIEhpZGUgYW4gZXhpc3RpbmcgbGF5ZXJzIGZyb20gY3VzdG9tIG1hcCBsYXllciBvYmplY3RzXG4gKiBAcGFyYW0gc3RhdGVcbiAqIEBwYXJhbSBsYXllclxuICogQHJldHVybnMge1sqLCpdfSBNYXBzIG9mIGN1c3RvbSBsYXllciBvYmplY3RzXG4gKi9cbmZ1bmN0aW9uIHRvZ2dsZUxheWVyRnJvbVNwbGl0TWFwcyhzdGF0ZSwgbGF5ZXIpIHtcbiAgcmV0dXJuIHN0YXRlLnNwbGl0TWFwcy5tYXAoc2V0dGluZ3MgPT4ge1xuICAgIGNvbnN0IHtsYXllcnN9ID0gc2V0dGluZ3M7XG4gICAgY29uc3QgbmV3TGF5ZXJzID0ge1xuICAgICAgLi4ubGF5ZXJzLFxuICAgICAgW2xheWVyLmlkXTogZ2VuZXJhdGVMYXllck1ldGFGb3JTcGxpdFZpZXdzKGxheWVyKVxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2V0dGluZ3MsXG4gICAgICBsYXllcnM6IG5ld0xheWVyc1xuICAgIH07XG4gIH0pO1xufVxuXG4vKipcbiAqIEhpZGUgYW4gZXhpc3RpbmcgbGF5ZXJzIGZyb20gY3VzdG9tIG1hcCBsYXllciBvYmplY3RzXG4gKiBAcGFyYW0gc3RhdGVcbiAqIEBwYXJhbSB3aWRnZXRcbiAqIEByZXR1cm5zIHtbKiwqXX0gTWFwcyBvZiBjdXN0b20gbGF5ZXIgb2JqZWN0c1xuICovXG5mdW5jdGlvbiB0b2dnbGVXaWRnZXRGcm9tU3BsaXRNYXBzKHN0YXRlLCBsYXllcikge1xuICAvLyBjb25zb2xlLmxvZygnMCcpO1xuICByZXR1cm4gc3RhdGUuc3BsaXRNYXBzLm1hcChzZXR0aW5ncyA9PiB7XG4gICAgY29uc3Qge3dpZGdldHN9ID0gc2V0dGluZ3M7XG4gICAgY29uc3QgbmV3V2lkZ2V0cyA9IHtcbiAgICAgIC4uLndpZGdldHMsXG4gICAgICBbd2lkZ2V0LmlkXTogZ2VuZXJhdGVMYXllck1ldGFGb3JTcGxpdFZpZXdzKHdpZGdldClcbiAgICB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNldHRpbmdzLFxuICAgICAgd2lkZ2V0czogbmV3V2lkZ2V0c1xuICAgIH07XG4gIH0pO1xufVxuXG4vKipcbiAqIFdoZW4gYSB1c2VyIGNsaWNrcyBvbiB0aGUgc3BlY2lmaWMgbWFwIGNsb3NpbmcgaWNvblxuICogdGhlIGFwcGxpY2F0aW9uIHdpbGwgY2xvc2UgdGhlIHNlbGVjdGVkIG1hcFxuICogYW5kIHdpbGwgbWVyZ2UgdGhlIHJlbWFpbmluZyBvbmUgd2l0aCB0aGUgZ2xvYmFsIHN0YXRlXG4gKiBUT0RPOiBpIHRoaW5rIGluIHRoZSBmdXR1cmUgdGhpcyBhY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBtZXJnZSBtYXAgbGF5ZXJzIHdpdGggZ2xvYmFsIHNldHRpbmdzXG4gKiBAcGFyYW0gc3RhdGVcbiAqIEBwYXJhbSBhY3Rpb25cbiAqIEByZXR1cm5zIHsqfVxuICovXG5mdW5jdGlvbiBjbG9zZVNwZWNpZmljTWFwQXRJbmRleChzdGF0ZSwgYWN0aW9uKSB7XG4gIC8vIHJldHJpZXZlIGxheWVycyBtZXRhIGRhdGEgZnJvbSB0aGUgcmVtYWluaW5nIG1hcCB0aGF0IHdlIG5lZWQgdG8ga2VlcFxuICBjb25zdCBpbmRleFRvUmV0cmlldmUgPSAxIC0gYWN0aW9uLnBheWxvYWQ7XG5cbiAgY29uc3QgbWV0YVNldHRpbmdzID0gc3RhdGUuc3BsaXRNYXBzW2luZGV4VG9SZXRyaWV2ZV07XG4gIGlmICghbWV0YVNldHRpbmdzIHx8ICFtZXRhU2V0dGluZ3MubGF5ZXJzKSB7XG4gICAgLy8gaWYgd2UgY2FuJ3QgZmluZCB0aGUgbWV0YSBzZXR0aW5ncyB3ZSBzaW1wbHkgY2xlYW4gdXAgc3BsaXRNYXBzIGFuZFxuICAgIC8vIGtlZXAgZ2xvYmFsIHN0YXRlIGFzIGl0IGlzXG4gICAgLy8gYnV0IHdoeSBkb2VzIHRoaXMgZXZlciBoYXBwZW4/XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgc3BsaXRNYXBzOiBbXVxuICAgIH07XG4gIH1cblxuICBjb25zdCB7bGF5ZXJzfSA9IHN0YXRlO1xuXG4gIC8vIHVwZGF0ZSBsYXllciB2aXNpYmlsaXR5XG4gIGNvbnN0IG5ld0xheWVycyA9IGxheWVycy5tYXAobGF5ZXIgPT5cbiAgICBsYXllci51cGRhdGVMYXllckNvbmZpZyh7XG4gICAgICBpc1Zpc2libGU6IG1ldGFTZXR0aW5ncy5sYXllcnNbbGF5ZXIuaWRdXG4gICAgICAgID8gbWV0YVNldHRpbmdzLmxheWVyc1tsYXllci5pZF0uaXNWaXNpYmxlXG4gICAgICAgIDogbGF5ZXIuY29uZmlnLmlzVmlzaWJsZVxuICAgIH0pXG4gICk7XG5cbiAgLy8gZGVsZXRlIG1hcFxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyczogbmV3TGF5ZXJzLFxuICAgIHNwbGl0TWFwczogW11cbiAgfTtcbn1cblxuLy8gVE9ETzogcmVkbyB3cml0ZSBoYW5kbGVyIHRvIG5vdCB1c2UgdGFza3NcbmV4cG9ydCBjb25zdCBsb2FkRmlsZXNVcGRhdGVyID0gKHN0YXRlLCBhY3Rpb24pID0+IHtcbiAgY29uc3Qge2ZpbGVzfSA9IGFjdGlvbjtcblxuICBjb25zdCBmaWxlc1RvTG9hZCA9IGZpbGVzLm1hcChmaWxlQmxvYiA9PlxuICAgIHByb2Nlc3NGaWxlVG9Mb2FkKGZpbGVCbG9iLCBmaWxlQmxvYi5pZClcbiAgKTtcblxuICAvLyByZWFkZXIgLT4gcGFyc2VyIC0+IGF1Z21lbnQgLT4gcmVjZWl2ZVZpc0RhdGFcbiAgY29uc3QgbG9hZEZpbGVUYXNrcyA9IFtcbiAgICBUYXNrLmFsbChmaWxlc1RvTG9hZC5tYXAoTE9BRF9GSUxFX1RBU0spKS5iaW1hcChcbiAgICAgIHJlc3VsdHMgPT4ge1xuICAgICAgICBjb25zdCBkYXRhID0gcmVzdWx0cy5yZWR1Y2UoXG4gICAgICAgICAgKGYsIGMpID0+ICh7XG4gICAgICAgICAgICAvLyB1c2luZyBjb25jYXQgaGVyZSBiZWNhdXNlIHRoZSBjdXJyZW50IGRhdGFzZXRzIGNvdWxkIGJlIGFuIGFycmF5IG9yIGEgc2luZ2xlIGl0ZW1cbiAgICAgICAgICAgIGRhdGFzZXRzOiBmLmRhdGFzZXRzLmNvbmNhdChjLmRhdGFzZXRzKSxcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZGVlcCBtZXJnZSB0aGlzIHRoaW5nIHVubGVzcyB3ZSBmaW5kIGEgYmV0dGVyIHNvbHV0aW9uXG4gICAgICAgICAgICAvLyB0aGlzIGNhc2Ugd2lsbCBvbmx5IGhhcHBlbiBpZiB3ZSBhbGxvdyB0byBsb2FkIG11bHRpcGxlIGtlcGxlcmdsIGpzb24gZmlsZXNcbiAgICAgICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgICAuLi5mLmNvbmZpZyxcbiAgICAgICAgICAgICAgLi4uKGMuY29uZmlnIHx8IHt9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHtkYXRhc2V0czogW10sIGNvbmZpZzoge30sIG9wdGlvbnM6IHtjZW50ZXJNYXA6IHRydWV9fVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYWRkRGF0YVRvTWFwKGRhdGEpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IGxvYWRGaWxlc0VycihlcnJvcilcbiAgICApXG4gIF07XG5cbiAgcmV0dXJuIHdpdGhUYXNrKFxuICAgIHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgZmlsZUxvYWRpbmc6IHRydWVcbiAgICB9LFxuICAgIGxvYWRGaWxlVGFza3NcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBsb2FkRmlsZXNFcnJVcGRhdGVyID0gKHN0YXRlLCB7ZXJyb3J9KSA9PiAoe1xuICAuLi5zdGF0ZSxcbiAgZmlsZUxvYWRpbmc6IGZhbHNlLFxuICBmaWxlTG9hZGluZ0VycjogZXJyb3Jcbn0pO1xuXG4vKipcbiAqIGhlbHBlciBmdW5jdGlvbiB0byB1cGRhdGUgQWxsIGxheWVyIGRvbWFpbiBhbmQgbGF5ZXIgZGF0YSBvZiBzdGF0ZVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGRhdGFzZXRzXG4gKiBAcmV0dXJucyB7b2JqZWN0fSBzdGF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRGVmYXVsdExheWVycyhzdGF0ZSwgZGF0YXNldHMpIHtcbiAgY29uc3QgZGVmYXVsdExheWVycyA9IE9iamVjdC52YWx1ZXMoZGF0YXNldHMpLnJlZHVjZShcbiAgICAoYWNjdSwgZGF0YXNldCkgPT4gW1xuICAgICAgLi4uYWNjdSxcbiAgICAgIC4uLihmaW5kRGVmYXVsdExheWVyKGRhdGFzZXQsIHN0YXRlLmxheWVyQ2xhc3NlcykgfHwgW10pXG4gICAgXSxcbiAgICBbXVxuICApO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyczogWy4uLnN0YXRlLmxheWVycywgLi4uZGVmYXVsdExheWVyc10sXG4gICAgbGF5ZXJPcmRlcjogW1xuICAgICAgLy8gcHV0IG5ldyBsYXllcnMgb24gdG9wIG9mIG9sZCBvbmVzXG4gICAgICAuLi5kZWZhdWx0TGF5ZXJzLm1hcCgoXywgaSkgPT4gc3RhdGUubGF5ZXJzLmxlbmd0aCArIGkpLFxuICAgICAgLi4uc3RhdGUubGF5ZXJPcmRlclxuICAgIF1cbiAgfTtcbn1cblxuLyoqXG4gKiBoZWxwZXIgZnVuY3Rpb24gdG8gdXBkYXRlIEFsbCBsYXllciBkb21haW4gYW5kIGxheWVyIGRhdGEgb2Ygc3RhdGVcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3RhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhc2V0c1xuICogQHJldHVybnMge29iamVjdH0gc3RhdGVcbiAqL1xuLy8gZXhwb3J0IGZ1bmN0aW9uIGFkZERlZmF1bHRXaWRnZXQoc3RhdGUsIGRhdGFzZXRzKSB7XG4vLyAgIGNvbnN0IGRlZmF1bHRXaWRnZXQgPSBPYmplY3QudmFsdWVzKGRhdGFzZXRzKS5yZWR1Y2UoXG4vLyAgICAgKGFjY3UsIGRhdGFzZXQpID0+IFtcbi8vICAgICAgIC4uLmFjY3UsXG4vLyAgICAgICAuLi4oZmluZERlZmF1bHRMYXllcihkYXRhc2V0LCBzdGF0ZS53aWRnZXRDbGFzc2VzKSB8fCBbXSlcbi8vICAgICBdLFxuLy8gICAgIFtdXG4vLyAgICk7XG4vLyAgIHJldHVybiB7XG4vLyAgICAgLi4uc3RhdGUsXG4vLyAgICAgd2lkZ2V0czogWy4uLnN0YXRlLndpZGdldHMsIC4uLmRlZmF1bHRXaWRnZXRdLFxuLy8gICAgIGxheWVyT3JkZXI6IFtcbi8vICAgICAgIC8vIHB1dCBuZXcgbGF5ZXJzIG9uIHRvcCBvZiBvbGQgb25lc1xuLy8gICAgICAgLi4uZGVmYXVsdFdpZGdldC5tYXAoKF8sIGkpID0+IHN0YXRlLndpZGdldHMubGVuZ3RoICsgaSksXG4vLyAgICAgICAuLi5zdGF0ZS53aWRnZXRPcmRlclxuLy8gICAgIF1cbi8vICAgfTtcbi8vIH1cblxuLyoqXG4gKiBoZWxwZXIgZnVuY3Rpb24gdG8gZmluZCBkZWZhdWx0IHRvb2x0aXBzXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge29iamVjdH0gZGF0YXNldFxuICogQHJldHVybnMge29iamVjdH0gc3RhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZERlZmF1bHRUb29sdGlwcyhzdGF0ZSwgZGF0YXNldCkge1xuICBjb25zdCB0b29sdGlwRmllbGRzID0gZmluZEZpZWxkc1RvU2hvdyhkYXRhc2V0KTtcblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGludGVyYWN0aW9uQ29uZmlnOiB7XG4gICAgICAuLi5zdGF0ZS5pbnRlcmFjdGlvbkNvbmZpZyxcbiAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgLi4uc3RhdGUuaW50ZXJhY3Rpb25Db25maWcudG9vbHRpcCxcbiAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgLy8gZmluZCBkZWZhdWx0IGZpZWxkcyB0byBzaG93IGluIHRvb2x0aXBcbiAgICAgICAgICBmaWVsZHNUb1Nob3c6IHtcbiAgICAgICAgICAgIC4uLnN0YXRlLmludGVyYWN0aW9uQ29uZmlnLnRvb2x0aXAuY29uZmlnLmZpZWxkc1RvU2hvdyxcbiAgICAgICAgICAgIC4uLnRvb2x0aXBGaWVsZHNcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIHRvIHVwZGF0ZSBsYXllciBkb21haW5zIGZvciBhbiBhcnJheSBvZiBkYXRzZXRzXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlXG4gKiBAcGFyYW0ge2FycmF5IHwgc3RyaW5nfSBkYXRhSWRcbiAqIEBwYXJhbSB7b2JqZWN0fSBuZXdGaWx0ZXIgLSBpZiBpcyBjYWxsZWQgYnkgc2V0RmlsdGVyLCB0aGUgZmlsdGVyIHRoYXQgaGFzIGNoYW5nZWRcbiAqIEByZXR1cm5zIHtvYmplY3R9IHN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBbGxMYXllckRvbWFpbkRhdGEoc3RhdGUsIGRhdGFJZCwgbmV3RmlsdGVyKSB7XG4gIGNvbnN0IGRhdGFJZHMgPSB0eXBlb2YgZGF0YUlkID09PSAnc3RyaW5nJyA/IFtkYXRhSWRdIDogZGF0YUlkO1xuICBjb25zdCBuZXdMYXllcnMgPSBbXTtcbiAgY29uc3QgbmV3TGF5ZXJEYXRhcyA9IFtdO1xuICBzdGF0ZS5sYXllcnMuZm9yRWFjaCgob2xkTGF5ZXIsIGkpID0+IHtcbiAgICBpZiAob2xkTGF5ZXIuY29uZmlnLmRhdGFJZCAmJiBkYXRhSWRzLmluY2x1ZGVzKG9sZExheWVyLmNvbmZpZy5kYXRhSWQpKSB7XG4gICAgICAvLyBObyBuZWVkIHRvIHJlY2FsY3VsYXRlIGxheWVyIGRvbWFpbiBpZiBmaWx0ZXIgaGFzIGZpeGVkIGRvbWFpblxuICAgICAgdmFyIG5ld0xheWVyO1xuICAgICAgaWYgKG9sZExheWVyLnR5cGUgPT09ICdib3VuZGFyeScpIHtcbiAgICAgICAgbmV3TGF5ZXIgPVxuICAgICAgICAgIG5ld0ZpbHRlciAmJiBuZXdGaWx0ZXIuZml4ZWREb21haW5cbiAgICAgICAgICAgID8gb2xkTGF5ZXJcbiAgICAgICAgICAgIDogb2xkTGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oXG4gICAgICAgICAgICAgICAgc3RhdGUuZGF0YXNldHNbb2xkTGF5ZXIuY29uZmlnLmRhdGFJZF0sXG4gICAgICAgICAgICAgICAgc3RhdGUubGF5ZXJEYXRhW2ldLFxuICAgICAgICAgICAgICAgIG5ld0ZpbHRlclxuICAgICAgICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3TGF5ZXIgPVxuICAgICAgICAgIG5ld0ZpbHRlciAmJiBuZXdGaWx0ZXIuZml4ZWREb21haW5cbiAgICAgICAgICAgID8gb2xkTGF5ZXJcbiAgICAgICAgICAgIDogb2xkTGF5ZXIudXBkYXRlTGF5ZXJEb21haW4oXG4gICAgICAgICAgICAgICAgc3RhdGUuZGF0YXNldHNbb2xkTGF5ZXIuY29uZmlnLmRhdGFJZF0sXG4gICAgICAgICAgICAgICAgbmV3RmlsdGVyXG4gICAgICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YXIge2xheWVyRGF0YSwgbGF5ZXJ9ID0gY2FsY3VsYXRlTGF5ZXJEYXRhKFxuICAgICAgICBuZXdMYXllcixcbiAgICAgICAgc3RhdGUsXG4gICAgICAgIHN0YXRlLmxheWVyRGF0YVtpXVxuICAgICAgKTtcbiAgICAgIC8vIGxldCBkYXRhID0gbGF5ZXIuYXhpb3NBcGlDYWxsKCk7XG4gICAgICAvLyBjb25zb2xlLmxvZyhkYXRhKTtcbiAgICAgIC8vICAgaWYgKGxheWVyLnR5cGUgPT09ICdib3VuZGFyeScpIHtcbiAgICAgIC8vICAgICAvLyBjb25zb2xlLmxvZygncmVhY2hpbmcgZGF0YScpO1xuICAgICAgLy8gICAgIGRhdGEudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgIC8vICAgICAgIC8vIGNvbnNvbGUubG9nKCdwcm9taXNlIHJlc3VsdCcsIHJlc3VsdCk7XG4gICAgICAvLyAgICAgICAvLyBjb25zdCB0ZXN0RGF0YSA9IGxheWVyLmZvcm1hdExheWVyKCk7XG4gICAgICAvLyAgICAgICB2YXIge2xheWVyRGF0YSwgbGF5ZXJ9ID0gY2FsY3VsYXRlTGF5ZXJEYXRhQWZ0ZXJBUElDYWxsKFxuICAgICAgLy8gICAgICAgICBuZXdMYXllcixcbiAgICAgIC8vICAgICAgICAgc3RhdGUsXG4gICAgICAvLyAgICAgICAgIGxheWVyRGF0YSxcbiAgICAgIC8vICAgICAgICAgcmVzdWx0XG4gICAgICAvLyAgICAgICApO1xuICAgICAgLy8gICAgICAgLy8gY29uc29sZS5sb2coJ2ZpbHRlcmVkIGxheWVyRGF0YSBhbmQgbGF5ZXInLCBsYXllckRhdGEsIGxheWVyKTtcbiAgICAgIC8vICAgICAgIGxheWVyRGF0YSA9IHtcbiAgICAgIC8vICAgICAgICAgLi4ubGF5ZXJEYXRhLFxuICAgICAgLy8gICAgICAgICByZXN1bHRcbiAgICAgIC8vICAgICAgIH07XG4gICAgICAvLyAgICAgICBuZXdMYXllcnNbaV0gPSBsYXllcjtcbiAgICAgIC8vICAgICAgIG5ld0xheWVyRGF0YXNbaV0gPSBsYXllckRhdGE7XG4gICAgICAvLyAgICAgICAvLyBjb25zb2xlLmxvZygncmV0dXJuIGluc2lkZSBhcGkgY2FsbCcsIG5ld0xheWVycywgbmV3TGF5ZXJEYXRhcyk7XG4gICAgICAvLyAgICAgICAvLyByZXR1cm4ge1xuICAgICAgLy8gICAgICAgLy8gICAuLi5zdGF0ZSxcbiAgICAgIC8vICAgICAgIC8vICAgbGF5ZXJzOiB7XG4gICAgICAvLyAgICAgICAvLyAgICAgLi4uc3RhdGUubGF5ZXJzLFxuICAgICAgLy8gICAgICAgLy8gICAgIFtzdGF0ZS5sYXllcnNbaV1dOiBsYXllclxuICAgICAgLy8gICAgICAgLy8gICB9LFxuICAgICAgLy8gICAgICAgLy8gICBsYXllckRhdGE6IHtcbiAgICAgIC8vICAgICAgIC8vICAgICAuLi5zdGF0ZS5sYXllckRhdGEsXG4gICAgICAvLyAgICAgICAvLyAgICAgW3N0YXRlLmxheWVyRGF0YVtpXV06IGxheWVyRGF0YVxuICAgICAgLy8gICAgICAgLy8gICB9XG4gICAgICAvLyAgICAgICAvLyB9O1xuICAgICAgLy8gICAgIH0pO1xuICAgICAgLy8gICB9XG4gICAgICAvLyAgIC8vIGNvbnNvbGUubG9nKCdmaWx0ZXJlZCBTdGF0ZScsIHN0YXRlKTtcbiAgICAgIC8vICAgLy8gY29uc29sZS5sb2cobGF5ZXJEYXRhKTtcbiAgICAgIG5ld0xheWVycy5wdXNoKGxheWVyKTtcbiAgICAgIG5ld0xheWVyRGF0YXMucHVzaChsYXllckRhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdMYXllcnMucHVzaChvbGRMYXllcik7XG4gICAgICBuZXdMYXllckRhdGFzLnB1c2goc3RhdGUubGF5ZXJEYXRhW2ldKTtcbiAgICB9XG4gIH0pO1xuICAvLyBjb25zb2xlLmxvZygnbmV3IGxheWVycyBhbmQgbGF5ZXIgZGF0YScsIG5ld0xheWVycywgbmV3TGF5ZXJEYXRhcyk7XG4gIC8vIGNvbnNvbGUubG9nKCdyZXR1cm4gaW5zaWRlIHVwZGF0ZUFsbERhdGFEb21haW4gJyk7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBuZXdMYXllcnMsXG4gICAgbGF5ZXJEYXRhOiBuZXdMYXllckRhdGFzXG4gIH07XG59XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIHRvIHJlY2FsY3VsdGUgd2lkZ2V0IGFnZ3JlZ2F0aW9uRGF0YSBldmVyeXRpbWUgbGF5ZXJEYXRhIGlzIHVwZGF0ZWRcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3RhdGVcbiAqIEByZXR1cm5zIHtvYmplY3R9IHN0YXRlXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVdpZGdldEFnZ3JlZ2F0aW9uRGF0YShzdGF0ZSkge1xuICB2YXIgd2lkZ2V0cyA9IHN0YXRlLndpZGdldHM7XG4gIHZhciBuZXdXaWRnZXRzID0gW107XG5cbiAgd2lkZ2V0cy5tYXAodyA9PiB7XG4gICAgY29uc3Qge25ld1dpZGdldH0gPSB3LmNhbGN1bGF0ZUFnZ3JlZ2F0aW9uRGF0YSh3LCBzdGF0ZSk7XG4gICAgbmV3V2lkZ2V0cy5wdXNoKG5ld1dpZGdldCk7XG4gIH0pO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIHdpZGdldHM6IG5ld1dpZGdldHNcbiAgfTtcbn1cblxuLyoqXG4gKiBoZWxwZXIgZnVuY3Rpb24gdG8gdXBkYXRlIHN0YXRlc1xuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdGF0ZVxuICogQHJldHVybnMge29iamVjdH0gc3RhdGVcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoTGF5ZXJEYXRhVXBkYXRlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIGNvbnN0IHtjb2xsZWN0ZWR9ID0gYWN0aW9uO1xuICBjb25zdCBuZXdMYXllciA9IGFjdGlvbi5sYXllcjtcbiAgY29uc3QgaWR4ID0gc3RhdGUubGF5ZXJzLmZpbmRJbmRleChsID0+IGwuaWQgPT09IG5ld0xheWVyLmlkKTtcbiAgdmFyIHtsYXllckRhdGEsIGxheWVyfSA9IGNhbGN1bGF0ZUxheWVyRGF0YUFmdGVyQVBJQ2FsbChcbiAgICBuZXdMYXllcixcbiAgICBzdGF0ZSxcbiAgICBzdGF0ZS5sYXllckRhdGFbaWR4XSxcbiAgICBjb2xsZWN0ZWQsXG4gICAge3NhbWVEYXRhOiB0cnVlfVxuICApO1xuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGxheWVyRGF0YTogc3RhdGUubGF5ZXJEYXRhLm1hcCgobHlyRGF0YSwgaSkgPT5cbiAgICAgIGkgPT09IGlkeCA/IGxheWVyRGF0YSA6IGx5ckRhdGFcbiAgICApXG4gIH07XG59XG5cbi8qKlxuICogaGVscGVyIGZ1bmN0aW9uIGZvciBhc3luYyBBUEkgY2FsbFxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBzdGF0ZVxuICogQHJldHVybnMge29iamVjdH0gZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBpQ2FsbERhdGEoc3RhdGUsIGFjdGlvbikge1xuICAvLyBjb25zb2xlLmxvZyhzdGF0ZSwgYWN0aW9uKTtcbiAgY29uc3Qge2xheWVyfSA9IGFjdGlvbjtcbiAgY29uc3Qge2FsbERhdGF9ID0gc3RhdGUuZGF0YXNldHNbbGF5ZXIuY29uZmlnLmRhdGFJZF07XG4gIC8vIGNvbnNvbGUubG9nKGFsbERhdGEpO1xuICByZXR1cm4gc3RhdGU7XG59XG4iXX0=