UNPKG

kepler.gl

Version:

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

1,538 lines • 213 kB
"use strict";

var _typeof3 = require("@babel/runtime/helpers/typeof");
var _regeneratorRuntime2 = require("@babel/runtime/regenerator");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.layerColors = exports.defaultGetFieldValue = exports["default"] = exports.colorMaker = exports.OVERLAY_TYPE_CONST = exports.LAYER_ID_LENGTH = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _core = require("@deck.gl/core");
var _deckglArrowLayers = require("@kepler.gl/deckgl-arrow-layers");
var _extensions = require("@deck.gl/extensions");
var _layers = require("@deck.gl/layers");
var _window = require("global/window");
var _keymirror = _interopRequireDefault(require("keymirror"));
var arrow = _interopRequireWildcard(require("apache-arrow"));
var _defaultLayerIcon = _interopRequireDefault(require("./default-layer-icon"));
var _layerUpdate = require("./layer-update");
var _layerUtils = require("./layer-utils");
var _constants = require("@kepler.gl/constants");
var _utils = require("@kepler.gl/utils");
var _commonUtils = require("@kepler.gl/common-utils");
var _lodash = _interopRequireDefault(require("lodash.memoize"));
var _getApplicationConfig; // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var _marked = /*#__PURE__*/_regeneratorRuntime2.mark(generateColor);
/**
 * Approx. number of points to sample in a large data set
 */
var LAYER_ID_LENGTH = exports.LAYER_ID_LENGTH = 6;
var MAX_SAMPLE_SIZE = 5000;
var defaultDomain = [0, 1];
var dataFilterExtension = new _extensions.DataFilterExtension({
  filterSize: _constants.MAX_GPU_FILTERS,
  // `countItems` option. It enables the GPU to report the number of objects that pass the filter criteria via the `onFilteredItemsChange` callback.
  // @ts-expect-error not typed
  countItems: (_getApplicationConfig = (0, _utils.getApplicationConfig)().useOnFilteredItemsChange) !== null && _getApplicationConfig !== void 0 ? _getApplicationConfig : false
});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
var defaultDataAccessor = function defaultDataAccessor(dc) {
  return function (d) {
    return d;
  };
};
var identity = function identity(d) {
  return d;
};
// Can't use fiedValueAccesor because need the raw data to render tooltip
// SHAN: Revisit here
var defaultGetFieldValue = exports.defaultGetFieldValue = function defaultGetFieldValue(field, d) {
  return field.valueAccessor(d);
};
var OVERLAY_TYPE_CONST = exports.OVERLAY_TYPE_CONST = (0, _keymirror["default"])({
  deckgl: null,
  mapboxgl: null
});
var layerColors = exports.layerColors = Object.values(_constants.DataVizColors).map(_utils.hexToRgb);
function generateColor() {
  var index;
  return _regenerator["default"].wrap(function generateColor$(_context) {
    while (1) switch (_context.prev = _context.next) {
      case 0:
        index = 0;
      case 1:
        if (!(index < layerColors.length + 1)) {
          _context.next = 7;
          break;
        }
        if (index === layerColors.length) {
          index = 0;
        }
        _context.next = 5;
        return layerColors[index++];
      case 5:
        _context.next = 1;
        break;
      case 7:
      case "end":
        return _context.stop();
    }
  }, _marked);
}
var colorMaker = exports.colorMaker = generateColor();
var Layer = /*#__PURE__*/function () {
  function Layer(props) {
    (0, _classCallCheck2["default"])(this, Layer);
    (0, _defineProperty2["default"])(this, "id", void 0);
    (0, _defineProperty2["default"])(this, "meta", void 0);
    (0, _defineProperty2["default"])(this, "visConfigSettings", void 0);
    (0, _defineProperty2["default"])(this, "config", void 0);
    // TODO: define _oldDataUpdateTriggers
    (0, _defineProperty2["default"])(this, "_oldDataUpdateTriggers", void 0);
    (0, _defineProperty2["default"])(this, "isValid", void 0);
    (0, _defineProperty2["default"])(this, "errorMessage", void 0);
    (0, _defineProperty2["default"])(this, "filteredItemCount", void 0);
    this.id = props.id || (0, _commonUtils.generateHashId)(LAYER_ID_LENGTH);
    // meta
    this.meta = {};

    // visConfigSettings
    this.visConfigSettings = {};
    this.config = this.getDefaultLayerConfig(props);

    // set columnMode from supported columns
    if (!this.config.columnMode) {
      var supportedColumnModes = this.supportedColumnModes;
      if (supportedColumnModes !== null && supportedColumnModes !== void 0 && supportedColumnModes.length) {
        var _supportedColumnModes;
        this.config.columnMode = (_supportedColumnModes = supportedColumnModes[0]) === null || _supportedColumnModes === void 0 ? void 0 : _supportedColumnModes.key;
      }
    }
    // then set column, columnMode should already been set
    this.config.columns = this.getLayerColumns(props.columns);

    // false indicates that the layer caused an error, and was disabled
    this.isValid = true;
    this.errorMessage = null;
    // item count
    this.filteredItemCount = {};
  }
  return (0, _createClass2["default"])(Layer, [{
    key: "layerIcon",
    get: function get() {
      return _defaultLayerIcon["default"];
    }
  }, {
    key: "overlayType",
    get: function get() {
      return OVERLAY_TYPE_CONST.deckgl;
    }
  }, {
    key: "type",
    get: function get() {
      return null;
    }
  }, {
    key: "name",
    get: function get() {
      return this.type;
    }
  }, {
    key: "isAggregated",
    get: function get() {
      return false;
    }
  }, {
    key: "requiredLayerColumns",
    get: function get() {
      var supportedColumnModes = this.supportedColumnModes;
      if (supportedColumnModes) {
        return supportedColumnModes.reduce(function (acc, obj) {
          return obj.requiredColumns ? acc.concat(obj.requiredColumns) : acc;
        }, []);
      }
      return [];
    }
  }, {
    key: "optionalColumns",
    get: function get() {
      var supportedColumnModes = this.supportedColumnModes;
      if (supportedColumnModes) {
        return supportedColumnModes.reduce(function (acc, obj) {
          return obj.optionalColumns ? acc.concat(obj.optionalColumns) : acc;
        }, []);
      }
      return [];
    }
  }, {
    key: "noneLayerDataAffectingProps",
    get: function get() {
      return ['label', 'opacity', 'thickness', 'isVisible', 'hidden'];
    }
  }, {
    key: "visualChannels",
    get: function get() {
      return {
        color: {
          property: 'color',
          field: 'colorField',
          scale: 'colorScale',
          domain: 'colorDomain',
          range: 'colorRange',
          key: 'color',
          channelScaleType: _constants.CHANNEL_SCALES.color,
          nullValue: _constants.NO_VALUE_COLOR,
          defaultValue: function defaultValue(config) {
            return config.color;
          }
        },
        size: {
          property: 'size',
          field: 'sizeField',
          scale: 'sizeScale',
          domain: 'sizeDomain',
          range: 'sizeRange',
          key: 'size',
          channelScaleType: _constants.CHANNEL_SCALES.size,
          nullValue: 0,
          defaultValue: 1
        }
      };
    }
  }, {
    key: "columnValidators",
    get: function get() {
      return {};
    }
    /*
     * Column pairs maps layer column to a specific field pairs,
     * By default, it is set to null
     */
  }, {
    key: "columnPairs",
    get: function get() {
      return null;
    }

    /**
     * Column labels if its different than column key
     */
  }, {
    key: "columnLabels",
    get: function get() {
      return null;
    }

    /*
     * Default point column pairs, can be used for point based layers: point, icon etc.
     */
  }, {
    key: "defaultPointColumnPairs",
    get: function get() {
      return {
        lat: {
          pair: ['lng', 'altitude'],
          fieldPairKey: 'lat'
        },
        lng: {
          pair: ['lat', 'altitude'],
          fieldPairKey: 'lng'
        },
        altitude: {
          pair: ['lng', 'lat'],
          fieldPairKey: 'altitude'
        }
      };
    }

    /*
     * Default link column pairs, can be used for link based layers: arc, line etc
     */
  }, {
    key: "defaultLinkColumnPairs",
    get: function get() {
      return {
        lat: {
          pair: ['lng', 'alt'],
          fieldPairKey: 'lat'
        },
        lng: {
          pair: ['lat', 'alt'],
          fieldPairKey: 'lng'
        },
        alt: {
          pair: ['lng', 'lat'],
          fieldPairKey: 'altitude'
        },
        lat0: {
          pair: 'lng0',
          fieldPairKey: 'lat'
        },
        lng0: {
          pair: 'lat0',
          fieldPairKey: 'lng'
        },
        alt0: {
          pair: ['lng0', 'lat0'],
          fieldPairKey: 'altitude'
        },
        lat1: {
          pair: 'lng1',
          fieldPairKey: 'lat'
        },
        lng1: {
          pair: 'lat1',
          fieldPairKey: 'lng'
        },
        alt1: {
          pair: ['lng1', 'lat1'],
          fieldPairKey: 'altitude'
        }
      };
    }

    /**
     * Return a React component for to render layer instructions in a modal
     * @returns {object} - an object
     * @example
     *  return {
     *    id: 'iconInfo',
     *    template: IconInfoModal,
     *    modalProps: {
     *      title: 'How to draw icons'
     *   };
     * }
     */
  }, {
    key: "layerInfoModal",
    get: function get() {
      return null;
    }

    /**
     * Returns which column modes this layer supports
     */
  }, {
    key: "supportedColumnModes",
    get: function get() {
      return null;
    }
  }, {
    key: "supportedDatasetTypes",
    get: function get() {
      return null;
    }

    /*
     * Given a dataset, automatically find props to create layer based on it
     * and return the props and previous found layers.
     * By default, no layers will be found
     */
  }, {
    key: "getDefaultLayerConfig",
    value: function getDefaultLayerConfig(props) {
      var _props$isVisible, _props$isConfigActive, _props$hidden;
      return _objectSpread({
        dataId: props.dataId,
        label: props.label || _constants.DEFAULT_LAYER_LABEL,
        color: props.color || colorMaker.next().value,
        // set columns later
        columns: {},
        isVisible: (_props$isVisible = props.isVisible) !== null && _props$isVisible !== void 0 ? _props$isVisible : true,
        isConfigActive: (_props$isConfigActive = props.isConfigActive) !== null && _props$isConfigActive !== void 0 ? _props$isConfigActive : false,
        highlightColor: props.highlightColor || _constants.DEFAULT_HIGHLIGHT_COLOR,
        hidden: (_props$hidden = props.hidden) !== null && _props$hidden !== void 0 ? _props$hidden : false,
        // TODO: refactor this into separate visual Channel config
        // color by field, domain is set by filters, field, scale type
        colorField: null,
        colorDomain: [0, 1],
        colorScale: _constants.SCALE_TYPES.quantile,
        // color by size, domain is set by filters, field, scale type
        sizeDomain: [0, 1],
        sizeScale: _constants.SCALE_TYPES.linear,
        sizeField: null,
        visConfig: {},
        textLabel: [_constants.DEFAULT_TEXT_LABEL],
        colorUI: {
          color: _constants.DEFAULT_COLOR_UI,
          colorRange: _constants.DEFAULT_COLOR_UI
        },
        animation: {
          enabled: false
        }
      }, props.columnMode ? {
        columnMode: props.columnMode
      } : {});
    }

    /**
     * Get the description of a visualChannel config
     * @param key
     * @returns
     */
  }, {
    key: "getVisualChannelDescription",
    value: function getVisualChannelDescription(key) {
      // e.g. label: Color, measure: Vehicle Type
      var channel = this.visualChannels[key];
      if (!channel) return {
        label: '',
        measure: undefined
      };
      var rangeSettings = this.visConfigSettings[channel.range];
      var fieldSettings = this.config[channel.field];
      var label = rangeSettings === null || rangeSettings === void 0 ? void 0 : rangeSettings.label;
      return {
        label: typeof label === 'function' ? label(this.config) : label || '',
        measure: fieldSettings ? fieldSettings.displayName || fieldSettings.name : channel.defaultMeasure
      };
    }

    /**
     * Assign a field to layer column, return column config
     */
  }, {
    key: "assignColumn",
    value: function assignColumn(key, field) {
      var _this$config$columns;
      // field value could be null for optional columns
      var update = field ? {
        value: field.name,
        fieldIdx: field.fieldIdx
      } : {
        value: null,
        fieldIdx: -1
      };
      return _objectSpread(_objectSpread({}, this.config.columns), {}, (0, _defineProperty2["default"])({}, key, _objectSpread(_objectSpread({}, (_this$config$columns = this.config.columns) === null || _this$config$columns === void 0 ? void 0 : _this$config$columns[key]), update)));
    }

    /**
     * Assign a field pair to column config, return column config
     */
  }, {
    key: "assignColumnPairs",
    value: function assignColumnPairs(key, fieldPairs) {
      var _this$columnPairs, _this$columnPairs2;
      if (!this.columnPairs || !((_this$columnPairs = this.columnPairs) !== null && _this$columnPairs !== void 0 && _this$columnPairs[key])) {
        // should not end in this state
        return this.config.columns;
      }
      // key = 'lat'
      var _ref = ((_this$columnPairs2 = this.columnPairs) === null || _this$columnPairs2 === void 0 ? void 0 : _this$columnPairs2[key]) || {},
        pair = _ref.pair,
        fieldPairKey = _ref.fieldPairKey;
      if (typeof fieldPairKey === 'string' && !fieldPairs[fieldPairKey]) {
        // do not allow `key: undefined` to creep into the `updatedColumn` object
        return this.config.columns;
      }

      // pair = ['lng', 'alt] | 'lng'
      var updatedColumn = _objectSpread(_objectSpread({}, this.config.columns), {}, (0, _defineProperty2["default"])({}, key, fieldPairs[fieldPairKey]));
      var partnerKeys = (0, _commonUtils.toArray)(pair);
      var _iterator = _createForOfIteratorHelper(partnerKeys),
        _step;
      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var _this$columnPairs3, _this$columnPairs4;
          var partnerKey = _step.value;
          if (this.config.columns[partnerKey] && (_this$columnPairs3 = this.columnPairs) !== null && _this$columnPairs3 !== void 0 && _this$columnPairs3[partnerKey] &&
          // @ts-ignore
          fieldPairs[(_this$columnPairs4 = this.columnPairs) === null || _this$columnPairs4 === void 0 ? void 0 : _this$columnPairs4[partnerKey].fieldPairKey]) {
            var _this$columnPairs5;
            // @ts-ignore
            updatedColumn[partnerKey] = fieldPairs[(_this$columnPairs5 = this.columnPairs) === null || _this$columnPairs5 === void 0 ? void 0 : _this$columnPairs5[partnerKey].fieldPairKey];
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
      return updatedColumn;
    }

    /**
     * Calculate a radius zoom multiplier to render points, so they are visible in all zoom level
     * @param {object} mapState
     * @param {number} mapState.zoom - actual zoom
     * @param {number | void} mapState.zoomOffset - zoomOffset when render in the plot container for export image
     * @returns {number}
     */
  }, {
    key: "getZoomFactor",
    value: function getZoomFactor(_ref2) {
      var zoom = _ref2.zoom,
        _ref2$zoomOffset = _ref2.zoomOffset,
        zoomOffset = _ref2$zoomOffset === void 0 ? 0 : _ref2$zoomOffset;
      return Math.pow(2, Math.max(14 - zoom + zoomOffset, 0));
    }

    /**
     * Calculate a elevation zoom multiplier to render points, so they are visible in all zoom level
     * @param {object} mapState
     * @param {number} mapState.zoom - actual zoom
     * @param {number=} mapState.zoomOffset - zoomOffset when render in the plot container for export image
     * @returns {number}
     */
  }, {
    key: "getElevationZoomFactor",
    value: function getElevationZoomFactor(_ref3) {
      var zoom = _ref3.zoom,
        _ref3$zoomOffset = _ref3.zoomOffset,
        zoomOffset = _ref3$zoomOffset === void 0 ? 0 : _ref3$zoomOffset;
      // enableElevationZoomFactor is used to support existing maps
      var _this$config$visConfi = this.config.visConfig,
        fixedHeight = _this$config$visConfi.fixedHeight,
        enableElevationZoomFactor = _this$config$visConfi.enableElevationZoomFactor;
      return fixedHeight || enableElevationZoomFactor === false ? 1 : Math.pow(2, Math.max(8 - zoom + zoomOffset, 0));
    }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  }, {
    key: "formatLayerData",
    value: function formatLayerData(datasets, oldLayerData, animationConfig) {
      return {};
    }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  }, {
    key: "renderLayer",
    value: function renderLayer() {
      return [];
    }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  }, {
    key: "getHoverData",
    value: function getHoverData(object, dataContainer,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    fields,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    animationConfig,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    hoverInfo) {
      if (!object) {
        return null;
      }

      // By default, each entry of layerData should have an index of a row in the original data container.
      // Each layer can implement its own getHoverData method
      return dataContainer.row(object.index);
    }
  }, {
    key: "getFilteredItemCount",
    value: function getFilteredItemCount() {
      // use first layer
      if (Object.keys(this.filteredItemCount).length) {
        var firstLayer = Object.keys(this.filteredItemCount)[0];
        return this.filteredItemCount[firstLayer];
      }
      return null;
    }
    /**
     * When change layer type, try to copy over layer configs as much as possible
     * @param configToCopy - config to copy over
     * @param visConfigSettings - visConfig settings of config to copy
     * @param datasets - current datasets.
     * @param defaultLayerProps - default layer creation configurations for current layer and datasets.
     */
  }, {
    key: "assignConfigToLayer",
    value: function assignConfigToLayer(configToCopy, visConfigSettings, datasets, defaultLayerProps) {
      var _this = this;
      // don't deep merge visualChannel field
      // don't deep merge color range, reversed: is not a key by default
      var shallowCopy = ['colorRange', 'strokeColorRange'].concat(Object.values(this.visualChannels).map(function (v) {
        return v.field;
      }));

      // don't copy over domain and animation
      var notToCopy = ['animation'].concat(Object.values(this.visualChannels).map(function (v) {
        return v.domain;
      }));
      // if range is for the same property group copy it, otherwise, not to copy
      Object.values(this.visualChannels).forEach(function (v) {
        if (configToCopy.visConfig[v.range] && _this.visConfigSettings[v.range] && visConfigSettings[v.range].group !== _this.visConfigSettings[v.range].group) {
          notToCopy.push(v.range);
        }
      });

      // don't copy over visualChannel range
      var currentConfig = this.config;
      var copied = this.copyLayerConfig(currentConfig, configToCopy, {
        shallowCopy: shallowCopy,
        notToCopy: notToCopy
      });

      // update columNode based on new columns
      if (this.config.columnMode && this.supportedColumnModes) {
        var _satisfiedColumnMode;
        var dataset = datasets === null || datasets === void 0 ? void 0 : datasets[this.config.dataId];
        // try to find a mode with all requied columns from the source config
        var satisfiedColumnMode = (0, _layerUtils.getSatisfiedColumnMode)(this.supportedColumnModes, copied.columns, dataset === null || dataset === void 0 ? void 0 : dataset.fields);

        // if no suitable column mode found or no such columMode exists for the layer
        // then try use one of the automatically detected layer configs
        if (!satisfiedColumnMode) {
          var options = [].concat((0, _toConsumableArray2["default"])((defaultLayerProps === null || defaultLayerProps === void 0 ? void 0 : defaultLayerProps.props) || []), (0, _toConsumableArray2["default"])((defaultLayerProps === null || defaultLayerProps === void 0 ? void 0 : defaultLayerProps.altProps) || []));
          if (options.length) {
            // Use the first of the default configurations
            var defaultColumnConfig = options[0].columns;
            satisfiedColumnMode = (0, _layerUtils.getSatisfiedColumnMode)(this.supportedColumnModes, defaultColumnConfig, dataset === null || dataset === void 0 ? void 0 : dataset.fields);
            if (satisfiedColumnMode) {
              copied.columns = _objectSpread(_objectSpread({}, copied.columns), defaultColumnConfig);
            }
          }
        }
        copied.columnMode = ((_satisfiedColumnMode = satisfiedColumnMode) === null || _satisfiedColumnMode === void 0 ? void 0 : _satisfiedColumnMode.key) || copied.columnMode;
      }
      this.updateLayerConfig(copied);
      // validate visualChannel field type and scale types
      Object.keys(this.visualChannels).forEach(function (channel) {
        _this.validateVisualChannel(channel);
      });
    }

    /*
     * Recursively copy config over to an empty layer
     * when received saved config, or copy config over from a different layer type
     * make sure to only copy over value to existing keys
     * @param {object} currentConfig - existing config to be override
     * @param {object} configToCopy - new Config to copy over
     * @param {string[]} shallowCopy - array of properties to not to be deep copied
     * @param {string[]} notToCopy - array of properties not to copy
     * @returns {object} - copied config
     */
  }, {
    key: "copyLayerConfig",
    value: function copyLayerConfig(currentConfig, configToCopy) {
      var _this2 = this;
      var _ref4 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
        _ref4$shallowCopy = _ref4.shallowCopy,
        shallowCopy = _ref4$shallowCopy === void 0 ? [] : _ref4$shallowCopy,
        _ref4$notToCopy = _ref4.notToCopy,
        notToCopy = _ref4$notToCopy === void 0 ? [] : _ref4$notToCopy;
      var copied = {};
      Object.keys(currentConfig).forEach(function (key) {
        if ((0, _utils.isPlainObject)(currentConfig[key]) && (0, _utils.isPlainObject)(configToCopy[key]) && !shallowCopy.includes(key) && !notToCopy.includes(key)) {
          // recursively assign object value
          copied[key] = _this2.copyLayerConfig(currentConfig[key], configToCopy[key], {
            shallowCopy: shallowCopy,
            notToCopy: notToCopy
          });
        } else if ((0, _commonUtils.notNullorUndefined)(configToCopy[key]) && !notToCopy.includes(key)) {
          // copy
          copied[key] = configToCopy[key];
        } else {
          // keep existing
          copied[key] = currentConfig[key];
        }
      });
      return copied;
    }
  }, {
    key: "registerVisConfig",
    value: function registerVisConfig(layerVisConfigs) {
      var _this3 = this;
      Object.keys(layerVisConfigs).forEach(function (item) {
        var configItem = layerVisConfigs[item];
        if (typeof configItem === 'string' && _constants.LAYER_VIS_CONFIGS[configItem]) {
          // if assigned one of default LAYER_CONFIGS
          _this3.config.visConfig[item] = _constants.LAYER_VIS_CONFIGS[configItem].defaultValue;
          _this3.visConfigSettings[item] = _constants.LAYER_VIS_CONFIGS[configItem];
        } else if ((0, _typeof2["default"])(configItem) === 'object' && ['type', 'defaultValue'].every(function (p) {
          return Object.prototype.hasOwnProperty.call(configItem, p);
        })) {
          // if provided customized visConfig, and has type && defaultValue
          // TODO: further check if customized visConfig is valid
          _this3.config.visConfig[item] = configItem.defaultValue;
          _this3.visConfigSettings[item] = configItem;
        }
      });
    }
  }, {
    key: "getLayerColumns",
    value: function getLayerColumns() {
      var propsColumns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var columnValidators = this.columnValidators || {};
      var required = this.requiredLayerColumns.reduce(function (accu, key) {
        var _propsColumns$key$val, _propsColumns$key, _propsColumns$key$fie, _propsColumns$key2, _propsColumns$key$val2, _propsColumns$key3, _propsColumns$key$fie2, _propsColumns$key4;
        return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, columnValidators[key] ? {
          value: (_propsColumns$key$val = (_propsColumns$key = propsColumns[key]) === null || _propsColumns$key === void 0 ? void 0 : _propsColumns$key.value) !== null && _propsColumns$key$val !== void 0 ? _propsColumns$key$val : null,
          fieldIdx: (_propsColumns$key$fie = (_propsColumns$key2 = propsColumns[key]) === null || _propsColumns$key2 === void 0 ? void 0 : _propsColumns$key2.fieldIdx) !== null && _propsColumns$key$fie !== void 0 ? _propsColumns$key$fie : -1,
          validator: columnValidators[key]
        } : {
          value: (_propsColumns$key$val2 = (_propsColumns$key3 = propsColumns[key]) === null || _propsColumns$key3 === void 0 ? void 0 : _propsColumns$key3.value) !== null && _propsColumns$key$val2 !== void 0 ? _propsColumns$key$val2 : null,
          fieldIdx: (_propsColumns$key$fie2 = (_propsColumns$key4 = propsColumns[key]) === null || _propsColumns$key4 === void 0 ? void 0 : _propsColumns$key4.fieldIdx) !== null && _propsColumns$key$fie2 !== void 0 ? _propsColumns$key$fie2 : -1
        }));
      }, {});
      var optional = this.optionalColumns.reduce(function (accu, key) {
        var _propsColumns$key$val3, _propsColumns$key5, _propsColumns$key$fie3, _propsColumns$key6;
        return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, {
          value: (_propsColumns$key$val3 = (_propsColumns$key5 = propsColumns[key]) === null || _propsColumns$key5 === void 0 ? void 0 : _propsColumns$key5.value) !== null && _propsColumns$key$val3 !== void 0 ? _propsColumns$key$val3 : null,
          fieldIdx: (_propsColumns$key$fie3 = (_propsColumns$key6 = propsColumns[key]) === null || _propsColumns$key6 === void 0 ? void 0 : _propsColumns$key6.fieldIdx) !== null && _propsColumns$key$fie3 !== void 0 ? _propsColumns$key$fie3 : -1,
          optional: true
        }));
      }, {});
      var columns = _objectSpread(_objectSpread({}, required), optional);
      return columns;
    }
  }, {
    key: "updateLayerConfig",
    value: function updateLayerConfig(newConfig) {
      this.config = _objectSpread(_objectSpread({}, this.config), newConfig);
      return this;
    }
  }, {
    key: "updateLayerVisConfig",
    value: function updateLayerVisConfig(newVisConfig) {
      this.config.visConfig = _objectSpread(_objectSpread({}, this.config.visConfig), newVisConfig);
      return this;
    }
  }, {
    key: "updateLayerColorUI",
    value: function updateLayerColorUI(prop, newConfig) {
      var _this$config = this.config,
        previous = _this$config.colorUI,
        visConfig = _this$config.visConfig;
      if (!(0, _utils.isPlainObject)(newConfig) || typeof prop !== 'string') {
        return this;
      }
      var colorUIProp = Object.entries(newConfig).reduce(function (accu, _ref5) {
        var _ref6 = (0, _slicedToArray2["default"])(_ref5, 2),
          key = _ref6[0],
          value = _ref6[1];
        return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, (0, _utils.isPlainObject)(accu[key]) && (0, _utils.isPlainObject)(value) ? _objectSpread(_objectSpread({}, accu[key]), value) : value));
      }, previous[prop] || _constants.DEFAULT_COLOR_UI);
      var colorUI = _objectSpread(_objectSpread({}, previous), {}, (0, _defineProperty2["default"])({}, prop, colorUIProp));
      this.updateLayerConfig({
        colorUI: colorUI
      });
      // if colorUI[prop] is colorRange
      var isColorRange = visConfig[prop] && visConfig[prop].colors;
      if (isColorRange) {
        // if open dropdown and prop is color range
        // Automatically set colorRangeConfig's step and reversed
        this.updateColorUIByColorRange(newConfig, prop);

        // if changes in UI is made to 'reversed', 'steps' or steps
        // update current layer colorRange
        this.updateColorRangeByColorUI(newConfig, previous, prop);

        // if set colorRangeConfig to custom
        // initiate customPalette to be edited in the ui
        this.updateCustomPalette(newConfig, previous, prop);
      }
      return this;
    }

    // if set colorRangeConfig to custom palette or custom breaks
    // initiate customPalette to be edited in the ui
  }, {
    key: "updateCustomPalette",
    value: function updateCustomPalette(newConfig, previous, prop) {
      var _newConfig$colorRange, _newConfig$colorRange2;
      if (!((_newConfig$colorRange = newConfig.colorRangeConfig) !== null && _newConfig$colorRange !== void 0 && _newConfig$colorRange.custom) && !((_newConfig$colorRange2 = newConfig.colorRangeConfig) !== null && _newConfig$colorRange2 !== void 0 && _newConfig$colorRange2.customBreaks)) {
        return;
      }
      if (newConfig.customPalette) {
        // if new config also set customPalette, no need to initiate new
        return;
      }
      var _this$config2 = this.config,
        colorUI = _this$config2.colorUI,
        visConfig = _this$config2.visConfig;
      if (!visConfig[prop]) return;
      // make copy of current color range to customPalette
      var customPalette = _objectSpread({}, visConfig[prop]);
      if (newConfig.colorRangeConfig.customBreaks && !customPalette.colorMap) {
        // find visualChanel
        var visualChannels = this.visualChannels;
        var channelKey = Object.keys(visualChannels).find(function (key) {
          return visualChannels[key].range === prop;
        });
        if (!channelKey) {
          // should never happn
          _window.console.warn("updateColorUI: Can't find visual channel which range is ".concat(prop));
          return;
        }
        // add name|type|category to updateCustomPalette if customBreaks, so that
        // colors will not be override as well when inverse palette with custom break
        // initiate colorMap from current scale

        var colorMap = (0, _utils.initializeLayerColorMap)(this, visualChannels[channelKey]);
        customPalette = (0, _utils.initializeCustomPalette)(visConfig[prop], colorMap);
      } else if (newConfig.colorRangeConfig.custom) {
        customPalette = (0, _utils.initializeCustomPalette)(visConfig[prop]);
      }
      this.updateLayerConfig({
        colorUI: _objectSpread(_objectSpread({}, colorUI), {}, (0, _defineProperty2["default"])({}, prop, _objectSpread(_objectSpread({}, colorUI[prop]), {}, {
          customPalette: customPalette
        })))
      });
    }

    /**
     * if open dropdown and prop is color range
     * Automatically set colorRangeConfig's step and reversed
     * @param {*} newConfig
     * @param {*} prop
     */
  }, {
    key: "updateColorUIByColorRange",
    value: function updateColorUIByColorRange(newConfig, prop) {
      var _newConfig$customPale;
      var _this$config3 = this.config,
        colorUI = _this$config3.colorUI,
        visConfig = _this$config3.visConfig;

      // when custom palette adds/removes step, the number in "Steps" input control
      // should be updated as well
      var isCustom = ((_newConfig$customPale = newConfig.customPalette) === null || _newConfig$customPale === void 0 ? void 0 : _newConfig$customPale.category) === 'Custom';
      var customStepsChanged = isCustom ? newConfig.customPalette.colors.length !== visConfig[prop].colors.length : false;
      if (typeof newConfig.showDropdown !== 'number' && !customStepsChanged) return;
      this.updateLayerConfig({
        colorUI: _objectSpread(_objectSpread({}, colorUI), {}, (0, _defineProperty2["default"])({}, prop, _objectSpread(_objectSpread({}, colorUI[prop]), {}, {
          colorRangeConfig: _objectSpread(_objectSpread({}, colorUI[prop].colorRangeConfig), {}, {
            steps: customStepsChanged ? colorUI[prop].customPalette.colors.length : visConfig[prop].colors.length,
            reversed: Boolean(visConfig[prop].reversed)
          })
        })))
      });
    }
  }, {
    key: "updateColorRangeByColorUI",
    value: function updateColorRangeByColorUI(newConfig, previous, prop) {
      // only update colorRange if changes in UI is made to 'reversed', 'steps' or steps
      var shouldUpdate = newConfig.colorRangeConfig && ['reversed', 'steps', 'colorBlindSafe', 'type'].some(function (key) {
        return Object.prototype.hasOwnProperty.call(newConfig.colorRangeConfig, key) && newConfig.colorRangeConfig[key] !== (previous[prop] || _constants.DEFAULT_COLOR_UI).colorRangeConfig[key];
      });
      if (!shouldUpdate) return;
      var _this$config4 = this.config,
        colorUI = _this$config4.colorUI,
        visConfig = _this$config4.visConfig;

      // for custom palette, one can only 'reverse' the colors in custom palette.
      // changing 'steps', 'colorBindSafe', 'type' should fall back to predefined palette.
      var isCustomColorReversed = visConfig.colorRange.category === 'Custom' && newConfig.colorRangeConfig && Object.prototype.hasOwnProperty.call(newConfig.colorRangeConfig, 'reversed');
      var update = isCustomColorReversed ? (0, _utils.updateCustomColorRangeByColorUI)(visConfig[prop], colorUI[prop].colorRangeConfig) : (0, _utils.updateColorRangeByMatchingPalette)(visConfig[prop], colorUI[prop].colorRangeConfig);
      if (update) {
        this.updateLayerVisConfig((0, _defineProperty2["default"])({}, prop, update));
      }
    }
  }, {
    key: "hasColumnValue",
    value: function hasColumnValue(column) {
      return Boolean(column && column.value && column.fieldIdx > -1);
    }
  }, {
    key: "hasRequiredColumn",
    value: function hasRequiredColumn(column) {
      return Boolean(column && (column.optional || this.hasColumnValue(column)));
    }
    /**
     * Check whether layer has all columns
     * @returns yes or no
     */
  }, {
    key: "hasAllColumns",
    value: function hasAllColumns() {
      var _this4 = this;
      var _this$config5 = this.config,
        columns = _this$config5.columns,
        columnMode = _this$config5.columnMode;
      // if layer has different column mode, check if have all required columns of current column Mode
      if (columnMode) {
        var _currentColumnModes$r;
        var currentColumnModes = (this.supportedColumnModes || []).find(function (colMode) {
          return colMode.key === columnMode;
        });
        return Boolean(currentColumnModes !== undefined && ((_currentColumnModes$r = currentColumnModes.requiredColumns) === null || _currentColumnModes$r === void 0 ? void 0 : _currentColumnModes$r.every(function (colKey) {
          return _this4.hasColumnValue(columns[colKey]);
        })));
      }
      return Boolean(columns && Object.values(columns).every(function (column) {
        return _this4.hasRequiredColumn(column);
      }));
    }

    /**
     * Check whether layer has data
     *
     * @param {Array | Object} layerData
     * @returns {boolean} yes or no
     */
  }, {
    key: "hasLayerData",
    value: function hasLayerData(layerData) {
      if (!layerData) {
        return false;
      }
      return Boolean(layerData.data && (layerData.data.length || layerData.data.numRows));
    }
  }, {
    key: "isValidToSave",
    value: function isValidToSave() {
      return Boolean(this.type && this.hasAllColumns());
    }
  }, {
    key: "shouldRenderLayer",
    value: function shouldRenderLayer(data) {
      return Boolean(this.type) && this.hasAllColumns() && this.hasLayerData(data) && typeof this.renderLayer === 'function';
    }
  }, {
    key: "getColorScale",
    value: function getColorScale(colorScale, colorDomain, colorRange) {
      if (colorScale === _constants.SCALE_TYPES.customOrdinal) {
        return (0, _utils.getCategoricalColorScale)(colorDomain, colorRange);
      }
      if ((0, _utils.hasColorMap)(colorRange) && colorScale === _constants.SCALE_TYPES.custom) {
        var _colorRange$colorMap;
        var cMap = new Map();
        (_colorRange$colorMap = colorRange.colorMap) === null || _colorRange$colorMap === void 0 || _colorRange$colorMap.forEach(function (_ref7) {
          var _ref8 = (0, _slicedToArray2["default"])(_ref7, 2),
            k = _ref8[0],
            v = _ref8[1];
          cMap.set(k, typeof v === 'string' ? (0, _utils.hexToRgb)(v) : v);
        });
        var scaleType = colorScale === _constants.SCALE_TYPES.custom ? colorScale : _constants.SCALE_TYPES.ordinal;
        var scale = (0, _utils.getScaleFunction)(scaleType, cMap.values(), cMap.keys(), false);
        scale.unknown(cMap.get(_constants.UNKNOWN_COLOR_KEY) || _constants.NO_VALUE_COLOR);
        return scale;
      }
      return this.getVisChannelScale(colorScale, colorDomain, colorRange.colors.map(_utils.hexToRgb));
    }
  }, {
    key: "accessVSFieldValue",
    value: function accessVSFieldValue(_field, _indexKey) {
      return defaultGetFieldValue;
    }
    /**
     * Mapping from visual channels to deck.gl accesors
     * @param param Parameters
     * @param param.dataAccessor Access kepler.gl layer data from deck.gl layer
     * @param param.dataContainer DataContainer to use use with dataAccessor
     * @return {Object} attributeAccessors - deck.gl layer attribute accessors
     */
  }, {
    key: "getAttributeAccessors",
    value: function getAttributeAccessors(_ref9) {
      var _this5 = this;
      var _ref9$dataAccessor = _ref9.dataAccessor,
        dataAccessor = _ref9$dataAccessor === void 0 ? defaultDataAccessor : _ref9$dataAccessor,
        dataContainer = _ref9.dataContainer,
        indexKey = _ref9.indexKey;
      var attributeAccessors = {};
      Object.keys(this.visualChannels).forEach(function (channel) {
        var _this5$visualChannels = _this5.visualChannels[channel],
          field = _this5$visualChannels.field,
          fixed = _this5$visualChannels.fixed,
          scale = _this5$visualChannels.scale,
          domain = _this5$visualChannels.domain,
          range = _this5$visualChannels.range,
          accessor = _this5$visualChannels.accessor,
          defaultValue = _this5$visualChannels.defaultValue,
          getAttributeValue = _this5$visualChannels.getAttributeValue,
          nullValue = _this5$visualChannels.nullValue,
          channelScaleType = _this5$visualChannels.channelScaleType;
        if (accessor) {
          var shouldGetScale = _this5.config[field];
          if (shouldGetScale) {
            var isFixed = fixed && _this5.config.visConfig[fixed];
            var scaleFunction = channelScaleType === _constants.CHANNEL_SCALES.color ? _this5.getColorScale(_this5.config[scale], _this5.config[domain], _this5.config.visConfig[range]) : _this5.getVisChannelScale(_this5.config[scale], _this5.config[domain], _this5.config.visConfig[range], isFixed);
            var getFieldValue = _this5.accessVSFieldValue(_this5.config[field], indexKey);
            if (scaleFunction) {
              attributeAccessors[accessor] = scaleFunction.byZoom ? (0, _lodash["default"])(function (z) {
                var scaleFunc = scaleFunction(z);
                return function (d) {
                  return _this5.getEncodedChannelValue(scaleFunc, dataAccessor(dataContainer)(d), _this5.config[field], nullValue, getFieldValue);
                };
              }) : function (d) {
                return _this5.getEncodedChannelValue(scaleFunction, dataAccessor(dataContainer)(d), _this5.config[field], nullValue, getFieldValue);
              };

              // set getFillColorByZoom to true
              if (scaleFunction.byZoom) {
                attributeAccessors["".concat(accessor, "ByZoom")] = true;
              }
            }
          } else if (typeof getAttributeValue === 'function') {
            attributeAccessors[accessor] = getAttributeValue(_this5.config);
          } else {
            attributeAccessors[accessor] = typeof defaultValue === 'function' ? defaultValue(_this5.config) : defaultValue;
          }
          if (!attributeAccessors[accessor]) {
            _window.console.warn("Failed to provide accessor function for ".concat(accessor || channel));
          }
        }
      });
      return attributeAccessors;
    }
  }, {
    key: "getVisChannelScale",
    value: function getVisChannelScale(scale, domain, range, fixed) {
      // if quantile is provided per zoom
      if ((0, _utils.isDomainQuantile)(domain) && scale === _constants.SCALE_TYPES.quantile) {
        var zSteps = domain.z;
        var getScale = function getScaleByZoom(z) {
          var scaleDomain = (0, _utils.getDomainStepsbyZoom)(domain.quantiles, zSteps, z);
          var thresholds = (0, _utils.getThresholdsFromQuantiles)(scaleDomain, range.length);
          return (0, _utils.getScaleFunction)('threshold', range, thresholds, false);
        };
        getScale.byZoom = true;
        return getScale;
      } else if ((0, _utils.isDomainStops)(domain)) {
        // color is based on zoom
        var _zSteps = domain.z;
        // get scale function by z
        // {
        //  z: [z, z, z],
        //  stops: [[min, max], [min, max]],
        //  interpolation: 'interpolate'
        // }

        var _getScale = function getScaleByZoom(z) {
          var scaleDomain = (0, _utils.getDomainStepsbyZoom)(domain.stops, _zSteps, z);
          return (0, _utils.getScaleFunction)(scale, range, scaleDomain, fixed);
        };
        _getScale.byZoom = true;
        return _getScale;
      }
      return _constants.SCALE_FUNC[fixed ? 'linear' : scale]().domain(domain).range(fixed ? domain : range);
    }

    /**
     * Get longitude and latitude bounds of the data.
     */
  }, {
    key: "getPointsBounds",
    value: function getPointsBounds(dataContainer) {
      var getPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity;
      // no need to loop through the entire dataset
      // get a sample of data to calculate bounds
      var sampleData = dataContainer.numRows() > MAX_SAMPLE_SIZE ? (0, _utils.getSampleContainerData)(dataContainer, MAX_SAMPLE_SIZE) : dataContainer;
      var points = getPosition ? sampleData.mapIndex(getPosition) : [];
      var latBounds = (0, _utils.getLatLngBounds)(points, 1, [-90, 90]);
      var lngBounds = (0, _utils.getLatLngBounds)(points, 0, [-180, 180]);
      if (!latBounds || !lngBounds) {
        return null;
      }
      return [lngBounds[0], latBounds[0], lngBounds[1], latBounds[1]];
    }
  }, {
    key: "getChangedTriggers",
    value: function getChangedTriggers(dataUpdateTriggers) {
      var triggerChanged = (0, _layerUpdate.diffUpdateTriggers)(dataUpdateTriggers, this._oldDataUpdateTriggers);
      this._oldDataUpdateTriggers = dataUpdateTriggers;
      return triggerChanged;
    }
  }, {
    key: "getEncodedChannelValue",
    value: function getEncodedChannelValue(scale, data, field) {
      var nullValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _constants.NO_VALUE_COLOR;
      var getValue = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : defaultGetFieldValue;
      var value = getValue(field, data);
      if (!(0, _commonUtils.notNullorUndefined)(value)) {
        return nullValue;
      }
      var attributeValue;
      if (Array.isArray(value)) {
        attributeValue = value.map(scale);
      } else {
        attributeValue = scale(value);
      }
      if (!(0, _commonUtils.notNullorUndefined)(attributeValue)) {
        attributeValue = nullValue;
      }
      return attributeValue;
    }
  }, {
    key: "updateMeta",
    value: function updateMeta(meta) {
      this.meta = _objectSpread(_objectSpread({}, this.meta), meta);
    }
  }, {
    key: "getDataUpdateTriggers",
    value: function getDataUpdateTriggers(_ref10) {
      var filteredIndex = _ref10.filteredIndex,
        id = _ref10.id,
        dataContainer = _ref10.dataContainer;
      var columns = this.config.columns;
      return _objectSpread({
        getData: {
          datasetId: id,
          dataContainer: dataContainer,
          columns: columns,
          filteredIndex: filteredIndex
        },
        getMeta: {
          datasetId: id,
          dataContainer: dataContainer,
          columns: columns
        }
      }, (this.config.textLabel || []).reduce(function (accu, tl, i) {
        return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, "getLabelCharacterSet-".concat(i), tl.field ? tl.field.name : null));
      }, {}));
    }
  }, {
    key: "updateData",
    value: function updateData(datasets, oldLayerData) {
      if (!this.config.dataId) {
        return {};
      }
      var layerDataset = datasets[this.config.dataId];
      var dataContainer = layerDataset.dataContainer;
      var getPosition = this.getPositionAccessor(dataContainer);
      var dataUpdateTriggers = this.getDataUpdateTriggers(layerDataset);
      var triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
      if (triggerChanged && (triggerChanged.getMeta || triggerChanged.getData)) {
        this.updateLayerMeta(layerDataset, getPosition);

        // reset filteredItemCount
        this.filteredItemCount = {};
      }
      var data = [];
      if (!(triggerChanged && triggerChanged.getData) && oldLayerData && oldLayerData.data) {
        // same data
        data = oldLayerData.data;
      } else {
        data = this.calculateDataAttribute(layerDataset, getPosition);
      }
      return {
        data: data,
        triggerChanged: triggerChanged
      };
    }

    /**
     * helper function to update one layer domain when state.data changed
     * if state.data change is due ot update filter, newFiler will be passed
     * called by updateAllLayerDomainData
     * @param datasets
     * @param newFilter
     * @returns layer
     */
  }, {
    key: "updateLayerDomain",
    value: function updateLayerDomain(datasets, newFilter) {
      var _this6 = this;
      var table = this.getDataset(datasets);
      if (!table) {
        return this;
      }
      Object.values(this.visualChannels).forEach(function (channel) {
        var scale = channel.scale;
        var scaleType = _this6.config[scale];
        // ordinal domain is based on dataContainer, if only filter changed
        // no need to update ordinal domain
        if (!newFilter || scaleType !== _constants.SCALE_TYPES.ordinal) {
          var domain = channel.domain;
          var updatedDomain = _this6.calculateLayerDomain(table, channel);
          _this6.updateLayerConfig((0, _defineProperty2["default"])({}, domain, updatedDomain));
        }
      });
      return this;
    }
  }, {
    key: "getDataset",
    value: function getDataset(datasets) {
      return this.config.dataId ? datasets[this.config.dataId] : null;
    }

    /**
     * Validate visual channel field and scales based on supported field & scale type
     * @param channel
     */
  }, {
    key: "validateVisualChannel",
    value: function validateVisualChannel(channel) {
      this.validateFieldType(channel);
      this.validateScale(channel);
    }

    /**
     * Validate field type based on channelScaleType
     */
  }, {
    key: "validateFieldType",
    value: function validateFieldType(channel) {
      var visualChannel = this.visualChannels[channel];
      var field = visualChannel.field,
        channelScaleType = visualChannel.channelScaleType,
        supportedFieldTypes = visualChannel.supportedFieldTypes;
      if (this.config[field]) {
        // if field is selected, check if field type is supported
        var channelSupportedFieldTypes = supportedFieldTypes || _constants.CHANNEL_SCALE_SUPPORTED_FIELDS[channelScaleType];
        if (!channelSupportedFieldTypes.includes(this.config[field].type)) {
          // field type is not supported, set it back to null
          // set scale back to default
          this.updateLayerConfig((0, _defineProperty2["default"])({}, field, null));
        }
      }
    }

    /**
     * Validate scale type based on aggregation
     */
  }, {
    key: "validateScale",
    value: function validateScale(channel) {
      var visualChannel = this.visualChannels[channel];
      var scale = visualChannel.scale;
      if (!scale) {
        // visualChannel doesn't have scale
        return;
      }
      var scaleOptions = this.getScaleOptions(channel);
      // check if current selected scale is
      // supported, if not, change to default
      if (!scaleOptions.includes(this.config[scale])) {
        this.updateLayerConfig((0, _defineProperty2["default"])({}, scale, scaleOptions[0]));
      }
    }

    /**
     * Get scale options based on current field
     * @param {string} channel
     * @returns {string[]}
     */
  }, {
    key: "getScaleOptions",
    value: function getScaleOptions(channel) {
      var visualChannel = this.visualChannels[channel];
      var field = visualChannel.field,
        scale = visualChannel.scale,
        channelScaleType = visualChannel.channelScaleType;
      return this.config[field] ? _constants.FIELD_OPTS[this.config[field].type].scale[channelScaleType] : [this.getDefaultLayerConfig({
        dataId: ''
      })[scale]];
    }
  }, {
    key: "updateLayerVisualChannel",
    value: function updateLayerVisualChannel(dataset, channel) {
      var visualChannel = this.visualChannels[channel];
      this.validateVisualChannel(channel);
      // calculate layer channel domain
      var updatedDomain = this.calculateLayerDomain(dataset, visualChannel);
      this.updateLayerConfig((0, _defineProperty2["default"])({}, visualChannel.domain, updatedDomain));
    }
  }, {
    key: "getVisualChannelUpdateTriggers",
    value: function getVisualChannelUpdateTriggers() {
      var _this7 = this;
      var updateTriggers = {};
      Object.values(this.visualChannels).forEach(function (visualChannel) {
        // field range scale domain
        var accessor = visualChannel.accessor,
          field = visualChannel.field,
          scale = visualChannel.scale,
          domain = visualChannel.domain,
          range = visualChannel.range,
          defaultValue = visualChannel.defaultValue,
          fixed = visualChannel.fixed;
        if (accessor) {
          updateTriggers[accessor] = _objectSpread((0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])({}, field, _this7.config[field]), scale, _this7.config[scale]), domain, _this7.config[domain]), range, _this7.config.visConfig[range]), "defaultValue", typeof defaultValue === 'function' ? defaultValue(_this7.config) : defaultValue), fixed ? (0, _defineProperty2["default"])({}, fixed, _this7.config.visConfig[fixed]) : {});
        }
      });
      return updateTriggers;
    }
  }, {
    key: "calculateLayerDomain",
    value: function calculateLayerDomain(dataset, visualChannel) {
      var scale = visualChannel.scale;
      var scaleType = this.config[scale];
      var field = this.config[visualChannel.field];
      if (!field) {
        // if colorField or sizeField were set back to null
        return defaultDomain;
      }
      return dataset.getColumnLayerDomain(field, scaleType) || defaultDomain;
    }
  }, {
    key: "hasHoveredObject",
    value: function hasHoveredObject(objectInfo) {
      return this.isLayerHovered(objectInfo) && objectInfo.object ? objectInfo.object : null;
    }
  }, {
    key: "isLayerHovered",
    value: function isLayerHovered(objectInfo) {
      var _objectInfo$layer;
      return (objectInfo === null || objectInfo === void 0 ? void 0 : objectInfo.picked) && (objectInfo === null || objectInfo === void 0 || (_objectInfo$layer = objectInfo.layer) === null || _objectInfo$layer === void 0 || (_objectInfo$layer = _objectInfo$layer.props) === null || _objectInfo$layer === void 0 ? void 0 : _objectInfo$layer.id) === this.id;
    }
  }, {
    key: "getRadiusScaleByZoom",
    value: function getRadiusScaleByZoom(mapState, fixedRadius) {
      var radiusChannel = Object.values(this.visualChannels).find(function (vc) {
        return vc.property === 'radius';
      });
      if (!radiusChannel) {
        return 1;
      }
      var field = radiusChannel.field;
      var fixed = fixedRadius === undefined ? this.config.visConfig.fixedRadius : fixedRadius;
      var radius = this.config.visConfig.radius;
      return fixed ? 1 : (this.config[field] ? 1 : radius) * this.getZoomFactor(mapState);
    }
  }, {
    key: "shouldCalculateLayerData",
    value: function shouldCalculateLayerData(props) {
      var _this8 = this;
      return props.some(function (p) {
        return !_this8.noneLayerDataAffectingProps.includes(p);
      });
    }
  }, {
    key: "getBrushingExtensionProps",
    value: function getBrushingExtensionProps(interactionConfig, brushingTarget) {
      var brush = interactionConfig.brush;
      return {
        // brushing
        autoHighlight: !brush.enabled,
        brushingRadius: brush.config.size * 1000,
        brushingTarget: brushingTarget || 'source',
        brushingEnabled: brush.enabled
      };
    }
  }, {
    key: "getDefaultDeckLayerProps",
    value: function getDefaultDeckLayerProps(_ref12) {
      var idx = _ref12.idx,
        gpuFilter = _ref12.gpuFilter,
        mapState = _ref12.mapState,
        layerCallbacks = _ref12.layerCallbacks,
        visible = _ref12.visible;
      return {
        id: this.id,
        idx: idx,
        coordinateSystem: _core.COORDINATE_SYSTEM.LNGLAT,
        pickable: true,
        wrapLongitude: true,
        parameters: {
          depthTest: Boolean(mapState.dragRotate || this.config.visConfig.enable3d)
        },
        hidden: this.config.hidden,
        // visconfig
        opacity: this.config.visConfig.opacity,
        highlightColor: this.config.highlightColor,
        // data filtering
        extensions: [dataFilterExtension],
        filterRange: gpuFilter ? gpuFilter.filterRange : undefined,
        onFilteredItemsChange: gpuFilter ? layerCallbacks === null || layerCallbacks === void 0 ? void 0 : layerCallbacks.onFilteredItemsChange : undefined,
        // layer should be visible and if splitMap, shown in to one of panel
        visible: this.config.isVisible && visible
      };
    }
  }, {
    key: "getDefaultHoverLayerProps",
    value: function getDefaultHoverLayerProps() {
      return {
        id: "".concat(this.id, "-hovered"),
        pickable: false,
        wrapLongitude: true,
        coordinateSystem: _core.COORDINATE_SYSTEM.LNGLAT
      };
    }
  }, {
    key: "renderTextLabelLayer",
    value: function renderTextLabelLayer(_ref13, renderOpts) {
      var _this9 = this;
      var getPosition = _ref13.getPosition,
        getFiltered = _ref13.getFiltered,
        getPixelOffset = _ref13.getPixelOffset,
        backgroundProps = _ref13.backgroundProps,
        updateTriggers = _ref13.updateTriggers,
        sharedProps = _ref13.sharedProps;
      var data = renderOpts.data,
        mapState = renderOpts.mapState;
      var textLabel = this.config.textLabel;
      var TextLayerClass = data.data instanceof arrow.Table ? _deckglArrowLayers.GeoArrowTextLayer : _layers.TextLayer;
      return data.textLabels.reduce(function (accu, d, i) {
        if (d.getText) {
          var _textLabel$i$field, _textLabel$i$field2;
          var background = textLabel[i].background || (backgroundProps === null || backgroundProps === void 0 ? void 0 : backgroundProps.background);
          accu.push(
          // @ts-expect-error
          new TextLayerClass(_objectSpread(_objectSpread({}, sharedProps), {}, {
            id: "".concat(_this9.id, "-label-").concat((_textLabel$i$field = textLabel[i].field) === null || _textLabel$i$field === void 0 ? void 0 : _textLabel$i$field.name),
            data: data.data,
            visible: _this9.config.isVisible,
            getText: d.getText,
            getPosition: getPosition,
            getFiltered: getFiltered,
            characterSet: d.characterSet,
            getPixelOffset: getPixelOffset(textLabel[i]),
            getSize: _constants.PROJECTED_PIXEL_SIZE_MULTIPLIER,
            sizeScale: textLabel[i].size,
            getTextAnchor: textLabel[i].anchor,
            getAlignmentBaseline: textLabel[i].alignment,
            getColor: textLabel[i].color,
            outlineWidth: textLabel[i].outlineWidth * _constants.TEXT_OUTLINE_MULTIPLIER,
            outlineColor: textLabel[i].outlineColor,
            background: background,
            getBackgroundColor: textLabel[i].backgroundColor,
            fontSettings: {
              sdf: textLabel[i].outlineWidth > 0
            },
            parameters: {
              // text will always show on top of all layers
              depthTest: false
            },
            getFilterValue: data.getFilterValue,
            updateTriggers: _objectSpread(_objectSpread({}, updateTriggers), {}, {
              getText: (_textLabel$i$field2 = textLabel[i].field) === null || _textLabel$i$field2 === void 0 ? void 0 : _textLabel$i$field2.name,
              getPixelOffset: _objectSpread(_objectSpread({}, updateTriggers.getRadius), {}, {
                mapState: mapState,
                anchor: textLabel[i].anchor,
                alignment: textLabel[i].alignment
              }),
              getTextAnchor: textLabel[i].anchor,
              getAlignmentBaseline: textLabel[i].alignment,
              getColor: textLabel[i].color
            }),
            _subLayerProps: _objectSpread({}, background ? {
              background: {
                parameters: {
                  cull: false
                }
              }
            } : null)
          })));
        }
        return accu;
      }, []);
    }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  }, {
    key: "calculateDataAttribute",
    value: function calculateDataAttribute(keplerTable, getPosition) {
      // implemented in subclasses
      return [];
    }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  }, {
    key: "updateLayerMeta",
    value: function updateLayerMeta(dataset, getPosition) {
      // implemented in subclasses
    }

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  }, {
    key: "getPositionAccessor",
    value: function getPositionAccessor(dataContainer) {
      // implemented in subclasses
      return function () {
        return null;
      };
    }
  }, {
    key: "getLegendVisualChannels",
    value: function getLegendVisualChannels() {
      return this.visualChannels;
    }
  }], [{
    key: "findDefaultLayerProps",
    value: function findDefaultLayerProps(dataset, foundLayers) {
      return {
        props: [],
        foundLayers: foundLayers
      };
    }

    /**
     * Given a array of preset required column names
     * found field that has the same name to set as layer column
     *
     * @param {object} defaultFields
     * @param {object[]} allFields
     * @returns {object[] | null} all possible required layer column pairs
     */
  }, {
    key: "findDefaultColumnField",
    value: function findDefaultColumnField(defaultFields, allFields) {
      // find all matched fields for each required col
      var requiredColumns = Object.keys(defaultFields).reduce(function (prev, key) {
        var requiredFields = allFields.filter(function (f) {
          return f.name === defaultFields[key] || defaultFields[key].includes(f.name);
        });
        prev[key] = requiredFields.length ? requiredFields.map(function (f) {
          return {
            value: f.name,
            fieldIdx: f.fieldIdx
          };
        }) : null;
        return prev;
      }, {});
      if (!Object.values(requiredColumns).every(Boolean)) {
        // if any field missing, return null
        return null;
      }
      return this.getAllPossibleColumnPairs(requiredColumns);
    }
  }, {
    key: "getAllPossibleColumnPairs",
    value: function getAllPossibleColumnPairs(requiredColumns) {
      // for multiple matched field for one required column, return multiple
      // combinations, e. g. if column a has 2 matched, column b has 3 matched
      // 6 possible column pairs will be returned
      var allKeys = Object.keys(requiredColumns);
      var pointers = allKeys.map(function (k, i) {
        return i === allKeys.length - 1 ? -1 : 0;
      });
      var countPerKey = allKeys.map(function (k) {
        return requiredColumns[k].length;
      });
      // TODO: Better typings
      var pairs = [];

      /* eslint-disable no-loop-func */
      while (incrementPointers(pointers, countPerKey, pointers.length - 1)) {
        var newPair = pointers.reduce(function (prev, cuur, i) {
          prev[allKeys[i]] = requiredColumns[allKeys[i]][cuur];
          return prev;
        }, {});
        pairs.push(newPair);
      }
      /* eslint-enable no-loop-func */

      // recursively increment pointers
      function incrementPointers(pts, counts, index) {
        if (index === 0 && pts[0] === counts[0] - 1) {
          // nothing to increment
          return false;
        }
        if (pts[index] + 1 < counts[index]) {
          pts[index] = pts[index] + 1;
          return true;
        }
        pts[index] = 0;
        return incrementPointers(pts, counts, index - 1);
      }
      return pairs;
    }
  }, {
    key: "hexToRgb",
    value: function hexToRgb(c) {
      return (0, _utils.hexToRgb)(c);
    }
  }]);
}();
var _default = exports["default"] = Layer;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29yZSIsInJlcXVpcmUiLCJfZGVja2dsQXJyb3dMYXllcnMiLCJfZXh0ZW5zaW9ucyIsIl9sYXllcnMiLCJfd2luZG93IiwiX2tleW1pcnJvciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJhcnJvdyIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX2RlZmF1bHRMYXllckljb24iLCJfbGF5ZXJVcGRhdGUiLCJfbGF5ZXJVdGlscyIsIl9jb25zdGFudHMiLCJfdXRpbHMiLCJfY29tbW9uVXRpbHMiLCJfbG9kYXNoIiwiX2dldEFwcGxpY2F0aW9uQ29uZmlnIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJfdHlwZW9mMyIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJBcnJheSIsImlzQXJyYXkiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJsZW5ndGgiLCJfbiIsIkYiLCJzIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsIl9tYXJrZWQiLCJfcmVnZW5lcmF0b3JSdW50aW1lMiIsIm1hcmsiLCJnZW5lcmF0ZUNvbG9yIiwiTEFZRVJfSURfTEVOR1RIIiwiZXhwb3J0cyIsIk1BWF9TQU1QTEVfU0laRSIsImRlZmF1bHREb21haW4iLCJkYXRhRmlsdGVyRXh0ZW5zaW9uIiwiRGF0YUZpbHRlckV4dGVuc2lvbiIsImZpbHRlclNpemUiLCJNQVhfR1BVX0ZJTFRFUlMiLCJjb3VudEl0ZW1zIiwiZ2V0QXBwbGljYXRpb25Db25maWciLCJ1c2VPbkZpbHRlcmVkSXRlbXNDaGFuZ2UiLCJkZWZhdWx0RGF0YUFjY2Vzc29yIiwiZGMiLCJkIiwiaWRlbnRpdHkiLCJkZWZhdWx0R2V0RmllbGRWYWx1ZSIsImZpZWxkIiwidmFsdWVBY2Nlc3NvciIsIk9WRVJMQVlfVFlQRV9DT05TVCIsImtleW1pcnJvciIsImRlY2tnbCIsIm1hcGJveGdsIiwibGF5ZXJDb2xvcnMiLCJ2YWx1ZXMiLCJEYXRhVml6Q29sb3JzIiwibWFwIiwiaGV4VG9SZ2IiLCJpbmRleCIsIl9yZWdlbmVyYXRvciIsIndyYXAiLCJnZW5lcmF0ZUNvbG9yJCIsIl9jb250ZXh0IiwicHJldiIsInN0b3AiLCJjb2xvck1ha2VyIiwiTGF5ZXIiLCJwcm9wcyIsIl9jbGFzc0NhbGxDaGVjazIiLCJpZCIsImdlbmVyYXRlSGFzaElkIiwibWV0YSIsInZpc0NvbmZpZ1NldHRpbmdzIiwiY29uZmlnIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiY29sdW1uTW9kZSIsInN1cHBvcnRlZENvbHVtbk1vZGVzIiwiX3N1cHBvcnRlZENvbHVtbk1vZGVzIiwia2V5IiwiY29sdW1ucyIsImdldExheWVyQ29sdW1ucyIsImlzVmFsaWQiLCJlcnJvck1lc3NhZ2UiLCJmaWx0ZXJlZEl0ZW1Db3VudCIsIl9jcmVhdGVDbGFzczIiLCJEZWZhdWx0TGF5ZXJJY29uIiwidHlwZSIsInJlZHVjZSIsImFjYyIsIm9iaiIsInJlcXVpcmVkQ29sdW1ucyIsImNvbmNhdCIsIm9wdGlvbmFsQ29sdW1ucyIsImNvbG9yIiwicHJvcGVydHkiLCJzY2FsZSIsImRvbWFpbiIsInJhbmdlIiwiY2hhbm5lbFNjYWxlVHlwZSIsIkNIQU5ORUxfU0NBTEVTIiwibnVsbFZhbHVlIiwiTk9fVkFMVUVfQ09MT1IiLCJkZWZhdWx0VmFsdWUiLCJzaXplIiwibGF0IiwicGFpciIsImZpZWxkUGFpcktleSIsImxuZyIsImFsdGl0dWRlIiwiYWx0IiwibGF0MCIsImxuZzAiLCJhbHQwIiwibGF0MSIsImxuZzEiLCJhbHQxIiwiX3Byb3BzJGlzVmlzaWJsZSIsIl9wcm9wcyRpc0NvbmZpZ0FjdGl2ZSIsIl9wcm9wcyRoaWRkZW4iLCJkYXRhSWQiLCJsYWJlbCIsIkRFRkFVTFRfTEFZRVJfTEFCRUwiLCJpc1Zpc2libGUiLCJpc0NvbmZpZ0FjdGl2ZSIsImhpZ2hsaWdodENvbG9yIiwiREVGQVVMVF9ISUdITElHSFRfQ09MT1IiLCJoaWRkZW4iLCJjb2xvckZpZWxkIiwiY29sb3JEb21haW4iLCJjb2xvclNjYWxlIiwiU0NBTEVfVFlQRVMiLCJxdWFudGlsZSIsInNpemVEb21haW4iLCJzaXplU2NhbGUiLCJsaW5lYXIiLCJzaXplRmllbGQiLCJ2aXNDb25maWciLCJ0ZXh0TGFiZWwiLCJERUZBVUxUX1RFWFRfTEFCRUwiLCJjb2xvclVJIiwiREVGQVVMVF9DT0xPUl9VSSIsImNvbG9yUmFuZ2UiLCJhbmltYXRpb24iLCJlbmFibGVkIiwiZ2V0VmlzdWFsQ2hhbm5lbERlc2NyaXB0aW9uIiwiY2hhbm5lbCIsInZpc3VhbENoYW5uZWxzIiwibWVhc3VyZSIsInVuZGVmaW5lZCIsInJhbmdlU2V0dGluZ3MiLCJmaWVsZFNldHRpbmdzIiwiZGlzcGxheU5hbWUiLCJkZWZhdWx0TWVhc3VyZSIsImFzc2lnbkNvbHVtbiIsIl90aGlzJGNvbmZpZyRjb2x1bW5zIiwidXBkYXRlIiwiZmllbGRJZHgiLCJhc3NpZ25Db2x1bW5QYWlycyIsImZpZWxkUGFpcnMiLCJfdGhpcyRjb2x1bW5QYWlycyIsIl90aGlzJGNvbHVtblBhaXJzMiIsImNvbHVtblBhaXJzIiwiX3JlZiIsInVwZGF0ZWRDb2x1bW4iLCJwYXJ0bmVyS2V5cyIsInRvQXJyYXkiLCJfaXRlcmF0b3IiLCJfc3RlcCIsIl90aGlzJGNvbHVtblBhaXJzMyIsIl90aGlzJGNvbHVtblBhaXJzNCIsInBhcnRuZXJLZXkiLCJfdGhpcyRjb2x1bW5QYWlyczUiLCJlcnIiLCJnZXRab29tRmFjdG9yIiwiX3JlZjIiLCJ6b29tIiwiX3JlZjIkem9vbU9mZnNldCIsInpvb21PZmZzZXQiLCJNYXRoIiwicG93IiwibWF4IiwiZ2V0RWxldmF0aW9uWm9vbUZhY3RvciIsIl9yZWYzIiwiX3JlZjMkem9vbU9mZnNldCIsIl90aGlzJGNvbmZpZyR2aXNDb25maSIsImZpeGVkSGVpZ2h0IiwiZW5hYmxlRWxldmF0aW9uWm9vbUZhY3RvciIsImZvcm1hdExheWVyRGF0YSIsImRhdGFzZXRzIiwib2xkTGF5ZXJEYXRhIiwiYW5pbWF0aW9uQ29uZmlnIiwicmVuZGVyTGF5ZXIiLCJnZXRIb3ZlckRhdGEiLCJvYmplY3QiLCJkYXRhQ29udGFpbmVyIiwiZmllbGRzIiwiaG92ZXJJbmZvIiwicm93IiwiZ2V0RmlsdGVyZWRJdGVtQ291bnQiLCJmaXJzdExheWVyIiwiYXNzaWduQ29uZmlnVG9MYXllciIsImNvbmZpZ1RvQ29weSIsImRlZmF1bHRMYXllclByb3BzIiwiX3RoaXMiLCJzaGFsbG93Q29weSIsInYiLCJub3RUb0NvcHkiLCJncm91cCIsImN1cnJlbnRDb25maWciLCJjb3BpZWQiLCJjb3B5TGF5ZXJDb25maWciLCJfc2F0aXNmaWVkQ29sdW1uTW9kZSIsImRhdGFzZXQiLCJzYXRpc2ZpZWRDb2x1bW5Nb2RlIiwiZ2V0U2F0aXNmaWVkQ29sdW1uTW9kZSIsIm9wdGlvbnMiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwiYWx0UHJvcHMiLCJkZWZhdWx0Q29sdW1uQ29uZmlnIiwidXBkYXRlTGF5ZXJDb25maWciLCJ2YWxpZGF0ZVZpc3VhbENoYW5uZWwiLCJfdGhpczIiLCJfcmVmNCIsIl9yZWY0JHNoYWxsb3dDb3B5IiwiX3JlZjQkbm90VG9Db3B5IiwiaXNQbGFpbk9iamVjdCIsImluY2x1ZGVzIiwibm90TnVsbG9yVW5kZWZpbmVkIiwicmVnaXN0ZXJWaXNDb25maWciLCJsYXllclZpc0NvbmZpZ3MiLCJfdGhpczMiLCJpdGVtIiwiY29uZmlnSXRlbSIsIkxBWUVSX1ZJU19DT05GSUdTIiwiX3R5cGVvZjIiLCJldmVyeSIsInAiLCJwcm90b3R5cGUiLCJwcm9wc0NvbHVtbnMiLCJjb2x1bW5WYWxpZGF0b3JzIiwicmVxdWlyZWQiLCJyZXF1aXJlZExheWVyQ29sdW1ucyIsImFjY3UiLCJfcHJvcHNDb2x1bW5zJGtleSR2YWwiLCJfcHJvcHNDb2x1bW5zJGtleSIsIl9wcm9wc0NvbHVtbnMka2V5JGZpZSIsIl9wcm9wc0NvbHVtbnMka2V5MiIsIl9wcm9wc0NvbHVtbnMka2V5JHZhbDIiLCJfcHJvcHNDb2x1bW5zJGtleTMiLCJfcHJvcHNDb2x1bW5zJGtleSRmaWUyIiwiX3Byb3BzQ29sdW1ucyRrZXk0IiwidmFsaWRhdG9yIiwib3B0aW9uYWwiLCJfcHJvcHNDb2x1bW5zJGtleSR2YWwzIiwiX3Byb3BzQ29sdW1ucyRrZXk1IiwiX3Byb3BzQ29sdW1ucyRrZXkkZmllMyIsIl9wcm9wc0NvbHVtbnMka2V5NiIsIm5ld0NvbmZpZyIsInVwZGF0ZUxheWVyVmlzQ29uZmlnIiwibmV3VmlzQ29uZmlnIiwidXBkYXRlTGF5ZXJDb2xvclVJIiwicHJvcCIsIl90aGlzJGNvbmZpZyIsInByZXZpb3VzIiwiY29sb3JVSVByb3AiLCJlbnRyaWVzIiwiX3JlZjUiLCJfcmVmNiIsIl9zbGljZWRUb0FycmF5MiIsImlzQ29sb3JSYW5nZSIsImNvbG9ycyIsInVwZGF0ZUNvbG9yVUlCeUNvbG9yUmFuZ2UiLCJ1cGRhdGVDb2xvclJhbmdlQnlDb2xvclVJIiwidXBkYXRlQ3VzdG9tUGFsZXR0ZSIsIl9uZXdDb25maWckY29sb3JSYW5nZSIsIl9uZXdDb25maWckY29sb3JSYW5nZTIiLCJjb2xvclJhbmdlQ29uZmlnIiwiY3VzdG9tIiwiY3VzdG9tQnJlYWtzIiwiY3VzdG9tUGFsZXR0ZSIsIl90aGlzJGNvbmZpZzIiLCJjb2xvck1hcCIsImNoYW5uZWxLZXkiLCJmaW5kIiwiQ29uc29sZSIsIndhcm4iLCJpbml0aWFsaXplTGF5ZXJDb2xvck1hcCIsImluaXRpYWxpemVDdXN0b21QYWxldHRlIiwiX25ld0NvbmZpZyRjdXN0b21QYWxlIiwiX3RoaXMkY29uZmlnMyIsImlzQ3VzdG9tIiwiY2F0ZWdvcnkiLCJjdXN0b21TdGVwc0NoYW5nZWQiLCJzaG93RHJvcGRvd24iLCJzdGVwcyIsInJldmVyc2VkIiwiQm9vbGVhbiIsInNob3VsZFVwZGF0ZSIsInNvbWUiLCJfdGhpcyRjb25maWc0IiwiaXNDdXN0b21Db2xvclJldmVyc2VkIiwidXBkYXRlQ3VzdG9tQ29sb3JSYW5nZUJ5Q29sb3JVSSIsInVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZSIsImhhc0NvbHVtblZhbHVlIiwiY29sdW1uIiwiaGFzUmVxdWlyZWRDb2x1bW4iLCJoYXNBbGxDb2x1bW5zIiwiX3RoaXM0IiwiX3RoaXMkY29uZmlnNSIsIl9jdXJyZW50Q29sdW1uTW9kZXMkciIsImN1cnJlbnRDb2x1bW5Nb2RlcyIsImNvbE1vZGUiLCJjb2xLZXkiLCJoYXNMYXllckRhdGEiLCJsYXllckRhdGEiLCJkYXRhIiwibnVtUm93cyIsImlzVmFsaWRUb1NhdmUiLCJzaG91bGRSZW5kZXJMYXllciIsImdldENvbG9yU2NhbGUiLCJjdXN0b21PcmRpbmFsIiwiZ2V0Q2F0ZWdvcmljYWxDb2xvclNjYWxlIiwiaGFzQ29sb3JNYXAiLCJfY29sb3JSYW5nZSRjb2xvck1hcCIsImNNYXAiLCJNYXAiLCJfcmVmNyIsIl9yZWY4IiwiayIsInNjYWxlVHlwZSIsIm9yZGluYWwiLCJnZXRTY2FsZUZ1bmN0aW9uIiwidW5rbm93biIsIlVOS05PV05fQ09MT1JfS0VZIiwiZ2V0VmlzQ2hhbm5lbFNjYWxlIiwiYWNjZXNzVlNGaWVsZFZhbHVlIiwiX2ZpZWxkIiwiX2luZGV4S2V5IiwiZ2V0QXR0cmlidXRlQWNjZXNzb3JzIiwiX3JlZjkiLCJfdGhpczUiLCJfcmVmOSRkYXRhQWNjZXNzb3IiLCJkYXRhQWNjZXNzb3IiLCJpbmRleEtleSIsImF0dHJpYnV0ZUFjY2Vzc29ycyIsIl90aGlzNSR2aXN1YWxDaGFubmVscyIsImZpeGVkIiwiYWNjZXNzb3IiLCJnZXRBdHRyaWJ1dGVWYWx1ZSIsInNob3VsZEdldFNjYWxlIiwiaXNGaXhlZCIsInNjYWxlRnVuY3Rpb24iLCJnZXRGaWVsZFZhbHVlIiwiYnlab29tIiwibWVtb2l6ZSIsInoiLCJzY2FsZUZ1bmMiLCJnZXRFbmNvZGVkQ2hhbm5lbFZhbHVlIiwiaXNEb21haW5RdWFudGlsZSIsInpTdGVwcyIsImdldFNjYWxlIiwiZ2V0U2NhbGVCeVpvb20iLCJzY2FsZURvbWFpbiIsImdldERvbWFpblN0ZXBzYnlab29tIiwicXVhbnRpbGVzIiwidGhyZXNob2xkcyIsImdldFRocmVzaG9sZHNGcm9tUXVhbnRpbGVzIiwiaXNEb21haW5TdG9wcyIsInN0b3BzIiwiU0NBTEVfRlVOQyIsImdldFBvaW50c0JvdW5kcyIsImdldFBvc2l0aW9uIiwic2FtcGxlRGF0YSIsImdldFNhbXBsZUNvbnRhaW5lckRhdGEiLCJwb2ludHMiLCJtYXBJbmRleCIsImxhdEJvdW5kcyIsImdldExhdExuZ0JvdW5kcyIsImxuZ0JvdW5kcyIsImdldENoYW5nZWRUcmlnZ2VycyIsImRhdGFVcGRhdGVUcmlnZ2VycyIsInRyaWdnZXJDaGFuZ2VkIiwiZGlmZlVwZGF0ZVRyaWdnZXJzIiwiX29sZERhdGFVcGRhdGVUcmlnZ2VycyIsImdldFZhbHVlIiwiYXR0cmlidXRlVmFsdWUiLCJ1cGRhdGVNZXRhIiwiZ2V0RGF0YVVwZGF0ZVRyaWdnZXJzIiwiX3JlZjEwIiwiZmlsdGVyZWRJbmRleCIsImdldERhdGEiLCJkYXRhc2V0SWQiLCJnZXRNZXRhIiwidGwiLCJ1cGRhdGVEYXRhIiwibGF5ZXJEYXRhc2V0IiwiZ2V0UG9zaXRpb25BY2Nlc3NvciIsInVwZGF0ZUxheWVyTWV0YSIsImNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUiLCJ1cGRhdGVMYXllckRvbWFpbiIsIm5ld0ZpbHRlciIsIl90aGlzNiIsInRhYmxlIiwiZ2V0RGF0YXNldCIsInVwZGF0ZWREb21haW4iLCJjYWxjdWxhdGVMYXllckRvbWFpbiIsInZhbGlkYXRlRmllbGRUeXBlIiwidmFsaWRhdGVTY2FsZSIsInZpc3VhbENoYW5uZWwiLCJzdXBwb3J0ZWRGaWVsZFR5cGVzIiwiY2hhbm5lbFN1cHBvcnRlZEZpZWxkVHlwZXMiLCJDSEFOTkVMX1NDQUxFX1NVUFBPUlRFRF9GSUVMRFMiLCJzY2FsZU9wdGlvbnMiLCJnZXRTY2FsZU9wdGlvbnMiLCJGSUVMRF9PUFRTIiwidXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsIiwiZ2V0VmlzdWFsQ2hhbm5lbFVwZGF0ZVRyaWdnZXJzIiwiX3RoaXM3IiwidXBkYXRlVHJpZ2dlcnMiLCJnZXRDb2x1bW5MYXllckRvbWFpbiIsImhhc0hvdmVyZWRPYmplY3QiLCJvYmplY3RJbmZvIiwiaXNMYXllckhvdmVyZWQiLCJfb2JqZWN0SW5mbyRsYXllciIsInBpY2tlZCIsImxheWVyIiwiZ2V0UmFkaXVzU2NhbGVCeVpvb20iLCJtYXBTdGF0ZSIsImZpeGVkUmFkaXVzIiwicmFkaXVzQ2hhbm5lbCIsInZjIiwicmFkaXVzIiwic2hvdWxkQ2FsY3VsYXRlTGF5ZXJEYXRhIiwiX3RoaXM4Iiwibm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzIiwiZ2V0QnJ1c2hpbmdFeHRlbnNpb25Qcm9wcyIsImludGVyYWN0aW9uQ29uZmlnIiwiYnJ1c2hpbmdUYXJnZXQiLCJicnVzaCIsImF1dG9IaWdobGlnaHQiLCJicnVzaGluZ1JhZGl1cyIsImJydXNoaW5nRW5hYmxlZCIsImdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyIsIl9yZWYxMiIsImlkeCIsImdwdUZpbHRlciIsImxheWVyQ2FsbGJhY2tzIiwidmlzaWJsZSIsImNvb3JkaW5hdGVTeXN0ZW0iLCJDT09SRElOQVRFX1NZU1RFTSIsIkxOR0xBVCIsInBpY2thYmxlIiwid3JhcExvbmdpdHVkZSIsInBhcmFtZXRlcnMiLCJkZXB0aFRlc3QiLCJkcmFnUm90YXRlIiwiZW5hYmxlM2QiLCJvcGFjaXR5IiwiZXh0ZW5zaW9ucyIsImZpbHRlclJhbmdlIiwib25GaWx0ZXJlZEl0ZW1zQ2hhbmdlIiwiZ2V0RGVmYXVsdEhvdmVyTGF5ZXJQcm9wcyIsInJlbmRlclRleHRMYWJlbExheWVyIiwiX3JlZjEzIiwicmVuZGVyT3B0cyIsIl90aGlzOSIsImdldEZpbHRlcmVkIiwiZ2V0UGl4ZWxPZmZzZXQiLCJiYWNrZ3JvdW5kUHJvcHMiLCJzaGFyZWRQcm9wcyIsIlRleHRMYXllckNsYXNzIiwiVGFibGUiLCJHZW9BcnJvd1RleHRMYXllciIsIlRleHRMYXllciIsInRleHRMYWJlbHMiLCJnZXRUZXh0IiwiX3RleHRMYWJlbCRpJGZpZWxkIiwiX3RleHRMYWJlbCRpJGZpZWxkMiIsImJhY2tncm91bmQiLCJjaGFyYWN0ZXJTZXQiLCJnZXRTaXplIiwiUFJPSkVDVEVEX1BJWEVMX1NJWkVfTVVMVElQTElFUiIsImdldFRleHRBbmNob3IiLCJhbmNob3IiLCJnZXRBbGlnbm1lbnRCYXNlbGluZSIsImFsaWdubWVudCIsImdldENvbG9yIiwib3V0bGluZVdpZHRoIiwiVEVYVF9PVVRMSU5FX01VTFRJUExJRVIiLCJvdXRsaW5lQ29sb3IiLCJnZXRCYWNrZ3JvdW5kQ29sb3IiLCJiYWNrZ3JvdW5kQ29sb3IiLCJmb250U2V0dGluZ3MiLCJzZGYiLCJnZXRGaWx0ZXJWYWx1ZSIsImdldFJhZGl1cyIsIl9zdWJMYXllclByb3BzIiwiY3VsbCIsImtlcGxlclRhYmxlIiwiZ2V0TGVnZW5kVmlzdWFsQ2hhbm5lbHMiLCJmaW5kRGVmYXVsdExheWVyUHJvcHMiLCJmb3VuZExheWVycyIsImZpbmREZWZhdWx0Q29sdW1uRmllbGQiLCJkZWZhdWx0RmllbGRzIiwiYWxsRmllbGRzIiwicmVxdWlyZWRGaWVsZHMiLCJnZXRBbGxQb3NzaWJsZUNvbHVtblBhaXJzIiwiYWxsS2V5cyIsInBvaW50ZXJzIiwiY291bnRQZXJLZXkiLCJwYWlycyIsImluY3JlbWVudFBvaW50ZXJzIiwibmV3UGFpciIsImN1dXIiLCJwdHMiLCJjb3VudHMiLCJjIiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi9zcmMvYmFzZS1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0NPT1JESU5BVEVfU1lTVEVNfSBmcm9tICdAZGVjay5nbC9jb3JlJztcbmltcG9ydCB7R2VvQXJyb3dUZXh0TGF5ZXJ9IGZyb20gJ0BrZXBsZXIuZ2wvZGVja2dsLWFycm93LWxheWVycyc7XG5pbXBvcnQge0RhdGFGaWx0ZXJFeHRlbnNpb259IGZyb20gJ0BkZWNrLmdsL2V4dGVuc2lvbnMnO1xuaW1wb3J0IHtUZXh0TGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycyc7XG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQga2V5bWlycm9yIGZyb20gJ2tleW1pcnJvcic7XG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0ICogYXMgYXJyb3cgZnJvbSAnYXBhY2hlLWFycm93JztcbmltcG9ydCBEZWZhdWx0TGF5ZXJJY29uIGZyb20gJy4vZGVmYXVsdC1sYXllci1pY29uJztcbmltcG9ydCB7ZGlmZlVwZGF0ZVRyaWdnZXJzfSBmcm9tICcuL2xheWVyLXVwZGF0ZSc7XG5pbXBvcnQge2dldFNhdGlzZmllZENvbHVtbk1vZGUsIEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlfSBmcm9tICcuL2xheWVyLXV0aWxzJztcblxuaW1wb3J0IHtcbiAgQ0hBTk5FTF9TQ0FMRVMsXG4gIENIQU5ORUxfU0NBTEVfU1VQUE9SVEVEX0ZJRUxEUyxcbiAgREVGQVVMVF9DT0xPUl9VSSxcbiAgREVGQVVMVF9ISUdITElHSFRfQ09MT1IsXG4gIERFRkFVTFRfTEFZRVJfTEFCRUwsXG4gIERFRkFVTFRfVEVYVF9MQUJFTCxcbiAgRGF0YVZpekNvbG9ycyxcbiAgRklFTERfT1BUUyxcbiAgTEFZRVJfVklTX0NPTkZJR1MsXG4gIE1BWF9HUFVfRklMVEVSUyxcbiAgTk9fVkFMVUVfQ09MT1IsXG4gIFBST0pFQ1RFRF9QSVhFTF9TSVpFX01VTFRJUExJRVIsXG4gIFNDQUxFX0ZVTkMsXG4gIFNDQUxFX1RZUEVTLFxuICBURVhUX09VVExJTkVfTVVMVElQTElFUixcbiAgVU5LTk9XTl9DT0xPUl9LRVlcbn0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgRGF0YUNvbnRhaW5lckludGVyZmFjZSxcbiAgRG9tYWluUXVhbnRpbGVzLFxuICBnZXRBcHBsaWNhdGlvbkNvbmZpZyxcbiAgZ2V0TGF0TG5nQm91bmRzLFxuICBnZXRTYW1wbGVDb250YWluZXJEYXRhLFxuICBoYXNDb2xvck1hcCxcbiAgaGV4VG9SZ2IsXG4gIGlzUGxhaW5PYmplY3QsXG4gIGlzRG9tYWluU3RvcHMsXG4gIHVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZVxufSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWQsIHRvQXJyYXksIG5vdE51bGxvclVuZGVmaW5lZH0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuaW1wb3J0IHtEYXRhc2V0cywgR3B1RmlsdGVyLCBLZXBsZXJUYWJsZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge1xuICBBZ2dyZWdhdGVkQmluLFxuICBDb2xvclJhbmdlLFxuICBDb2xvclVJLFxuICBGaWVsZCxcbiAgRmlsdGVyLFxuICBHZXRWaXNDaGFubmVsU2NhbGVSZXR1cm5UeXBlLFxuICBMYXllclZpc0NvbmZpZ1NldHRpbmdzLFxuICBNYXBTdGF0ZSxcbiAgQW5pbWF0aW9uQ29uZmlnLFxuICBLZXBsZXJMYXllcixcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICBMYXllckNvbHVtbnMsXG4gIExheWVyQ29sdW1uLFxuICBDb2x1bW5QYWlycyxcbiAgQ29sdW1uTGFiZWxzLFxuICBTdXBwb3J0ZWRDb2x1bW5Nb2RlLFxuICBGaWVsZFBhaXIsXG4gIE5lc3RlZFBhcnRpYWwsXG4gIFJHQkNvbG9yLFxuICBWYWx1ZU9mLFxuICBWaXN1YWxDaGFubmVsLFxuICBWaXN1YWxDaGFubmVscyxcbiAgVmlzdWFsQ2hhbm5lbERvbWFpbixcbiAgVmlzdWFsQ2hhbm5lbEZpZWxkLFxuICBWaXN1YWxDaGFubmVsU2NhbGVcbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRTY2FsZUZ1bmN0aW9uLFxuICBpbml0aWFsaXplTGF5ZXJDb2xvck1hcCxcbiAgZ2V0Q2F0ZWdvcmljYWxDb2xvclNjYWxlLFxuICB1cGRhdGVDdXN0b21Db2xvclJhbmdlQnlDb2xvclVJXG59IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuaW1wb3J0IG1lbW9pemUgZnJvbSAnbG9kYXNoLm1lbW9pemUnO1xuaW1wb3J0IHtcbiAgaW5pdGlhbGl6ZUN1c3RvbVBhbGV0dGUsXG4gIGlzRG9tYWluUXVhbnRpbGUsXG4gIGdldERvbWFpblN0ZXBzYnlab29tLFxuICBnZXRUaHJlc2hvbGRzRnJvbVF1YW50aWxlc1xufSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuZXhwb3J0IHR5cGUge1xuICBBZ2dyZWdhdGVkQmluLFxuICBMYXllckJhc2VDb25maWcsXG4gIFZpc3VhbENoYW5uZWwsXG4gIFZpc3VhbENoYW5uZWxzLFxuICBWaXN1YWxDaGFubmVsRG9tYWluLFxuICBWaXN1YWxDaGFubmVsRmllbGQsXG4gIFZpc3VhbENoYW5uZWxTY2FsZVxufTtcblxuZXhwb3J0IHR5cGUgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbCA9IHtkYXRhSWQ6IExheWVyQmFzZUNvbmZpZ1snZGF0YUlkJ119ICYgUGFydGlhbDxMYXllckJhc2VDb25maWc+O1xuXG5leHBvcnQgdHlwZSBMYXllckNvbG9yQ29uZmlnID0ge1xuICBjb2xvckZpZWxkOiBWaXN1YWxDaGFubmVsRmllbGQ7XG4gIGNvbG9yRG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluO1xuICBjb2xvclNjYWxlOiBWaXN1YWxDaGFubmVsU2NhbGU7XG59O1xuZXhwb3J0IHR5cGUgTGF5ZXJTaXplQ29uZmlnID0ge1xuICAvLyBjb2xvciBieSBzaXplLCBkb21haW4gaXMgc2V0IGJ5IGZpbHRlcnMsIGZpZWxkLCBzY2FsZSB0eXBlXG4gIHNpemVEb21haW46IFZpc3VhbENoYW5uZWxEb21haW47XG4gIHNpemVTY2FsZTogVmlzdWFsQ2hhbm5lbFNjYWxlO1xuICBzaXplRmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbn07XG5leHBvcnQgdHlwZSBMYXllckhlaWdodENvbmZpZyA9IHtcbiAgaGVpZ2h0RmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbiAgaGVpZ2h0RG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluO1xuICBoZWlnaHRTY2FsZTogVmlzdWFsQ2hhbm5lbFNjYWxlO1xufTtcbmV4cG9ydCB0eXBlIExheWVyU3Ryb2tlQ29sb3JDb25maWcgPSB7XG4gIHN0cm9rZUNvbG9yRmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbiAgc3Ryb2tlQ29sb3JEb21haW46IFZpc3VhbENoYW5uZWxEb21haW47XG4gIHN0cm9rZUNvbG9yU2NhbGU6IFZpc3VhbENoYW5uZWxTY2FsZTtcbn07XG5leHBvcnQgdHlwZSBMYXllckNvdmVyYWdlQ29uZmlnID0ge1xuICBjb3ZlcmFnZUZpZWxkOiBWaXN1YWxDaGFubmVsRmllbGQ7XG4gIGNvdmVyYWdlRG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluO1xuICBjb3ZlcmFnZVNjYWxlOiBWaXN1YWxDaGFubmVsU2NhbGU7XG59O1xuZXhwb3J0IHR5cGUgTGF5ZXJSYWRpdXNDb25maWcgPSB7XG4gIHJhZGl1c0ZpZWxkOiBWaXN1YWxDaGFubmVsRmllbGQ7XG4gIHJhZGl1c0RvbWFpbjogVmlzdWFsQ2hhbm5lbERvbWFpbjtcbiAgcmFkaXVzU2NhbGU6IFZpc3VhbENoYW5uZWxTY2FsZTtcbn07XG5leHBvcnQgdHlwZSBMYXllcldlaWdodENvbmZpZyA9IHtcbiAgd2VpZ2h0RmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbn07XG5cbmV4cG9ydCB0eXBlIFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbiA9IHtcbiAgbGFiZWw6IHN0cmluZztcbiAgbWVhc3VyZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufTtcblxudHlwZSBDb2x1bW5WYWxpZGF0b3IgPSAoY29sdW1uOiBMYXllckNvbHVtbiwgY29sdW1uczogTGF5ZXJDb2x1bW5zLCBhbGxGaWVsZHM6IEZpZWxkW10pID0+IGJvb2xlYW47XG5cbmV4cG9ydCB0eXBlIFVwZGF0ZVRyaWdnZXJzID0ge1xuICBba2V5OiBzdHJpbmddOiBVcGRhdGVUcmlnZ2VyO1xufTtcbmV4cG9ydCB0eXBlIFVwZGF0ZVRyaWdnZXIgPSB7XG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn07XG5leHBvcnQgdHlwZSBMYXllckJvdW5kcyA9IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4vKipcbiAqIEFwcHJveC4gbnVtYmVyIG9mIHBvaW50cyB0byBzYW1wbGUgaW4gYSBsYXJnZSBkYXRhIHNldFxuICovXG5leHBvcnQgY29uc3QgTEFZRVJfSURfTEVOR1RIID0gNjtcblxuY29uc3QgTUFYX1NBTVBMRV9TSVpFID0gNTAwMDtcbmNvbnN0IGRlZmF1bHREb21haW46IFtudW1iZXIsIG51bWJlcl0gPSBbMCwgMV07XG5jb25zdCBkYXRhRmlsdGVyRXh0ZW5zaW9uID0gbmV3IERhdGFGaWx0ZXJFeHRlbnNpb24oe1xuICBmaWx0ZXJTaXplOiBNQVhfR1BVX0ZJTFRFUlMsXG4gIC8vIGBjb3VudEl0ZW1zYCBvcHRpb24uIEl0IGVuYWJsZXMgdGhlIEdQVSB0byByZXBvcnQgdGhlIG51bWJlciBvZiBvYmplY3RzIHRoYXQgcGFzcyB0aGUgZmlsdGVyIGNyaXRlcmlhIHZpYSB0aGUgYG9uRmlsdGVyZWRJdGVtc0NoYW5nZWAgY2FsbGJhY2suXG4gIC8vIEB0cy1leHBlY3QtZXJyb3Igbm90IHR5cGVkXG4gIGNvdW50SXRlbXM6IGdldEFwcGxpY2F0aW9uQ29uZmlnKCkudXNlT25GaWx0ZXJlZEl0ZW1zQ2hhbmdlID8/IGZhbHNlXG59KTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuY29uc3QgZGVmYXVsdERhdGFBY2Nlc3NvciA9IGRjID0+IGQgPT4gZDtcbmNvbnN0IGlkZW50aXR5ID0gZCA9PiBkO1xuLy8gQ2FuJ3QgdXNlIGZpZWRWYWx1ZUFjY2Vzb3IgYmVjYXVzZSBuZWVkIHRoZSByYXcgZGF0YSB0byByZW5kZXIgdG9vbHRpcFxuLy8gU0hBTjogUmV2aXNpdCBoZXJlXG5leHBvcnQgY29uc3QgZGVmYXVsdEdldEZpZWxkVmFsdWUgPSAoZmllbGQsIGQpID0+IGZpZWxkLnZhbHVlQWNjZXNzb3IoZCk7XG5cbmV4cG9ydCBjb25zdCBPVkVSTEFZX1RZUEVfQ09OU1QgPSBrZXltaXJyb3Ioe1xuICBkZWNrZ2w6IG51bGwsXG4gIG1hcGJveGdsOiBudWxsXG59KTtcblxuZXhwb3J0IGNvbnN0IGxheWVyQ29sb3JzID0gT2JqZWN0LnZhbHVlcyhEYXRhVml6Q29sb3JzKS5tYXAoaGV4VG9SZ2IpO1xuZnVuY3Rpb24qIGdlbmVyYXRlQ29sb3IoKTogR2VuZXJhdG9yPFJHQkNvbG9yPiB7XG4gIGxldCBpbmRleCA9IDA7XG4gIHdoaWxlIChpbmRleCA8IGxheWVyQ29sb3JzLmxlbmd0aCArIDEpIHtcbiAgICBpZiAoaW5kZXggPT09IGxheWVyQ29sb3JzLmxlbmd0aCkge1xuICAgICAgaW5kZXggPSAwO1xuICAgIH1cbiAgICB5aWVsZCBsYXllckNvbG9yc1tpbmRleCsrXTtcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBMYXllckluZm9Nb2RhbCA9IHtcbiAgaWQ6IHN0cmluZztcbiAgdGVtcGxhdGU6IFJlYWN0LkZDPHZvaWQ+O1xuICBtb2RhbFByb3BzOiB7XG4gICAgdGl0bGU6IHN0cmluZztcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb2xvck1ha2VyID0gZ2VuZXJhdGVDb2xvcigpO1xuXG5leHBvcnQgdHlwZSBCYXNlTGF5ZXJDb25zdHJ1Y3RvclByb3BzID0ge1xuICBpZD86IHN0cmluZztcbn0gJiBMYXllckJhc2VDb25maWdQYXJ0aWFsO1xuXG5jbGFzcyBMYXllciBpbXBsZW1lbnRzIEtlcGxlckxheWVyIHtcbiAgaWQ6IHN0cmluZztcbiAgbWV0YTogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgdmlzQ29uZmlnU2V0dGluZ3M6IHtcbiAgICBba2V5OiBzdHJpbmddOiBWYWx1ZU9mPExheWVyVmlzQ29uZmlnU2V0dGluZ3M+O1xuICB9O1xuICBjb25maWc6IExheWVyQmFzZUNvbmZpZyAmIFBhcnRpYWw8TGF5ZXJDb2xvckNvbmZpZyAmIExheWVyU2l6ZUNvbmZpZz47XG4gIC8vIFRPRE86IGRlZmluZSBfb2xkRGF0YVVwZGF0ZVRyaWdnZXJzXG4gIF9vbGREYXRhVXBkYXRlVHJpZ2dlcnM6IGFueTtcblxuICBpc1ZhbGlkOiBib29sZWFuO1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZyB8IG51bGw7XG4gIGZpbHRlcmVkSXRlbUNvdW50OiB7XG4gICAgW2RlY2tMYXllcklkOiBzdHJpbmddOiBudW1iZXI7XG4gIH07XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IEJhc2VMYXllckNvbnN0cnVjdG9yUHJvcHMpIHtcbiAgICB0aGlzLmlkID0gcHJvcHMuaWQgfHwgZ2VuZXJhdGVIYXNoSWQoTEFZRVJfSURfTEVOR1RIKTtcbiAgICAvLyBtZXRhXG4gICAgdGhpcy5tZXRhID0ge307XG5cbiAgICAvLyB2aXNDb25maWdTZXR0aW5nc1xuICAgIHRoaXMudmlzQ29uZmlnU2V0dGluZ3MgPSB7fTtcblxuICAgIHRoaXMuY29uZmlnID0gdGhpcy5nZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMpO1xuXG4gICAgLy8gc2V0IGNvbHVtbk1vZGUgZnJvbSBzdXBwb3J0ZWQgY29sdW1uc1xuICAgIGlmICghdGhpcy5jb25maWcuY29sdW1uTW9kZSkge1xuICAgICAgY29uc3Qge3N1cHBvcnRlZENvbHVtbk1vZGVzfSA9IHRoaXM7XG4gICAgICBpZiAoc3VwcG9ydGVkQ29sdW1uTW9kZXM/Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmNvbmZpZy5jb2x1bW5Nb2RlID0gc3VwcG9ydGVkQ29sdW1uTW9kZXNbMF0/LmtleTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGhlbiBzZXQgY29sdW1uLCBjb2x1bW5Nb2RlIHNob3VsZCBhbHJlYWR5IGJlZW4gc2V0XG4gICAgdGhpcy5jb25maWcuY29sdW1ucyA9IHRoaXMuZ2V0TGF5ZXJDb2x1bW5zKHByb3BzLmNvbHVtbnMpO1xuXG4gICAgLy8gZmFsc2UgaW5kaWNhdGVzIHRoYXQgdGhlIGxheWVyIGNhdXNlZCBhbiBlcnJvciwgYW5kIHdhcyBkaXNhYmxlZFxuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XG4gICAgdGhpcy5lcnJvck1lc3NhZ2UgPSBudWxsO1xuICAgIC8vIGl0ZW0gY291bnRcbiAgICB0aGlzLmZpbHRlcmVkSXRlbUNvdW50ID0ge307XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCk6IFJlYWN0LkVsZW1lbnRUeXBlIHtcbiAgICByZXR1cm4gRGVmYXVsdExheWVySWNvbjtcbiAgfVxuXG4gIGdldCBvdmVybGF5VHlwZSgpOiBrZXlvZiB0eXBlb2YgT1ZFUkxBWV9UWVBFX0NPTlNUIHtcbiAgICByZXR1cm4gT1ZFUkxBWV9UWVBFX0NPTlNULmRlY2tnbDtcbiAgfVxuXG4gIGdldCB0eXBlKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZ2V0IG5hbWUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMudHlwZTtcbiAgfVxuXG4gIGdldCBpc0FnZ3JlZ2F0ZWQoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZ2V0IHJlcXVpcmVkTGF5ZXJDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCB7c3VwcG9ydGVkQ29sdW1uTW9kZXN9ID0gdGhpcztcbiAgICBpZiAoc3VwcG9ydGVkQ29sdW1uTW9kZXMpIHtcbiAgICAgIHJldHVybiBzdXBwb3J0ZWRDb2x1bW5Nb2Rlcy5yZWR1Y2U8c3RyaW5nW10+KFxuICAgICAgICAoYWNjLCBvYmopID0+IChvYmoucmVxdWlyZWRDb2x1bW5zID8gYWNjLmNvbmNhdChvYmoucmVxdWlyZWRDb2x1bW5zKSA6IGFjYyksXG4gICAgICAgIFtdXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgb3B0aW9uYWxDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCB7c3VwcG9ydGVkQ29sdW1uTW9kZXN9ID0gdGhpcztcbiAgICBpZiAoc3VwcG9ydGVkQ29sdW1uTW9kZXMpIHtcbiAgICAgIHJldHVybiBzdXBwb3J0ZWRDb2x1bW5Nb2Rlcy5yZWR1Y2U8c3RyaW5nW10+KFxuICAgICAgICAoYWNjLCBvYmopID0+IChvYmoub3B0aW9uYWxDb2x1bW5zID8gYWNjLmNvbmNhdChvYmoub3B0aW9uYWxDb2x1bW5zKSA6IGFjYyksXG4gICAgICAgIFtdXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgbm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzKCkge1xuICAgIHJldHVybiBbJ2xhYmVsJywgJ29wYWNpdHknLCAndGhpY2tuZXNzJywgJ2lzVmlzaWJsZScsICdoaWRkZW4nXTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpOiBWaXN1YWxDaGFubmVscyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB7XG4gICAgICAgIHByb3BlcnR5OiAnY29sb3InLFxuICAgICAgICBmaWVsZDogJ2NvbG9yRmllbGQnLFxuICAgICAgICBzY2FsZTogJ2NvbG9yU2NhbGUnLFxuICAgICAgICBkb21haW46ICdjb2xvckRvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnY29sb3JSYW5nZScsXG4gICAgICAgIGtleTogJ2NvbG9yJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMuY29sb3IsXG4gICAgICAgIG51bGxWYWx1ZTogTk9fVkFMVUVfQ09MT1IsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogY29uZmlnID0+IGNvbmZpZy5jb2xvclxuICAgICAgfSxcbiAgICAgIHNpemU6IHtcbiAgICAgICAgcHJvcGVydHk6ICdzaXplJyxcbiAgICAgICAgZmllbGQ6ICdzaXplRmllbGQnLFxuICAgICAgICBzY2FsZTogJ3NpemVTY2FsZScsXG4gICAgICAgIGRvbWFpbjogJ3NpemVEb21haW4nLFxuICAgICAgICByYW5nZTogJ3NpemVSYW5nZScsXG4gICAgICAgIGtleTogJ3NpemUnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiBDSEFOTkVMX1NDQUxFUy5zaXplLFxuICAgICAgICBudWxsVmFsdWU6IDAsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogMVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXQgY29sdW1uVmFsaWRhdG9ycygpOiB7W2tleTogc3RyaW5nXTogQ29sdW1uVmFsaWRhdG9yfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIC8qXG4gICAqIENvbHVtbiBwYWlycyBtYXBzIGxheWVyIGNvbHVtbiB0byBhIHNwZWNpZmljIGZpZWxkIHBhaXJzLFxuICAgKiBCeSBkZWZhdWx0LCBpdCBpcyBzZXQgdG8gbnVsbFxuICAgKi9cbiAgZ2V0IGNvbHVtblBhaXJzKCk6IENvbHVtblBhaXJzIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ29sdW1uIGxhYmVscyBpZiBpdHMgZGlmZmVyZW50IHRoYW4gY29sdW1uIGtleVxuICAgKi9cbiAgZ2V0IGNvbHVtbkxhYmVscygpOiBDb2x1bW5MYWJlbHMgfCBudWxsIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qXG4gICAqIERlZmF1bHQgcG9pbnQgY29sdW1uIHBhaXJzLCBjYW4gYmUgdXNlZCBmb3IgcG9pbnQgYmFzZWQgbGF5ZXJzOiBwb2ludCwgaWNvbiBldGMuXG4gICAqL1xuICBnZXQgZGVmYXVsdFBvaW50Q29sdW1uUGFpcnMoKTogQ29sdW1uUGFpcnMge1xuICAgIHJldHVybiB7XG4gICAgICBsYXQ6IHtwYWlyOiBbJ2xuZycsICdhbHRpdHVkZSddLCBmaWVsZFBhaXJLZXk6ICdsYXQnfSxcbiAgICAgIGxuZzoge3BhaXI6IFsnbGF0JywgJ2FsdGl0dWRlJ10sIGZpZWxkUGFpcktleTogJ2xuZyd9LFxuICAgICAgYWx0aXR1ZGU6IHtwYWlyOiBbJ2xuZycsICdsYXQnXSwgZmllbGRQYWlyS2V5OiAnYWx0aXR1ZGUnfVxuICAgIH07XG4gIH1cblxuICAvKlxuICAgKiBEZWZhdWx0IGxpbmsgY29sdW1uIHBhaXJzLCBjYW4gYmUgdXNlZCBmb3IgbGluayBiYXNlZCBsYXllcnM6IGFyYywgbGluZSBldGNcbiAgICovXG4gIGdldCBkZWZhdWx0TGlua0NvbHVtblBhaXJzKCk6IENvbHVtblBhaXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbGF0OiB7cGFpcjogWydsbmcnLCAnYWx0J10sIGZpZWxkUGFpcktleTogJ2xhdCd9LFxuICAgICAgbG5nOiB7cGFpcjogWydsYXQnLCAnYWx0J10sIGZpZWxkUGFpcktleTogJ2xuZyd9LFxuICAgICAgYWx0OiB7cGFpcjogWydsbmcnLCAnbGF0J10sIGZpZWxkUGFpcktleTogJ2FsdGl0dWRlJ30sXG5cbiAgICAgIGxhdDA6IHtwYWlyOiAnbG5nMCcsIGZpZWxkUGFpcktleTogJ2xhdCd9LFxuICAgICAgbG5nMDoge3BhaXI6ICdsYXQwJywgZmllbGRQYWlyS2V5OiAnbG5nJ30sXG4gICAgICBhbHQwOiB7cGFpcjogWydsbmcwJywgJ2xhdDAnXSwgZmllbGRQYWlyS2V5OiAnYWx0aXR1ZGUnfSxcblxuICAgICAgbGF0MToge3BhaXI6ICdsbmcxJywgZmllbGRQYWlyS2V5OiAnbGF0J30sXG4gICAgICBsbmcxOiB7cGFpcjogJ2xhdDEnLCBmaWVsZFBhaXJLZXk6ICdsbmcnfSxcbiAgICAgIGFsdDE6IHtwYWlyOiBbJ2xuZzEnLCAnbGF0MSddLCBmaWVsZFBhaXJLZXk6ICdhbHRpdHVkZSd9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBSZWFjdCBjb21wb25lbnQgZm9yIHRvIHJlbmRlciBsYXllciBpbnN0cnVjdGlvbnMgaW4gYSBtb2RhbFxuICAgKiBAcmV0dXJucyB7b2JqZWN0fSAtIGFuIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiAgcmV0dXJuIHtcbiAgICogICAgaWQ6ICdpY29uSW5mbycsXG4gICAqICAgIHRlbXBsYXRlOiBJY29uSW5mb01vZGFsLFxuICAgKiAgICBtb2RhbFByb3BzOiB7XG4gICAqICAgICAgdGl0bGU6ICdIb3cgdG8gZHJhdyBpY29ucydcbiAgICogICB9O1xuICAgKiB9XG4gICAqL1xuICBnZXQgbGF5ZXJJbmZvTW9kYWwoKTogTGF5ZXJJbmZvTW9kYWwgfCBSZWNvcmQ8c3RyaW5nLCBMYXllckluZm9Nb2RhbD4gfCBudWxsIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoaWNoIGNvbHVtbiBtb2RlcyB0aGlzIGxheWVyIHN1cHBvcnRzXG4gICAqL1xuICBnZXQgc3VwcG9ydGVkQ29sdW1uTW9kZXMoKTogU3VwcG9ydGVkQ29sdW1uTW9kZVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBnZXQgc3VwcG9ydGVkRGF0YXNldFR5cGVzKCk6IHN0cmluZ1tdIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKlxuICAgKiBHaXZlbiBhIGRhdGFzZXQsIGF1dG9tYXRpY2FsbHkgZmluZCBwcm9wcyB0byBjcmVhdGUgbGF5ZXIgYmFzZWQgb24gaXRcbiAgICogYW5kIHJldHVybiB0aGUgcHJvcHMgYW5kIHByZXZpb3VzIGZvdW5kIGxheWVycy5cbiAgICogQnkgZGVmYXVsdCwgbm8gbGF5ZXJzIHdpbGwgYmUgZm91bmRcbiAgICovXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoXG4gICAgZGF0YXNldDogS2VwbGVyVGFibGUsXG4gICAgZm91bmRMYXllcnM/OiBhbnlbXVxuICApOiBGaW5kRGVmYXVsdExheWVyUHJvcHNSZXR1cm5WYWx1ZSB7XG4gICAgcmV0dXJuIHtwcm9wczogW10sIGZvdW5kTGF5ZXJzfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIGFycmF5IG9mIHByZXNldCByZXF1aXJlZCBjb2x1bW4gbmFtZXNcbiAgICogZm91bmQgZmllbGQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSB0byBzZXQgYXMgbGF5ZXIgY29sdW1uXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkZWZhdWx0RmllbGRzXG4gICAqIEBwYXJhbSB7b2JqZWN0W119IGFsbEZpZWxkc1xuICAgKiBAcmV0dXJucyB7b2JqZWN0W10gfCBudWxsfSBhbGwgcG9zc2libGUgcmVxdWlyZWQgbGF5ZXIgY29sdW1uIHBhaXJzXG4gICAqL1xuICBzdGF0aWMgZmluZERlZmF1bHRDb2x1bW5GaWVsZChkZWZhdWx0RmllbGRzLCBhbGxGaWVsZHMpIHtcbiAgICAvLyBmaW5kIGFsbCBtYXRjaGVkIGZpZWxkcyBmb3IgZWFjaCByZXF1aXJlZCBjb2xcbiAgICBjb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3Qua2V5cyhkZWZhdWx0RmllbGRzKS5yZWR1Y2UoKHByZXYsIGtleSkgPT4ge1xuICAgICAgY29uc3QgcmVxdWlyZWRGaWVsZHMgPSBhbGxGaWVsZHMuZmlsdGVyKFxuICAgICAgICBmID0+IGYubmFtZSA9PT0gZGVmYXVsdEZpZWxkc1trZXldIHx8IGRlZmF1bHRGaWVsZHNba2V5XS5pbmNsdWRlcyhmLm5hbWUpXG4gICAgICApO1xuXG4gICAgICBwcmV2W2tleV0gPSByZXF1aXJlZEZpZWxkcy5sZW5ndGhcbiAgICAgICAgPyByZXF1aXJlZEZpZWxkcy5tYXAoZiA9PiAoe1xuICAgICAgICAgICAgdmFsdWU6IGYubmFtZSxcbiAgICAgICAgICAgIGZpZWxkSWR4OiBmLmZpZWxkSWR4XG4gICAgICAgICAgfSkpXG4gICAgICAgIDogbnVsbDtcbiAgICAgIHJldHVybiBwcmV2O1xuICAgIH0sIHt9KTtcblxuICAgIGlmICghT2JqZWN0LnZhbHVlcyhyZXF1aXJlZENvbHVtbnMpLmV2ZXJ5KEJvb2xlYW4pKSB7XG4gICAgICAvLyBpZiBhbnkgZmllbGQgbWlzc2luZywgcmV0dXJuIG51bGxcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmdldEFsbFBvc3NpYmxlQ29sdW1uUGFpcnMocmVxdWlyZWRDb2x1bW5zKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRBbGxQb3NzaWJsZUNvbHVtblBhaXJzKHJlcXVpcmVkQ29sdW1ucykge1xuICAgIC8vIGZvciBtdWx0aXBsZSBtYXRjaGVkIGZpZWxkIGZvciBvbmUgcmVxdWlyZWQgY29sdW1uLCByZXR1cm4gbXVsdGlwbGVcbiAgICAvLyBjb21iaW5hdGlvbnMsIGUuIGcuIGlmIGNvbHVtbiBhIGhhcyAyIG1hdGNoZWQsIGNvbHVtbiBiIGhhcyAzIG1hdGNoZWRcbiAgICAvLyA2IHBvc3NpYmxlIGNvbHVtbiBwYWlycyB3aWxsIGJlIHJldHVybmVkXG4gICAgY29uc3QgYWxsS2V5cyA9IE9iamVjdC5rZXlzKHJlcXVpcmVkQ29sdW1ucyk7XG4gICAgY29uc3QgcG9pbnRlcnMgPSBhbGxLZXlzLm1hcCgoaywgaSkgPT4gKGkgPT09IGFsbEtleXMubGVuZ3RoIC0gMSA/IC0xIDogMCkpO1xuICAgIGNvbnN0IGNvdW50UGVyS2V5ID0gYWxsS2V5cy5tYXAoayA9PiByZXF1aXJlZENvbHVtbnNba10ubGVuZ3RoKTtcbiAgICAvLyBUT0RPOiBCZXR0ZXIgdHlwaW5nc1xuICAgIGNvbnN0IHBhaXJzOiBhbnlbXSA9IFtdO1xuXG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovXG4gICAgd2hpbGUgKGluY3JlbWVudFBvaW50ZXJzKHBvaW50ZXJzLCBjb3VudFBlcktleSwgcG9pbnRlcnMubGVuZ3RoIC0gMSkpIHtcbiAgICAgIGNvbnN0IG5ld1BhaXIgPSBwb2ludGVycy5yZWR1Y2UoKHByZXYsIGN1dXIsIGkpID0+IHtcbiAgICAgICAgcHJldlthbGxLZXlzW2ldXSA9IHJlcXVpcmVkQ29sdW1uc1thbGxLZXlzW2ldXVtjdXVyXTtcbiAgICAgICAgcmV0dXJuIHByZXY7XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIHBhaXJzLnB1c2gobmV3UGFpcik7XG4gICAgfVxuICAgIC8qIGVzbGludC1lbmFibGUgbm8tbG9vcC1mdW5jICovXG5cbiAgICAvLyByZWN1cnNpdmVseSBpbmNyZW1lbnQgcG9pbnRlcnNcbiAgICBmdW5jdGlvbiBpbmNyZW1lbnRQb2ludGVycyhwdHMsIGNvdW50cywgaW5kZXgpIHtcbiAgICAgIGlmIChpbmRleCA9PT0gMCAmJiBwdHNbMF0gPT09IGNvdW50c1swXSAtIDEpIHtcbiAgICAgICAgLy8gbm90aGluZyB0byBpbmNyZW1lbnRcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHRzW2luZGV4XSArIDEgPCBjb3VudHNbaW5kZXhdKSB7XG4gICAgICAgIHB0c1tpbmRleF0gPSBwdHNbaW5kZXhdICsgMTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHB0c1tpbmRleF0gPSAwO1xuICAgICAgcmV0dXJuIGluY3JlbWVudFBvaW50ZXJzKHB0cywgY291bnRzLCBpbmRleCAtIDEpO1xuICAgIH1cblxuICAgIHJldHVybiBwYWlycztcbiAgfVxuXG4gIHN0YXRpYyBoZXhUb1JnYihjKSB7XG4gICAgcmV0dXJuIGhleFRvUmdiKGMpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKFxuICAgIHByb3BzOiBMYXllckJhc2VDb25maWdQYXJ0aWFsXG4gICk6IExheWVyQmFzZUNvbmZpZyAmIFBhcnRpYWw8TGF5ZXJDb2xvckNvbmZpZyAmIExheWVyU2l6ZUNvbmZpZz4ge1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhSWQ6IHByb3BzLmRhdGFJZCxcbiAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCB8fCBERUZBVUxUX0xBWUVSX0xBQkVMLFxuICAgICAgY29sb3I6IHByb3BzLmNvbG9yIHx8IGNvbG9yTWFrZXIubmV4dCgpLnZhbHVlLFxuICAgICAgLy8gc2V0IGNvbHVtbnMgbGF0ZXJcbiAgICAgIGNvbHVtbnM6IHt9LFxuICAgICAgaXNWaXNpYmxlOiBwcm9wcy5pc1Zpc2libGUgPz8gdHJ1ZSxcbiAgICAgIGlzQ29uZmlnQWN0aXZlOiBwcm9wcy5pc0NvbmZpZ0FjdGl2ZSA/PyBmYWxzZSxcbiAgICAgIGhpZ2hsaWdodENvbG9yOiBwcm9wcy5oaWdobGlnaHRDb2xvciB8fCBERUZBVUxUX0hJR0hMSUdIVF9DT0xPUixcbiAgICAgIGhpZGRlbjogcHJvcHMuaGlkZGVuID8/IGZhbHNlLFxuXG4gICAgICAvLyBUT0RPOiByZWZhY3RvciB0aGlzIGludG8gc2VwYXJhdGUgdmlzdWFsIENoYW5uZWwgY29uZmlnXG4gICAgICAvLyBjb2xvciBieSBmaWVsZCwgZG9tYWluIGlzIHNldCBieSBmaWx0ZXJzLCBmaWVsZCwgc2NhbGUgdHlwZVxuICAgICAgY29sb3JGaWVsZDogbnVsbCxcbiAgICAgIGNvbG9yRG9tYWluOiBbMCwgMV0sXG4gICAgICBjb2xvclNjYWxlOiBTQ0FMRV9UWVBFUy5xdWFudGlsZSxcblxuICAgICAgLy8gY29sb3IgYnkgc2l6ZSwgZG9tYWluIGlzIHNldCBieSBmaWx0ZXJzLCBmaWVsZCwgc2NhbGUgdHlwZVxuICAgICAgc2l6ZURvbWFpbjogWzAsIDFdLFxuICAgICAgc2l6ZVNjYWxlOiBTQ0FMRV9UWVBFUy5saW5lYXIsXG4gICAgICBzaXplRmllbGQ6IG51bGwsXG5cbiAgICAgIHZpc0NvbmZpZzoge30sXG5cbiAgICAgIHRleHRMYWJlbDogW0RFRkFVTFRfVEVYVF9MQUJFTF0sXG5cbiAgICAgIGNvbG9yVUk6IHtcbiAgICAgICAgY29sb3I6IERFRkFVTFRfQ09MT1JfVUksXG4gICAgICAgIGNvbG9yUmFuZ2U6IERFRkFVTFRfQ09MT1JfVUlcbiAgICAgIH0sXG4gICAgICBhbmltYXRpb246IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICAuLi4ocHJvcHMuY29sdW1uTW9kZSA/IHtjb2x1bW5Nb2RlOiBwcm9wcy5jb2x1bW5Nb2RlfSA6IHt9KVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkZXNjcmlwdGlvbiBvZiBhIHZpc3VhbENoYW5uZWwgY29uZmlnXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbihrZXk6IHN0cmluZyk6IFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbiB7XG4gICAgLy8gZS5nLiBsYWJlbDogQ29sb3IsIG1lYXN1cmU6IFZlaGljbGUgVHlwZVxuICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLnZpc3VhbENoYW5uZWxzW2tleV07XG4gICAgaWYgKCFjaGFubmVsKSByZXR1cm4ge2xhYmVsOiAnJywgbWVhc3VyZTogdW5kZWZpbmVkfTtcbiAgICBjb25zdCByYW5nZVNldHRpbmdzID0gdGhpcy52aXNDb25maWdTZXR0aW5nc1tjaGFubmVsLnJhbmdlXTtcbiAgICBjb25zdCBmaWVsZFNldHRpbmdzID0gdGhpcy5jb25maWdbY2hhbm5lbC5maWVsZF07XG4gICAgY29uc3QgbGFiZWwgPSByYW5nZVNldHRpbmdzPy5sYWJlbDtcbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IHR5cGVvZiBsYWJlbCA9PT0gJ2Z1bmN0aW9uJyA/IGxhYmVsKHRoaXMuY29uZmlnKSA6IGxhYmVsIHx8ICcnLFxuICAgICAgbWVhc3VyZTogZmllbGRTZXR0aW5nc1xuICAgICAgICA/IGZpZWxkU2V0dGluZ3MuZGlzcGxheU5hbWUgfHwgZmllbGRTZXR0aW5ncy5uYW1lXG4gICAgICAgIDogY2hhbm5lbC5kZWZhdWx0TWVhc3VyZVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQXNzaWduIGEgZmllbGQgdG8gbGF5ZXIgY29sdW1uLCByZXR1cm4gY29sdW1uIGNvbmZpZ1xuICAgKi9cbiAgYXNzaWduQ29sdW1uKGtleTogc3RyaW5nLCBmaWVsZDoge25hbWU6IHN0cmluZzsgZmllbGRJZHg6IG51bWJlcn0pOiBMYXllckNvbHVtbnMge1xuICAgIC8vIGZpZWxkIHZhbHVlIGNvdWxkIGJlIG51bGwgZm9yIG9wdGlvbmFsIGNvbHVtbnNcbiAgICBjb25zdCB1cGRhdGUgPSBmaWVsZFxuICAgICAgPyB7XG4gICAgICAgICAgdmFsdWU6IGZpZWxkLm5hbWUsXG4gICAgICAgICAgZmllbGRJZHg6IGZpZWxkLmZpZWxkSWR4XG4gICAgICAgIH1cbiAgICAgIDoge3ZhbHVlOiBudWxsLCBmaWVsZElkeDogLTF9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICBba2V5XToge1xuICAgICAgICAuLi50aGlzLmNvbmZpZy5jb2x1bW5zPy5ba2V5XSxcbiAgICAgICAgLi4udXBkYXRlXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ24gYSBmaWVsZCBwYWlyIHRvIGNvbHVtbiBjb25maWcsIHJldHVybiBjb2x1bW4gY29uZmlnXG4gICAqL1xuICBhc3NpZ25Db2x1bW5QYWlycyhrZXk6IHN0cmluZywgZmllbGRQYWlyczogRmllbGRQYWlyKTogTGF5ZXJDb2x1bW5zIHtcbiAgICBpZiAoIXRoaXMuY29sdW1uUGFpcnMgfHwgIXRoaXMuY29sdW1uUGFpcnM/LltrZXldKSB7XG4gICAgICAvLyBzaG91bGQgbm90IGVuZCBpbiB0aGlzIHN0YXRlXG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuY29sdW1ucztcbiAgICB9XG4gICAgLy8ga2V5ID0gJ2xhdCdcbiAgICBjb25zdCB7cGFpciwgZmllbGRQYWlyS2V5fSA9IHRoaXMuY29sdW1uUGFpcnM/LltrZXldIHx8IHt9O1xuXG4gICAgaWYgKHR5cGVvZiBmaWVsZFBhaXJLZXkgPT09ICdzdHJpbmcnICYmICFmaWVsZFBhaXJzW2ZpZWxkUGFpcktleV0pIHtcbiAgICAgIC8vIGRvIG5vdCBhbGxvdyBga2V5OiB1bmRlZmluZWRgIHRvIGNyZWVwIGludG8gdGhlIGB1cGRhdGVkQ29sdW1uYCBvYmplY3RcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5jb2x1bW5zO1xuICAgIH1cblxuICAgIC8vIHBhaXIgPSBbJ2xuZycsICdhbHRdIHwgJ2xuZydcbiAgICBjb25zdCB1cGRhdGVkQ29sdW1uID0ge1xuICAgICAgLi4udGhpcy5jb25maWcuY29sdW1ucyxcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgZmllbGRQYWlyS2V5IGNhbiBiZSBzdHJpbmdbXSBoZXJlP1xuICAgICAgW2tleV06IGZpZWxkUGFpcnNbZmllbGRQYWlyS2V5XVxuICAgIH07XG5cbiAgICBjb25zdCBwYXJ0bmVyS2V5cyA9IHRvQXJyYXkocGFpcik7XG4gICAgZm9yIChjb25zdCBwYXJ0bmVyS2V5IG9mIHBhcnRuZXJLZXlzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuY29uZmlnLmNvbHVtbnNbcGFydG5lcktleV0gJiZcbiAgICAgICAgdGhpcy5jb2x1bW5QYWlycz8uW3BhcnRuZXJLZXldICYmXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgZmllbGRQYWlyc1t0aGlzLmNvbHVtblBhaXJzPy5bcGFydG5lcktleV0uZmllbGRQYWlyS2V5XVxuICAgICAgKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdXBkYXRlZENvbHVtbltwYXJ0bmVyS2V5XSA9IGZpZWxkUGFpcnNbdGhpcy5jb2x1bW5QYWlycz8uW3BhcnRuZXJLZXldLmZpZWxkUGFpcktleV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVwZGF0ZWRDb2x1bW47XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIGEgcmFkaXVzIHpvb20gbXVsdGlwbGllciB0byByZW5kZXIgcG9pbnRzLCBzbyB0aGV5IGFyZSB2aXNpYmxlIGluIGFsbCB6b29tIGxldmVsXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtYXBTdGF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gbWFwU3RhdGUuem9vbSAtIGFjdHVhbCB6b29tXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgdm9pZH0gbWFwU3RhdGUuem9vbU9mZnNldCAtIHpvb21PZmZzZXQgd2hlbiByZW5kZXIgaW4gdGhlIHBsb3QgY29udGFpbmVyIGZvciBleHBvcnQgaW1hZ2VcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIGdldFpvb21GYWN0b3Ioe3pvb20sIHpvb21PZmZzZXQgPSAwfSkge1xuICAgIHJldHVybiBNYXRoLnBvdygyLCBNYXRoLm1heCgxNCAtIHpvb20gKyB6b29tT2Zmc2V0LCAwKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIGEgZWxldmF0aW9uIHpvb20gbXVsdGlwbGllciB0byByZW5kZXIgcG9pbnRzLCBzbyB0aGV5IGFyZSB2aXNpYmxlIGluIGFsbCB6b29tIGxldmVsXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtYXBTdGF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gbWFwU3RhdGUuem9vbSAtIGFjdHVhbCB6b29tXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gbWFwU3RhdGUuem9vbU9mZnNldCAtIHpvb21PZmZzZXQgd2hlbiByZW5kZXIgaW4gdGhlIHBsb3QgY29udGFpbmVyIGZvciBleHBvcnQgaW1hZ2VcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIGdldEVsZXZhdGlvblpvb21GYWN0b3Ioe3pvb20sIHpvb21PZmZzZXQgPSAwfToge3pvb206IG51bWJlcjsgem9vbU9mZnNldD86IG51bWJlcn0pOiBudW1iZXIge1xuICAgIC8vIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3IgaXMgdXNlZCB0byBzdXBwb3J0IGV4aXN0aW5nIG1hcHNcbiAgICBjb25zdCB7Zml4ZWRIZWlnaHQsIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3J9ID0gdGhpcy5jb25maWcudmlzQ29uZmlnO1xuICAgIHJldHVybiBmaXhlZEhlaWdodCB8fCBlbmFibGVFbGV2YXRpb25ab29tRmFjdG9yID09PSBmYWxzZVxuICAgICAgPyAxXG4gICAgICA6IE1hdGgucG93KDIsIE1hdGgubWF4KDggLSB6b29tICsgem9vbU9mZnNldCwgMCkpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBmb3JtYXRMYXllckRhdGEoZGF0YXNldHM6IERhdGFzZXRzLCBvbGRMYXllckRhdGE/OiB1bmtub3duLCBhbmltYXRpb25Db25maWc/OiBBbmltYXRpb25Db25maWcpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHJlbmRlckxheWVyKC4uLmFyZ3M6IGFueVtdKTogYW55W10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0SG92ZXJEYXRhKFxuICAgIG9iamVjdDogYW55LFxuICAgIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGZpZWxkcz86IEZpZWxkW10sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGFuaW1hdGlvbkNvbmZpZz86IEFuaW1hdGlvbkNvbmZpZyxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgaG92ZXJJbmZvPzoge2luZGV4OiBudW1iZXJ9XG4gICk6IGFueSB7XG4gICAgaWYgKCFvYmplY3QpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIEJ5IGRlZmF1bHQsIGVhY2ggZW50cnkgb2YgbGF5ZXJEYXRhIHNob3VsZCBoYXZlIGFuIGluZGV4IG9mIGEgcm93IGluIHRoZSBvcmlnaW5hbCBkYXRhIGNvbnRhaW5lci5cbiAgICAvLyBFYWNoIGxheWVyIGNhbiBpbXBsZW1lbnQgaXRzIG93biBnZXRIb3ZlckRhdGEgbWV0aG9kXG4gICAgcmV0dXJuIGRhdGFDb250YWluZXIucm93KG9iamVjdC5pbmRleCk7XG4gIH1cblxuICBnZXRGaWx0ZXJlZEl0ZW1Db3VudCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICAvLyB1c2UgZmlyc3QgbGF5ZXJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5maWx0ZXJlZEl0ZW1Db3VudCkubGVuZ3RoKSB7XG4gICAgICBjb25zdCBmaXJzdExheWVyID0gT2JqZWN0LmtleXModGhpcy5maWx0ZXJlZEl0ZW1Db3VudClbMF07XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXJlZEl0ZW1Db3VudFtmaXJzdExheWVyXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIFdoZW4gY2hhbmdlIGxheWVyIHR5cGUsIHRyeSB0byBjb3B5IG92ZXIgbGF5ZXIgY29uZmlncyBhcyBtdWNoIGFzIHBvc3NpYmxlXG4gICAqIEBwYXJhbSBjb25maWdUb0NvcHkgLSBjb25maWcgdG8gY29weSBvdmVyXG4gICAqIEBwYXJhbSB2aXNDb25maWdTZXR0aW5ncyAtIHZpc0NvbmZpZyBzZXR0aW5ncyBvZiBjb25maWcgdG8gY29weVxuICAgKiBAcGFyYW0gZGF0YXNldHMgLSBjdXJyZW50IGRhdGFzZXRzLlxuICAgKiBAcGFyYW0gZGVmYXVsdExheWVyUHJvcHMgLSBkZWZhdWx0IGxheWVyIGNyZWF0aW9uIGNvbmZpZ3VyYXRpb25zIGZvciBjdXJyZW50IGxheWVyIGFuZCBkYXRhc2V0cy5cbiAgICovXG4gIGFzc2lnbkNvbmZpZ1RvTGF5ZXIoXG4gICAgY29uZmlnVG9Db3B5OiBMYXllckJhc2VDb25maWcgJiBQYXJ0aWFsPExheWVyQ29sb3JDb25maWcgJiBMYXllclNpemVDb25maWc+LFxuICAgIHZpc0NvbmZpZ1NldHRpbmdzOiB7W2tleTogc3RyaW5nXTogVmFsdWVPZjxMYXllclZpc0NvbmZpZ1NldHRpbmdzPn0sXG4gICAgZGF0YXNldHM/OiBEYXRhc2V0cyxcbiAgICBkZWZhdWx0TGF5ZXJQcm9wcz86IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlIHwgbnVsbFxuICApIHtcbiAgICAvLyBkb24ndCBkZWVwIG1lcmdlIHZpc3VhbENoYW5uZWwgZmllbGRcbiAgICAvLyBkb24ndCBkZWVwIG1lcmdlIGNvbG9yIHJhbmdlLCByZXZlcnNlZDogaXMgbm90IGEga2V5IGJ5IGRlZmF1bHRcbiAgICBjb25zdCBzaGFsbG93Q29weSA9IFsnY29sb3JSYW5nZScsICdzdHJva2VDb2xvclJhbmdlJ10uY29uY2F0KFxuICAgICAgT2JqZWN0LnZhbHVlcyh0aGlzLnZpc3VhbENoYW5uZWxzKS5tYXAodiA9PiB2LmZpZWxkKVxuICAgICk7XG5cbiAgICAvLyBkb24ndCBjb3B5IG92ZXIgZG9tYWluIGFuZCBhbmltYXRpb25cbiAgICBjb25zdCBub3RUb0NvcHkgPSBbJ2FuaW1hdGlvbiddLmNvbmNhdChPYmplY3QudmFsdWVzKHRoaXMudmlzdWFsQ2hhbm5lbHMpLm1hcCh2ID0+IHYuZG9tYWluKSk7XG4gICAgLy8gaWYgcmFuZ2UgaXMgZm9yIHRoZSBzYW1lIHByb3BlcnR5IGdyb3VwIGNvcHkgaXQsIG90aGVyd2lzZSwgbm90IHRvIGNvcHlcbiAgICBPYmplY3QudmFsdWVzKHRoaXMudmlzdWFsQ2hhbm5lbHMpLmZvckVhY2godiA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGNvbmZpZ1RvQ29weS52aXNDb25maWdbdi5yYW5nZV0gJiZcbiAgICAgICAgdGhpcy52aXNDb25maWdTZXR0aW5nc1t2LnJhbmdlXSAmJlxuICAgICAgICB2aXNDb25maWdTZXR0aW5nc1t2LnJhbmdlXS5ncm91cCAhPT0gdGhpcy52aXNDb25maWdTZXR0aW5nc1t2LnJhbmdlXS5ncm91cFxuICAgICAgKSB7XG4gICAgICAgIG5vdFRvQ29weS5wdXNoKHYucmFuZ2UpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gZG9uJ3QgY29weSBvdmVyIHZpc3VhbENoYW5uZWwgcmFuZ2VcbiAgICBjb25zdCBjdXJyZW50Q29uZmlnID0gdGhpcy5jb25maWc7XG4gICAgY29uc3QgY29waWVkID0gdGhpcy5jb3B5TGF5ZXJDb25maWcoY3VycmVudENvbmZpZywgY29uZmlnVG9Db3B5LCB7XG4gICAgICBzaGFsbG93Q29weSxcbiAgICAgIG5vdFRvQ29weVxuICAgIH0pO1xuXG4gICAgLy8gdXBkYXRlIGNvbHVtTm9kZSBiYXNlZCBvbiBuZXcgY29sdW1uc1xuICAgIGlmICh0aGlzLmNvbmZpZy5jb2x1bW5Nb2RlICYmIHRoaXMuc3VwcG9ydGVkQ29sdW1uTW9kZXMpIHtcbiAgICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0cz8uW3RoaXMuY29uZmlnLmRhdGFJZF07XG4gICAgICAvLyB0cnkgdG8gZmluZCBhIG1vZGUgd2l0aCBhbGwgcmVxdWllZCBjb2x1bW5zIGZyb20gdGhlIHNvdXJjZSBjb25maWdcbiAgICAgIGxldCBzYXRpc2ZpZWRDb2x1bW5Nb2RlID0gZ2V0U2F0aXNmaWVkQ29sdW1uTW9kZShcbiAgICAgICAgdGhpcy5zdXBwb3J0ZWRDb2x1bW5Nb2RlcyxcbiAgICAgICAgY29waWVkLmNvbHVtbnMsXG4gICAgICAgIGRhdGFzZXQ/LmZpZWxkc1xuICAgICAgKTtcblxuICAgICAgLy8gaWYgbm8gc3VpdGFibGUgY29sdW1uIG1vZGUgZm91bmQgb3Igbm8gc3VjaCBjb2x1bU1vZGUgZXhpc3RzIGZvciB0aGUgbGF5ZXJcbiAgICAgIC8vIHRoZW4gdHJ5IHVzZSBvbmUgb2YgdGhlIGF1dG9tYXRpY2FsbHkgZGV0ZWN0ZWQgbGF5ZXIgY29uZmlnc1xuICAgICAgaWYgKCFzYXRpc2ZpZWRDb2x1bW5Nb2RlKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBbXG4gICAgICAgICAgLi4uKGRlZmF1bHRMYXllclByb3BzPy5wcm9wcyB8fCBbXSksXG4gICAgICAgICAgLi4uKGRlZmF1bHRMYXllclByb3BzPy5hbHRQcm9wcyB8fCBbXSlcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gVXNlIHRoZSBmaXJzdCBvZiB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uc1xuICAgICAgICAgIGNvbnN0IGRlZmF1bHRDb2x1bW5Db25maWcgPSBvcHRpb25zWzBdLmNvbHVtbnM7XG5cbiAgICAgICAgICBzYXRpc2ZpZWRDb2x1bW5Nb2RlID0gZ2V0U2F0aXNmaWVkQ29sdW1uTW9kZShcbiAgICAgICAgICAgIHRoaXMuc3VwcG9ydGVkQ29sdW1uTW9kZXMsXG4gICAgICAgICAgICBkZWZhdWx0Q29sdW1uQ29uZmlnLFxuICAgICAgICAgICAgZGF0YXNldD8uZmllbGRzXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChzYXRpc2ZpZWRDb2x1bW5Nb2RlKSB7XG4gICAgICAgICAgICBjb3BpZWQuY29sdW1ucyA9IHtcbiAgICAgICAgICAgICAgLi4uY29waWVkLmNvbHVtbnMsXG4gICAgICAgICAgICAgIC4uLmRlZmF1bHRDb2x1bW5Db25maWdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvcGllZC5jb2x1bW5Nb2RlID0gc2F0aXNmaWVkQ29sdW1uTW9kZT8ua2V5IHx8IGNvcGllZC5jb2x1bW5Nb2RlO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoY29waWVkKTtcbiAgICAvLyB2YWxpZGF0ZSB2aXN1YWxDaGFubmVsIGZpZWxkIHR5cGUgYW5kIHNjYWxlIHR5cGVzXG4gICAgT2JqZWN0LmtleXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIHRoaXMudmFsaWRhdGVWaXN1YWxDaGFubmVsKGNoYW5uZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLypcbiAgICogUmVjdXJzaXZlbHkgY29weSBjb25maWcgb3ZlciB0byBhbiBlbXB0eSBsYXllclxuICAgKiB3aGVuIHJlY2VpdmVkIHNhdmVkIGNvbmZpZywgb3IgY29weSBjb25maWcgb3ZlciBmcm9tIGEgZGlmZmVyZW50IGxheWVyIHR5cGVcbiAgICogbWFrZSBzdXJlIHRvIG9ubHkgY29weSBvdmVyIHZhbHVlIHRvIGV4aXN0aW5nIGtleXNcbiAgICogQHBhcmFtIHtvYmplY3R9IGN1cnJlbnRDb25maWcgLSBleGlzdGluZyBjb25maWcgdG8gYmUgb3ZlcnJpZGVcbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1RvQ29weSAtIG5ldyBDb25maWcgdG8gY29weSBvdmVyXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHNoYWxsb3dDb3B5IC0gYXJyYXkgb2YgcHJvcGVydGllcyB0byBub3QgdG8gYmUgZGVlcCBjb3BpZWRcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gbm90VG9Db3B5IC0gYXJyYXkgb2YgcHJvcGVydGllcyBub3QgdG8gY29weVxuICAgKiBAcmV0dXJucyB7b2JqZWN0fSAtIGNvcGllZCBjb25maWdcbiAgICovXG4gIGNvcHlMYXllckNvbmZpZyhcbiAgICBjdXJyZW50Q29uZmlnLFxuICAgIGNvbmZpZ1RvQ29weSxcbiAgICB7c2hhbGxvd0NvcHkgPSBbXSwgbm90VG9Db3B5ID0gW119OiB7c2hhbGxvd0NvcHk/OiBzdHJpbmdbXTsgbm90VG9Db3B5Pzogc3RyaW5nW119ID0ge31cbiAgKSB7XG4gICAgY29uc3QgY29waWVkOiB7Y29sdW1uTW9kZT86IHN0cmluZzsgY29sdW1ucz86IExheWVyQ29sdW1uc30gPSB7fTtcbiAgICBPYmplY3Qua2V5cyhjdXJyZW50Q29uZmlnKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGlzUGxhaW5PYmplY3QoY3VycmVudENvbmZpZ1trZXldKSAmJlxuICAgICAgICBpc1BsYWluT2JqZWN0KGNvbmZpZ1RvQ29weVtrZXldKSAmJlxuICAgICAgICAhc2hhbGxvd0NvcHkuaW5jbHVkZXMoa2V5KSAmJlxuICAgICAgICAhbm90VG9Db3B5LmluY2x1ZGVzKGtleSlcbiAgICAgICkge1xuICAgICAgICAvLyByZWN1cnNpdmVseSBhc3NpZ24gb2JqZWN0IHZhbHVlXG4gICAgICAgIGNvcGllZFtrZXldID0gdGhpcy5jb3B5TGF5ZXJDb25maWcoY3VycmVudENvbmZpZ1trZXldLCBjb25maWdUb0NvcHlba2V5XSwge1xuICAgICAgICAgIHNoYWxsb3dDb3B5LFxuICAgICAgICAgIG5vdFRvQ29weVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobm90TnVsbG9yVW5kZWZpbmVkKGNvbmZpZ1RvQ29weVtrZXldKSAmJiAhbm90VG9Db3B5LmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgLy8gY29weVxuICAgICAgICBjb3BpZWRba2V5XSA9IGNvbmZpZ1RvQ29weVtrZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8ga2VlcCBleGlzdGluZ1xuICAgICAgICBjb3BpZWRba2V5XSA9IGN1cnJlbnRDb25maWdba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBjb3BpZWQ7XG4gIH1cblxuICByZWdpc3RlclZpc0NvbmZpZyhsYXllclZpc0NvbmZpZ3M6IHtcbiAgICBba2V5OiBzdHJpbmddOiBrZXlvZiBMYXllclZpc0NvbmZpZ1NldHRpbmdzIHwgVmFsdWVPZjxMYXllclZpc0NvbmZpZ1NldHRpbmdzPjtcbiAgfSkge1xuICAgIE9iamVjdC5rZXlzKGxheWVyVmlzQ29uZmlncykuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZ0l0ZW0gPSBsYXllclZpc0NvbmZpZ3NbaXRlbV07XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZ0l0ZW0gPT09ICdzdHJpbmcnICYmIExBWUVSX1ZJU19DT05GSUdTW2NvbmZpZ0l0ZW1dKSB7XG4gICAgICAgIC8vIGlmIGFzc2lnbmVkIG9uZSBvZiBkZWZhdWx0IExBWUVSX0NPTkZJR1NcbiAgICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnW2l0ZW1dID0gTEFZRVJfVklTX0NPTkZJR1NbY29uZmlnSXRlbV0uZGVmYXVsdFZhbHVlO1xuICAgICAgICB0aGlzLnZpc0NvbmZpZ1NldHRpbmdzW2l0ZW1dID0gTEFZRVJfVklTX0NPTkZJR1NbY29uZmlnSXRlbV07XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0eXBlb2YgY29uZmlnSXRlbSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgWyd0eXBlJywgJ2RlZmF1bHRWYWx1ZSddLmV2ZXJ5KHAgPT4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZ0l0ZW0sIHApKVxuICAgICAgKSB7XG4gICAgICAgIC8vIGlmIHByb3ZpZGVkIGN1c3RvbWl6ZWQgdmlzQ29uZmlnLCBhbmQgaGFzIHR5cGUgJiYgZGVmYXVsdFZhbHVlXG4gICAgICAgIC8vIFRPRE86IGZ1cnRoZXIgY2hlY2sgaWYgY3VzdG9taXplZCB2aXNDb25maWcgaXMgdmFsaWRcbiAgICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnW2l0ZW1dID0gY29uZmlnSXRlbS5kZWZhdWx0VmFsdWU7XG4gICAgICAgIHRoaXMudmlzQ29uZmlnU2V0dGluZ3NbaXRlbV0gPSBjb25maWdJdGVtO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0TGF5ZXJDb2x1bW5zKHByb3BzQ29sdW1ucyA9IHt9KSB7XG4gICAgY29uc3QgY29sdW1uVmFsaWRhdG9ycyA9IHRoaXMuY29sdW1uVmFsaWRhdG9ycyB8fCB7fTtcbiAgICBjb25zdCByZXF1aXJlZCA9IHRoaXMucmVxdWlyZWRMYXllckNvbHVtbnMucmVkdWNlKFxuICAgICAgKGFjY3UsIGtleSkgPT4gKHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgW2tleV06IGNvbHVtblZhbGlkYXRvcnNba2V5XVxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICB2YWx1ZTogcHJvcHNDb2x1bW5zW2tleV0/LnZhbHVlID8/IG51bGwsXG4gICAgICAgICAgICAgIGZpZWxkSWR4OiBwcm9wc0NvbHVtbnNba2V5XT8uZmllbGRJZHggPz8gLTEsXG4gICAgICAgICAgICAgIHZhbGlkYXRvcjogY29sdW1uVmFsaWRhdG9yc1trZXldXG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB7dmFsdWU6IHByb3BzQ29sdW1uc1trZXldPy52YWx1ZSA/PyBudWxsLCBmaWVsZElkeDogcHJvcHNDb2x1bW5zW2tleV0/LmZpZWxkSWR4ID8/IC0xfVxuICAgICAgfSksXG4gICAgICB7fVxuICAgICk7XG4gICAgY29uc3Qgb3B0aW9uYWwgPSB0aGlzLm9wdGlvbmFsQ29sdW1ucy5yZWR1Y2UoXG4gICAgICAoYWNjdSwga2V5KSA9PiAoe1xuICAgICAgICAuLi5hY2N1LFxuICAgICAgICBba2V5XToge1xuICAgICAgICAgIHZhbHVlOiBwcm9wc0NvbHVtbnNba2V5XT8udmFsdWUgPz8gbnVsbCxcbiAgICAgICAgICBmaWVsZElkeDogcHJvcHNDb2x1bW5zW2tleV0/LmZpZWxkSWR4ID8/IC0xLFxuICAgICAgICAgIG9wdGlvbmFsOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuXG4gICAgY29uc3QgY29sdW1ucyA9IHsuLi5yZXF1aXJlZCwgLi4ub3B0aW9uYWx9O1xuXG4gICAgcmV0dXJuIGNvbHVtbnM7XG4gIH1cblxuICB1cGRhdGVMYXllckNvbmZpZzxcbiAgICBMYXllckNvbmZpZyBleHRlbmRzIExheWVyQmFzZUNvbmZpZyAmXG4gICAgICBQYXJ0aWFsPExheWVyQ29sb3JDb25maWcgJiBMYXllclNpemVDb25maWc+ID0gTGF5ZXJCYXNlQ29uZmlnXG4gID4obmV3Q29uZmlnOiBQYXJ0aWFsPExheWVyQ29uZmlnPik6IExheWVyIHtcbiAgICB0aGlzLmNvbmZpZyA9IHsuLi50aGlzLmNvbmZpZywgLi4ubmV3Q29uZmlnfTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHVwZGF0ZUxheWVyVmlzQ29uZmlnKG5ld1Zpc0NvbmZpZykge1xuICAgIHRoaXMuY29uZmlnLnZpc0NvbmZpZyA9IHsuLi50aGlzLmNvbmZpZy52aXNDb25maWcsIC4uLm5ld1Zpc0NvbmZpZ307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB1cGRhdGVMYXllckNvbG9yVUkocHJvcDogc3RyaW5nLCBuZXdDb25maWc6IE5lc3RlZFBhcnRpYWw8Q29sb3JVST4pOiBMYXllciB7XG4gICAgY29uc3Qge2NvbG9yVUk6IHByZXZpb3VzLCB2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG5cbiAgICBpZiAoIWlzUGxhaW5PYmplY3QobmV3Q29uZmlnKSB8fCB0eXBlb2YgcHJvcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbG9yVUlQcm9wID0gT2JqZWN0LmVudHJpZXMobmV3Q29uZmlnKS5yZWR1Y2UoKGFjY3UsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgW2tleV06XG4gICAgICAgICAgaXNQbGFpbk9iamVjdChhY2N1W2tleV0pICYmIGlzUGxhaW5PYmplY3QodmFsdWUpXG4gICAgICAgICAgICA/IHsuLi5hY2N1W2tleV0sIC4uLih2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPil9XG4gICAgICAgICAgICA6IHZhbHVlXG4gICAgICB9O1xuICAgIH0sIHByZXZpb3VzW3Byb3BdIHx8IERFRkFVTFRfQ09MT1JfVUkpO1xuXG4gICAgY29uc3QgY29sb3JVSSA9IHtcbiAgICAgIC4uLnByZXZpb3VzLFxuICAgICAgW3Byb3BdOiBjb2xvclVJUHJvcFxuICAgIH07XG5cbiAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtjb2xvclVJfSk7XG4gICAgLy8gaWYgY29sb3JVSVtwcm9wXSBpcyBjb2xvclJhbmdlXG4gICAgY29uc3QgaXNDb2xvclJhbmdlID0gdmlzQ29uZmlnW3Byb3BdICYmIHZpc0NvbmZpZ1twcm9wXS5jb2xvcnM7XG5cbiAgICBpZiAoaXNDb2xvclJhbmdlKSB7XG4gICAgICAvLyBpZiBvcGVuIGRyb3Bkb3duIGFuZCBwcm9wIGlzIGNvbG9yIHJhbmdlXG4gICAgICAvLyBBdXRvbWF0aWNhbGx5IHNldCBjb2xvclJhbmdlQ29uZmlnJ3Mgc3RlcCBhbmQgcmV2ZXJzZWRcbiAgICAgIHRoaXMudXBkYXRlQ29sb3JVSUJ5Q29sb3JSYW5nZShuZXdDb25maWcsIHByb3ApO1xuXG4gICAgICAvLyBpZiBjaGFuZ2VzIGluIFVJIGlzIG1hZGUgdG8gJ3JldmVyc2VkJywgJ3N0ZXBzJyBvciBzdGVwc1xuICAgICAgLy8gdXBkYXRlIGN1cnJlbnQgbGF5ZXIgY29sb3JSYW5nZVxuICAgICAgdGhpcy51cGRhdGVDb2xvclJhbmdlQnlDb2xvclVJKG5ld0NvbmZpZywgcHJldmlvdXMsIHByb3ApO1xuXG4gICAgICAvLyBpZiBzZXQgY29sb3JSYW5nZUNvbmZpZyB0byBjdXN0b21cbiAgICAgIC8vIGluaXRpYXRlIGN1c3RvbVBhbGV0dGUgdG8gYmUgZWRpdGVkIGluIHRoZSB1aVxuICAgICAgdGhpcy51cGRhdGVDdXN0b21QYWxldHRlKG5ld0NvbmZpZywgcHJldmlvdXMsIHByb3ApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gaWYgc2V0IGNvbG9yUmFuZ2VDb25maWcgdG8gY3VzdG9tIHBhbGV0dGUgb3IgY3VzdG9tIGJyZWFrc1xuICAvLyBpbml0aWF0ZSBjdXN0b21QYWxldHRlIHRvIGJlIGVkaXRlZCBpbiB0aGUgdWlcbiAgdXBkYXRlQ3VzdG9tUGFsZXR0ZShuZXdDb25maWcsIHByZXZpb3VzLCBwcm9wKSB7XG4gICAgaWYgKCFuZXdDb25maWcuY29sb3JSYW5nZUNvbmZpZz8uY3VzdG9tICYmICFuZXdDb25maWcuY29sb3JSYW5nZUNvbmZpZz8uY3VzdG9tQnJlYWtzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG5ld0NvbmZpZy5jdXN0b21QYWxldHRlKSB7XG4gICAgICAvLyBpZiBuZXcgY29uZmlnIGFsc28gc2V0IGN1c3RvbVBhbGV0dGUsIG5vIG5lZWQgdG8gaW5pdGlhdGUgbmV3XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHtjb2xvclVJLCB2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG5cbiAgICBpZiAoIXZpc0NvbmZpZ1twcm9wXSkgcmV0dXJuO1xuICAgIC8vIG1ha2UgY29weSBvZiBjdXJyZW50IGNvbG9yIHJhbmdlIHRvIGN1c3RvbVBhbGV0dGVcbiAgICBsZXQgY3VzdG9tUGFsZXR0ZSA9IHtcbiAgICAgIC4uLnZpc0NvbmZpZ1twcm9wXVxuICAgIH07XG5cbiAgICBpZiAobmV3Q29uZmlnLmNvbG9yUmFuZ2VDb25maWcuY3VzdG9tQnJlYWtzICYmICFjdXN0b21QYWxldHRlLmNvbG9yTWFwKSB7XG4gICAgICAvLyBmaW5kIHZpc3VhbENoYW5lbFxuICAgICAgY29uc3QgdmlzdWFsQ2hhbm5lbHMgPSB0aGlzLnZpc3VhbENoYW5uZWxzO1xuICAgICAgY29uc3QgY2hhbm5lbEtleSA9IE9iamVjdC5rZXlzKHZpc3VhbENoYW5uZWxzKS5maW5kKFxuICAgICAgICBrZXkgPT4gdmlzdWFsQ2hhbm5lbHNba2V5XS5yYW5nZSA9PT0gcHJvcFxuICAgICAgKTtcbiAgICAgIGlmICghY2hhbm5lbEtleSkge1xuICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcG5cbiAgICAgICAgQ29uc29sZS53YXJuKGB1cGRhdGVDb2xvclVJOiBDYW4ndCBmaW5kIHZpc3VhbCBjaGFubmVsIHdoaWNoIHJhbmdlIGlzICR7cHJvcH1gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gYWRkIG5hbWV8dHlwZXxjYXRlZ29yeSB0byB1cGRhdGVDdXN0b21QYWxldHRlIGlmIGN1c3RvbUJyZWFrcywgc28gdGhhdFxuICAgICAgLy8gY29sb3JzIHdpbGwgbm90IGJlIG92ZXJyaWRlIGFzIHdlbGwgd2hlbiBpbnZlcnNlIHBhbGV0dGUgd2l0aCBjdXN0b20gYnJlYWtcbiAgICAgIC8vIGluaXRpYXRlIGNvbG9yTWFwIGZyb20gY3VycmVudCBzY2FsZVxuXG4gICAgICBjb25zdCBjb2xvck1hcCA9IGluaXRpYWxpemVMYXllckNvbG9yTWFwKHRoaXMsIHZpc3VhbENoYW5uZWxzW2NoYW5uZWxLZXldKTtcbiAgICAgIGN1c3RvbVBhbGV0dGUgPSBpbml0aWFsaXplQ3VzdG9tUGFsZXR0ZSh2aXNDb25maWdbcHJvcF0sIGNvbG9yTWFwKTtcbiAgICB9IGVsc2UgaWYgKG5ld0NvbmZpZy5jb2xvclJhbmdlQ29uZmlnLmN1c3RvbSkge1xuICAgICAgY3VzdG9tUGFsZXR0ZSA9IGluaXRpYWxpemVDdXN0b21QYWxldHRlKHZpc0NvbmZpZ1twcm9wXSk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVMYXllckNvbmZpZyh7XG4gICAgICBjb2xvclVJOiB7XG4gICAgICAgIC4uLmNvbG9yVUksXG4gICAgICAgIFtwcm9wXToge1xuICAgICAgICAgIC4uLmNvbG9yVUlbcHJvcF0sXG4gICAgICAgICAgY3VzdG9tUGFsZXR0ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaWYgb3BlbiBkcm9wZG93biBhbmQgcHJvcCBpcyBjb2xvciByYW5nZVxuICAgKiBBdXRvbWF0aWNhbGx5IHNldCBjb2xvclJhbmdlQ29uZmlnJ3Mgc3RlcCBhbmQgcmV2ZXJzZWRcbiAgICogQHBhcmFtIHsqfSBuZXdDb25maWdcbiAgICogQHBhcmFtIHsqfSBwcm9wXG4gICAqL1xuICB1cGRhdGVDb2xvclVJQnlDb2xvclJhbmdlKG5ld0NvbmZpZywgcHJvcCkge1xuICAgIGNvbnN0IHtjb2xvclVJLCB2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG5cbiAgICAvLyB3aGVuIGN1c3RvbSBwYWxldHRlIGFkZHMvcmVtb3ZlcyBzdGVwLCB0aGUgbnVtYmVyIGluIFwiU3RlcHNcIiBpbnB1dCBjb250cm9sXG4gICAgLy8gc2hvdWxkIGJlIHVwZGF0ZWQgYXMgd2VsbFxuICAgIGNvbnN0IGlzQ3VzdG9tID0gbmV3Q29uZmlnLmN1c3RvbVBhbGV0dGU/LmNhdGVnb3J5ID09PSAnQ3VzdG9tJztcbiAgICBjb25zdCBjdXN0b21TdGVwc0NoYW5nZWQgPSBpc0N1c3RvbVxuICAgICAgPyBuZXdDb25maWcuY3VzdG9tUGFsZXR0ZS5jb2xvcnMubGVuZ3RoICE9PSB2aXNDb25maWdbcHJvcF0uY29sb3JzLmxlbmd0aFxuICAgICAgOiBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgbmV3Q29uZmlnLnNob3dEcm9wZG93biAhPT0gJ251bWJlcicgJiYgIWN1c3RvbVN0ZXBzQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgdGhpcy51cGRhdGVMYXllckNvbmZpZyh7XG4gICAgICBjb2xvclVJOiB7XG4gICAgICAgIC4uLmNvbG9yVUksXG4gICAgICAgIFtwcm9wXToge1xuICAgICAgICAgIC4uLmNvbG9yVUlbcHJvcF0sXG4gICAgICAgICAgY29sb3JSYW5nZUNvbmZpZzoge1xuICAgICAgICAgICAgLi4uY29sb3JVSVtwcm9wXS5jb2xvclJhbmdlQ29uZmlnLFxuICAgICAgICAgICAgc3RlcHM6IGN1c3RvbVN0ZXBzQ2hhbmdlZFxuICAgICAgICAgICAgICA/IGNvbG9yVUlbcHJvcF0uY3VzdG9tUGFsZXR0ZS5jb2xvcnMubGVuZ3RoXG4gICAgICAgICAgICAgIDogdmlzQ29uZmlnW3Byb3BdLmNvbG9ycy5sZW5ndGgsXG4gICAgICAgICAgICByZXZlcnNlZDogQm9vbGVhbih2aXNDb25maWdbcHJvcF0ucmV2ZXJzZWQpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVDb2xvclJhbmdlQnlDb2xvclVJKG5ld0NvbmZpZywgcHJldmlvdXMsIHByb3ApIHtcbiAgICAvLyBvbmx5IHVwZGF0ZSBjb2xvclJhbmdlIGlmIGNoYW5nZXMgaW4gVUkgaXMgbWFkZSB0byAncmV2ZXJzZWQnLCAnc3RlcHMnIG9yIHN0ZXBzXG4gICAgY29uc3Qgc2hvdWxkVXBkYXRlID1cbiAgICAgIG5ld0NvbmZpZy5jb2xvclJhbmdlQ29uZmlnICYmXG4gICAgICBbJ3JldmVyc2VkJywgJ3N0ZXBzJywgJ2NvbG9yQmxpbmRTYWZlJywgJ3R5cGUnXS5zb21lKFxuICAgICAgICBrZXkgPT5cbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobmV3Q29uZmlnLmNvbG9yUmFuZ2VDb25maWcsIGtleSkgJiZcbiAgICAgICAgICBuZXdDb25maWcuY29sb3JSYW5nZUNvbmZpZ1trZXldICE9PVxuICAgICAgICAgICAgKHByZXZpb3VzW3Byb3BdIHx8IERFRkFVTFRfQ09MT1JfVUkpLmNvbG9yUmFuZ2VDb25maWdba2V5XVxuICAgICAgKTtcbiAgICBpZiAoIXNob3VsZFVwZGF0ZSkgcmV0dXJuO1xuXG4gICAgY29uc3Qge2NvbG9yVUksIHZpc0NvbmZpZ30gPSB0aGlzLmNvbmZpZztcblxuICAgIC8vIGZvciBjdXN0b20gcGFsZXR0ZSwgb25lIGNhbiBvbmx5ICdyZXZlcnNlJyB0aGUgY29sb3JzIGluIGN1c3RvbSBwYWxldHRlLlxuICAgIC8vIGNoYW5naW5nICdzdGVwcycsICdjb2xvckJpbmRTYWZlJywgJ3R5cGUnIHNob3VsZCBmYWxsIGJhY2sgdG8gcHJlZGVmaW5lZCBwYWxldHRlLlxuICAgIGNvbnN0IGlzQ3VzdG9tQ29sb3JSZXZlcnNlZCA9XG4gICAgICB2aXNDb25maWcuY29sb3JSYW5nZS5jYXRlZ29yeSA9PT0gJ0N1c3RvbScgJiZcbiAgICAgIG5ld0NvbmZpZy5jb2xvclJhbmdlQ29uZmlnICYmXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobmV3Q29uZmlnLmNvbG9yUmFuZ2VDb25maWcsICdyZXZlcnNlZCcpO1xuXG4gICAgY29uc3QgdXBkYXRlID0gaXNDdXN0b21Db2xvclJldmVyc2VkXG4gICAgICA/IHVwZGF0ZUN1c3RvbUNvbG9yUmFuZ2VCeUNvbG9yVUkodmlzQ29uZmlnW3Byb3BdLCBjb2xvclVJW3Byb3BdLmNvbG9yUmFuZ2VDb25maWcpXG4gICAgICA6IHVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZSh2aXNDb25maWdbcHJvcF0sIGNvbG9yVUlbcHJvcF0uY29sb3JSYW5nZUNvbmZpZyk7XG5cbiAgICBpZiAodXBkYXRlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyVmlzQ29uZmlnKHtbcHJvcF06IHVwZGF0ZX0pO1xuICAgIH1cbiAgfVxuICBoYXNDb2x1bW5WYWx1ZShjb2x1bW4/OiBMYXllckNvbHVtbikge1xuICAgIHJldHVybiBCb29sZWFuKGNvbHVtbiAmJiBjb2x1bW4udmFsdWUgJiYgY29sdW1uLmZpZWxkSWR4ID4gLTEpO1xuICB9XG4gIGhhc1JlcXVpcmVkQ29sdW1uKGNvbHVtbj86IExheWVyQ29sdW1uKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4oY29sdW1uICYmIChjb2x1bW4ub3B0aW9uYWwgfHwgdGhpcy5oYXNDb2x1bW5WYWx1ZShjb2x1bW4pKSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgbGF5ZXIgaGFzIGFsbCBjb2x1bW5zXG4gICAqIEByZXR1cm5zIHllcyBvciBub1xuICAgKi9cbiAgaGFzQWxsQ29sdW1ucygpOiBib29sZWFuIHtcbiAgICBjb25zdCB7Y29sdW1ucywgY29sdW1uTW9kZX0gPSB0aGlzLmNvbmZpZztcbiAgICAvLyBpZiBsYXllciBoYXMgZGlmZmVyZW50IGNvbHVtbiBtb2RlLCBjaGVjayBpZiBoYXZlIGFsbCByZXF1aXJlZCBjb2x1bW5zIG9mIGN1cnJlbnQgY29sdW1uIE1vZGVcbiAgICBpZiAoY29sdW1uTW9kZSkge1xuICAgICAgY29uc3QgY3VycmVudENvbHVtbk1vZGVzID0gKHRoaXMuc3VwcG9ydGVkQ29sdW1uTW9kZXMgfHwgW10pLmZpbmQoXG4gICAgICAgIGNvbE1vZGUgPT4gY29sTW9kZS5rZXkgPT09IGNvbHVtbk1vZGVcbiAgICAgICk7XG4gICAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgICAgY3VycmVudENvbHVtbk1vZGVzICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICBjdXJyZW50Q29sdW1uTW9kZXMucmVxdWlyZWRDb2x1bW5zPy5ldmVyeShjb2xLZXkgPT4gdGhpcy5oYXNDb2x1bW5WYWx1ZShjb2x1bW5zW2NvbEtleV0pKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIEJvb2xlYW4oXG4gICAgICBjb2x1bW5zICYmXG4gICAgICAgIE9iamVjdC52YWx1ZXMoY29sdW1ucykuZXZlcnkoKGNvbHVtbj86IExheWVyQ29sdW1uKSA9PiB0aGlzLmhhc1JlcXVpcmVkQ29sdW1uKGNvbHVtbikpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB3aGV0aGVyIGxheWVyIGhhcyBkYXRhXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXkgfCBPYmplY3R9IGxheWVyRGF0YVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0geWVzIG9yIG5vXG4gICAqL1xuICBoYXNMYXllckRhdGEobGF5ZXJEYXRhOiB7ZGF0YTogdW5rbm93bltdIHwgYXJyb3cuVGFibGV9KSB7XG4gICAgaWYgKCFsYXllckRhdGEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgIGxheWVyRGF0YS5kYXRhICYmXG4gICAgICAgICgobGF5ZXJEYXRhLmRhdGEgYXMgdW5rbm93bltdKS5sZW5ndGggfHwgKGxheWVyRGF0YS5kYXRhIGFzIGFycm93LlRhYmxlKS5udW1Sb3dzKVxuICAgICk7XG4gIH1cblxuICBpc1ZhbGlkVG9TYXZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMudHlwZSAmJiB0aGlzLmhhc0FsbENvbHVtbnMoKSk7XG4gIH1cblxuICBzaG91bGRSZW5kZXJMYXllcihkYXRhKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIEJvb2xlYW4odGhpcy50eXBlKSAmJlxuICAgICAgdGhpcy5oYXNBbGxDb2x1bW5zKCkgJiZcbiAgICAgIHRoaXMuaGFzTGF5ZXJEYXRhKGRhdGEpICYmXG4gICAgICB0eXBlb2YgdGhpcy5yZW5kZXJMYXllciA9PT0gJ2Z1bmN0aW9uJ1xuICAgICk7XG4gIH1cblxuICBnZXRDb2xvclNjYWxlKFxuICAgIGNvbG9yU2NhbGU6IHN0cmluZyxcbiAgICBjb2xvckRvbWFpbjogVmlzdWFsQ2hhbm5lbERvbWFpbixcbiAgICBjb2xvclJhbmdlOiBDb2xvclJhbmdlXG4gICk6IEdldFZpc0NoYW5uZWxTY2FsZVJldHVyblR5cGUge1xuICAgIGlmIChjb2xvclNjYWxlID09PSBTQ0FMRV9UWVBFUy5jdXN0b21PcmRpbmFsKSB7XG4gICAgICByZXR1cm4gZ2V0Q2F0ZWdvcmljYWxDb2xvclNjYWxlKGNvbG9yRG9tYWluLCBjb2xvclJhbmdlKTtcbiAgICB9XG5cbiAgICBpZiAoaGFzQ29sb3JNYXAoY29sb3JSYW5nZSkgJiYgY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMuY3VzdG9tKSB7XG4gICAgICBjb25zdCBjTWFwID0gbmV3IE1hcCgpO1xuICAgICAgY29sb3JSYW5nZS5jb2xvck1hcD8uZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICAgIGNNYXAuc2V0KGssIHR5cGVvZiB2ID09PSAnc3RyaW5nJyA/IGhleFRvUmdiKHYpIDogdik7XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NhbGVUeXBlID0gY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMuY3VzdG9tID8gY29sb3JTY2FsZSA6IFNDQUxFX1RZUEVTLm9yZGluYWw7XG5cbiAgICAgIGNvbnN0IHNjYWxlID0gZ2V0U2NhbGVGdW5jdGlvbihzY2FsZVR5cGUsIGNNYXAudmFsdWVzKCksIGNNYXAua2V5cygpLCBmYWxzZSk7XG4gICAgICBzY2FsZS51bmtub3duKGNNYXAuZ2V0KFVOS05PV05fQ09MT1JfS0VZKSB8fCBOT19WQUxVRV9DT0xPUik7XG5cbiAgICAgIHJldHVybiBzY2FsZSBhcyBHZXRWaXNDaGFubmVsU2NhbGVSZXR1cm5UeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5nZXRWaXNDaGFubmVsU2NhbGUoY29sb3JTY2FsZSwgY29sb3JEb21haW4sIGNvbG9yUmFuZ2UuY29sb3JzLm1hcChoZXhUb1JnYikpO1xuICB9XG5cbiAgYWNjZXNzVlNGaWVsZFZhbHVlKF9maWVsZCwgX2luZGV4S2V5KSB7XG4gICAgcmV0dXJuIGRlZmF1bHRHZXRGaWVsZFZhbHVlO1xuICB9XG4gIC8qKlxuICAgKiBNYXBwaW5nIGZyb20gdmlzdWFsIGNoYW5uZWxzIHRvIGRlY2suZ2wgYWNjZXNvcnNcbiAgICogQHBhcmFtIHBhcmFtIFBhcmFtZXRlcnNcbiAgICogQHBhcmFtIHBhcmFtLmRhdGFBY2Nlc3NvciBBY2Nlc3Mga2VwbGVyLmdsIGxheWVyIGRhdGEgZnJvbSBkZWNrLmdsIGxheWVyXG4gICAqIEBwYXJhbSBwYXJhbS5kYXRhQ29udGFpbmVyIERhdGFDb250YWluZXIgdG8gdXNlIHVzZSB3aXRoIGRhdGFBY2Nlc3NvclxuICAgKiBAcmV0dXJuIHtPYmplY3R9IGF0dHJpYnV0ZUFjY2Vzc29ycyAtIGRlY2suZ2wgbGF5ZXIgYXR0cmlidXRlIGFjY2Vzc29yc1xuICAgKi9cbiAgZ2V0QXR0cmlidXRlQWNjZXNzb3JzKHtcbiAgICBkYXRhQWNjZXNzb3IgPSBkZWZhdWx0RGF0YUFjY2Vzc29yLFxuICAgIGRhdGFDb250YWluZXIsXG4gICAgaW5kZXhLZXlcbiAgfToge1xuICAgIGRhdGFBY2Nlc3Nvcj86IHR5cGVvZiBkZWZhdWx0RGF0YUFjY2Vzc29yO1xuICAgIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2U7XG4gICAgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsO1xuICB9KSB7XG4gICAgY29uc3QgYXR0cmlidXRlQWNjZXNzb3JzOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuXG4gICAgT2JqZWN0LmtleXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZmllbGQsXG4gICAgICAgIGZpeGVkLFxuICAgICAgICBzY2FsZSxcbiAgICAgICAgZG9tYWluLFxuICAgICAgICByYW5nZSxcbiAgICAgICAgYWNjZXNzb3IsXG4gICAgICAgIGRlZmF1bHRWYWx1ZSxcbiAgICAgICAgZ2V0QXR0cmlidXRlVmFsdWUsXG4gICAgICAgIG51bGxWYWx1ZSxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZVxuICAgICAgfSA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG5cbiAgICAgIGlmIChhY2Nlc3Nvcikge1xuICAgICAgICBjb25zdCBzaG91bGRHZXRTY2FsZSA9IHRoaXMuY29uZmlnW2ZpZWxkXTtcblxuICAgICAgICBpZiAoc2hvdWxkR2V0U2NhbGUpIHtcbiAgICAgICAgICBjb25zdCBpc0ZpeGVkID0gZml4ZWQgJiYgdGhpcy5jb25maWcudmlzQ29uZmlnW2ZpeGVkXTtcblxuICAgICAgICAgIGNvbnN0IHNjYWxlRnVuY3Rpb24gPVxuICAgICAgICAgICAgY2hhbm5lbFNjYWxlVHlwZSA9PT0gQ0hBTk5FTF9TQ0FMRVMuY29sb3JcbiAgICAgICAgICAgICAgPyB0aGlzLmdldENvbG9yU2NhbGUoXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tzY2FsZV0sXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tkb21haW5dLFxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnW3JhbmdlXVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgOiB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnW3NjYWxlXSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnW2RvbWFpbl0sXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy52aXNDb25maWdbcmFuZ2VdLFxuICAgICAgICAgICAgICAgICAgaXNGaXhlZFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBnZXRGaWVsZFZhbHVlID0gdGhpcy5hY2Nlc3NWU0ZpZWxkVmFsdWUodGhpcy5jb25maWdbZmllbGRdLCBpbmRleEtleSk7XG5cbiAgICAgICAgICBpZiAoc2NhbGVGdW5jdGlvbikge1xuICAgICAgICAgICAgYXR0cmlidXRlQWNjZXNzb3JzW2FjY2Vzc29yXSA9IHNjYWxlRnVuY3Rpb24uYnlab29tXG4gICAgICAgICAgICAgID8gbWVtb2l6ZSh6ID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxlRnVuYyA9IHNjYWxlRnVuY3Rpb24oeik7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZCA9PlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoXG4gICAgICAgICAgICAgICAgICAgICAgc2NhbGVGdW5jLFxuICAgICAgICAgICAgICAgICAgICAgIGRhdGFBY2Nlc3NvcihkYXRhQ29udGFpbmVyKShkKSxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tmaWVsZF0sXG4gICAgICAgICAgICAgICAgICAgICAgbnVsbFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgIGdldEZpZWxkVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICA6IGQgPT5cbiAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShcbiAgICAgICAgICAgICAgICAgICAgc2NhbGVGdW5jdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGF0YUFjY2Vzc29yKGRhdGFDb250YWluZXIpKGQpLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tmaWVsZF0sXG4gICAgICAgICAgICAgICAgICAgIG51bGxWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRWYWx1ZVxuICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gc2V0IGdldEZpbGxDb2xvckJ5Wm9vbSB0byB0cnVlXG4gICAgICAgICAgICBpZiAoc2NhbGVGdW5jdGlvbi5ieVpvb20pIHtcbiAgICAgICAgICAgICAgYXR0cmlidXRlQWNjZXNzb3JzW2Ake2FjY2Vzc29yfUJ5Wm9vbWBdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGdldEF0dHJpYnV0ZVZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgYXR0cmlidXRlQWNjZXNzb3JzW2FjY2Vzc29yXSA9IGdldEF0dHJpYnV0ZVZhbHVlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhdHRyaWJ1dGVBY2Nlc3NvcnNbYWNjZXNzb3JdID1cbiAgICAgICAgICAgIHR5cGVvZiBkZWZhdWx0VmFsdWUgPT09ICdmdW5jdGlvbicgPyBkZWZhdWx0VmFsdWUodGhpcy5jb25maWcpIDogZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFhdHRyaWJ1dGVBY2Nlc3NvcnNbYWNjZXNzb3JdKSB7XG4gICAgICAgICAgQ29uc29sZS53YXJuKGBGYWlsZWQgdG8gcHJvdmlkZSBhY2Nlc3NvciBmdW5jdGlvbiBmb3IgJHthY2Nlc3NvciB8fCBjaGFubmVsfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXR0cmlidXRlQWNjZXNzb3JzO1xuICB9XG5cbiAgZ2V0VmlzQ2hhbm5lbFNjYWxlKFxuICAgIHNjYWxlOiBzdHJpbmcsXG4gICAgZG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluIHwgRG9tYWluUXVhbnRpbGVzLFxuICAgIHJhbmdlOiBhbnksXG4gICAgZml4ZWQ/OiBib29sZWFuXG4gICk6IEdldFZpc0NoYW5uZWxTY2FsZVJldHVyblR5cGUge1xuICAgIC8vIGlmIHF1YW50aWxlIGlzIHByb3ZpZGVkIHBlciB6b29tXG4gICAgaWYgKGlzRG9tYWluUXVhbnRpbGUoZG9tYWluKSAmJiBzY2FsZSA9PT0gU0NBTEVfVFlQRVMucXVhbnRpbGUpIHtcbiAgICAgIGNvbnN0IHpTdGVwcyA9IGRvbWFpbi56O1xuXG4gICAgICBjb25zdCBnZXRTY2FsZSA9IGZ1bmN0aW9uIGdldFNjYWxlQnlab29tKHopIHtcbiAgICAgICAgY29uc3Qgc2NhbGVEb21haW4gPSBnZXREb21haW5TdGVwc2J5Wm9vbShkb21haW4ucXVhbnRpbGVzLCB6U3RlcHMsIHopO1xuICAgICAgICBjb25zdCB0aHJlc2hvbGRzID0gZ2V0VGhyZXNob2xkc0Zyb21RdWFudGlsZXMoc2NhbGVEb21haW4sIHJhbmdlLmxlbmd0aCk7XG5cbiAgICAgICAgcmV0dXJuIGdldFNjYWxlRnVuY3Rpb24oJ3RocmVzaG9sZCcsIHJhbmdlLCB0aHJlc2hvbGRzLCBmYWxzZSk7XG4gICAgICB9O1xuXG4gICAgICBnZXRTY2FsZS5ieVpvb20gPSB0cnVlO1xuICAgICAgcmV0dXJuIGdldFNjYWxlO1xuICAgIH0gZWxzZSBpZiAoaXNEb21haW5TdG9wcyhkb21haW4pKSB7XG4gICAgICAvLyBjb2xvciBpcyBiYXNlZCBvbiB6b29tXG4gICAgICBjb25zdCB6U3RlcHMgPSBkb21haW4uejtcbiAgICAgIC8vIGdldCBzY2FsZSBmdW5jdGlvbiBieSB6XG4gICAgICAvLyB7XG4gICAgICAvLyAgejogW3osIHosIHpdLFxuICAgICAgLy8gIHN0b3BzOiBbW21pbiwgbWF4XSwgW21pbiwgbWF4XV0sXG4gICAgICAvLyAgaW50ZXJwb2xhdGlvbjogJ2ludGVycG9sYXRlJ1xuICAgICAgLy8gfVxuXG4gICAgICBjb25zdCBnZXRTY2FsZSA9IGZ1bmN0aW9uIGdldFNjYWxlQnlab29tKHopIHtcbiAgICAgICAgY29uc3Qgc2NhbGVEb21haW4gPSBnZXREb21haW5TdGVwc2J5Wm9vbShkb21haW4uc3RvcHMsIHpTdGVwcywgeik7XG5cbiAgICAgICAgcmV0dXJuIGdldFNjYWxlRnVuY3Rpb24oc2NhbGUsIHJhbmdlLCBzY2FsZURvbWFpbiwgZml4ZWQpO1xuICAgICAgfTtcblxuICAgICAgZ2V0U2NhbGUuYnlab29tID0gdHJ1ZTtcbiAgICAgIHJldHVybiBnZXRTY2FsZTtcbiAgICB9XG5cbiAgICByZXR1cm4gU0NBTEVfRlVOQ1tmaXhlZCA/ICdsaW5lYXInIDogc2NhbGVdKClcbiAgICAgIC5kb21haW4oZG9tYWluKVxuICAgICAgLnJhbmdlKGZpeGVkID8gZG9tYWluIDogcmFuZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBsb25naXR1ZGUgYW5kIGxhdGl0dWRlIGJvdW5kcyBvZiB0aGUgZGF0YS5cbiAgICovXG4gIGdldFBvaW50c0JvdW5kcyhcbiAgICBkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLFxuICAgIGdldFBvc2l0aW9uOiAoeDogYW55LCBkYzogRGF0YUNvbnRhaW5lckludGVyZmFjZSkgPT4gbnVtYmVyW10gPSBpZGVudGl0eVxuICApOiBudW1iZXJbXSB8IG51bGwge1xuICAgIC8vIG5vIG5lZWQgdG8gbG9vcCB0aHJvdWdoIHRoZSBlbnRpcmUgZGF0YXNldFxuICAgIC8vIGdldCBhIHNhbXBsZSBvZiBkYXRhIHRvIGNhbGN1bGF0ZSBib3VuZHNcbiAgICBjb25zdCBzYW1wbGVEYXRhID1cbiAgICAgIGRhdGFDb250YWluZXIubnVtUm93cygpID4gTUFYX1NBTVBMRV9TSVpFXG4gICAgICAgID8gZ2V0U2FtcGxlQ29udGFpbmVyRGF0YShkYXRhQ29udGFpbmVyLCBNQVhfU0FNUExFX1NJWkUpXG4gICAgICAgIDogZGF0YUNvbnRhaW5lcjtcblxuICAgIGNvbnN0IHBvaW50cyA9IGdldFBvc2l0aW9uID8gc2FtcGxlRGF0YS5tYXBJbmRleChnZXRQb3NpdGlvbikgOiBbXTtcblxuICAgIGNvbnN0IGxhdEJvdW5kcyA9IGdldExhdExuZ0JvdW5kcyhwb2ludHMsIDEsIFstOTAsIDkwXSk7XG4gICAgY29uc3QgbG5nQm91bmRzID0gZ2V0TGF0TG5nQm91bmRzKHBvaW50cywgMCwgWy0xODAsIDE4MF0pO1xuXG4gICAgaWYgKCFsYXRCb3VuZHMgfHwgIWxuZ0JvdW5kcykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtsbmdCb3VuZHNbMF0sIGxhdEJvdW5kc1swXSwgbG5nQm91bmRzWzFdLCBsYXRCb3VuZHNbMV1dO1xuICB9XG5cbiAgZ2V0Q2hhbmdlZFRyaWdnZXJzKGRhdGFVcGRhdGVUcmlnZ2Vycykge1xuICAgIGNvbnN0IHRyaWdnZXJDaGFuZ2VkID0gZGlmZlVwZGF0ZVRyaWdnZXJzKGRhdGFVcGRhdGVUcmlnZ2VycywgdGhpcy5fb2xkRGF0YVVwZGF0ZVRyaWdnZXJzKTtcbiAgICB0aGlzLl9vbGREYXRhVXBkYXRlVHJpZ2dlcnMgPSBkYXRhVXBkYXRlVHJpZ2dlcnM7XG5cbiAgICByZXR1cm4gdHJpZ2dlckNoYW5nZWQ7XG4gIH1cblxuICBnZXRFbmNvZGVkQ2hhbm5lbFZhbHVlKFxuICAgIHNjYWxlOiAodmFsdWUpID0+IGFueSxcbiAgICBkYXRhOiBhbnlbXSxcbiAgICBmaWVsZDogVmlzdWFsQ2hhbm5lbEZpZWxkLFxuICAgIG51bGxWYWx1ZSA9IE5PX1ZBTFVFX0NPTE9SLFxuICAgIGdldFZhbHVlID0gZGVmYXVsdEdldEZpZWxkVmFsdWVcbiAgKSB7XG4gICAgY29uc3QgdmFsdWUgPSBnZXRWYWx1ZShmaWVsZCwgZGF0YSk7XG5cbiAgICBpZiAoIW5vdE51bGxvclVuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBudWxsVmFsdWU7XG4gICAgfVxuXG4gICAgbGV0IGF0dHJpYnV0ZVZhbHVlO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgYXR0cmlidXRlVmFsdWUgPSB2YWx1ZS5tYXAoc2NhbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhdHRyaWJ1dGVWYWx1ZSA9IHNjYWxlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAoIW5vdE51bGxvclVuZGVmaW5lZChhdHRyaWJ1dGVWYWx1ZSkpIHtcbiAgICAgIGF0dHJpYnV0ZVZhbHVlID0gbnVsbFZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBhdHRyaWJ1dGVWYWx1ZTtcbiAgfVxuXG4gIHVwZGF0ZU1ldGEobWV0YTogTGF5ZXJbJ21ldGEnXSkge1xuICAgIHRoaXMubWV0YSA9IHsuLi50aGlzLm1ldGEsIC4uLm1ldGF9O1xuICB9XG5cbiAgZ2V0RGF0YVVwZGF0ZVRyaWdnZXJzKHtmaWx0ZXJlZEluZGV4LCBpZCwgZGF0YUNvbnRhaW5lcn06IEtlcGxlclRhYmxlKTogYW55IHtcbiAgICBjb25zdCB7Y29sdW1uc30gPSB0aGlzLmNvbmZpZztcblxuICAgIHJldHVybiB7XG4gICAgICBnZXREYXRhOiB7ZGF0YXNldElkOiBpZCwgZGF0YUNvbnRhaW5lciwgY29sdW1ucywgZmlsdGVyZWRJbmRleH0sXG4gICAgICBnZXRNZXRhOiB7ZGF0YXNldElkOiBpZCwgZGF0YUNvbnRhaW5lciwgY29sdW1uc30sXG4gICAgICAuLi4odGhpcy5jb25maWcudGV4dExhYmVsIHx8IFtdKS5yZWR1Y2UoXG4gICAgICAgIChhY2N1LCB0bCwgaSkgPT4gKHtcbiAgICAgICAgICAuLi5hY2N1LFxuICAgICAgICAgIFtgZ2V0TGFiZWxDaGFyYWN0ZXJTZXQtJHtpfWBdOiB0bC5maWVsZCA/IHRsLmZpZWxkLm5hbWUgOiBudWxsXG4gICAgICAgIH0pLFxuICAgICAgICB7fVxuICAgICAgKVxuICAgIH07XG4gIH1cblxuICB1cGRhdGVEYXRhKGRhdGFzZXRzOiBEYXRhc2V0cywgb2xkTGF5ZXJEYXRhOiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLmRhdGFJZCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBsYXllckRhdGFzZXQgPSBkYXRhc2V0c1t0aGlzLmNvbmZpZy5kYXRhSWRdO1xuICAgIGNvbnN0IHtkYXRhQ29udGFpbmVyfSA9IGxheWVyRGF0YXNldDtcblxuICAgIGNvbnN0IGdldFBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuICAgIGNvbnN0IGRhdGFVcGRhdGVUcmlnZ2VycyA9IHRoaXMuZ2V0RGF0YVVwZGF0ZVRyaWdnZXJzKGxheWVyRGF0YXNldCk7XG4gICAgY29uc3QgdHJpZ2dlckNoYW5nZWQgPSB0aGlzLmdldENoYW5nZWRUcmlnZ2VycyhkYXRhVXBkYXRlVHJpZ2dlcnMpO1xuXG4gICAgaWYgKHRyaWdnZXJDaGFuZ2VkICYmICh0cmlnZ2VyQ2hhbmdlZC5nZXRNZXRhIHx8IHRyaWdnZXJDaGFuZ2VkLmdldERhdGEpKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyTWV0YShsYXllckRhdGFzZXQsIGdldFBvc2l0aW9uKTtcblxuICAgICAgLy8gcmVzZXQgZmlsdGVyZWRJdGVtQ291bnRcbiAgICAgIHRoaXMuZmlsdGVyZWRJdGVtQ291bnQgPSB7fTtcbiAgICB9XG5cbiAgICBsZXQgZGF0YSA9IFtdO1xuXG4gICAgaWYgKCEodHJpZ2dlckNoYW5nZWQgJiYgdHJpZ2dlckNoYW5nZWQuZ2V0RGF0YSkgJiYgb2xkTGF5ZXJEYXRhICYmIG9sZExheWVyRGF0YS5kYXRhKSB7XG4gICAgICAvLyBzYW1lIGRhdGFcbiAgICAgIGRhdGEgPSBvbGRMYXllckRhdGEuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IHRoaXMuY2FsY3VsYXRlRGF0YUF0dHJpYnV0ZShsYXllckRhdGFzZXQsIGdldFBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2RhdGEsIHRyaWdnZXJDaGFuZ2VkfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBoZWxwZXIgZnVuY3Rpb24gdG8gdXBkYXRlIG9uZSBsYXllciBkb21haW4gd2hlbiBzdGF0ZS5kYXRhIGNoYW5nZWRcbiAgICogaWYgc3RhdGUuZGF0YSBjaGFuZ2UgaXMgZHVlIG90IHVwZGF0ZSBmaWx0ZXIsIG5ld0ZpbGVyIHdpbGwgYmUgcGFzc2VkXG4gICAqIGNhbGxlZCBieSB1cGRhdGVBbGxMYXllckRvbWFpbkRhdGFcbiAgICogQHBhcmFtIGRhdGFzZXRzXG4gICAqIEBwYXJhbSBuZXdGaWx0ZXJcbiAgICogQHJldHVybnMgbGF5ZXJcbiAgICovXG4gIHVwZGF0ZUxheWVyRG9tYWluKGRhdGFzZXRzOiBEYXRhc2V0cywgbmV3RmlsdGVyPzogRmlsdGVyKTogTGF5ZXIge1xuICAgIGNvbnN0IHRhYmxlID0gdGhpcy5nZXREYXRhc2V0KGRhdGFzZXRzKTtcbiAgICBpZiAoIXRhYmxlKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgT2JqZWN0LnZhbHVlcyh0aGlzLnZpc3VhbENoYW5uZWxzKS5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgY29uc3Qge3NjYWxlfSA9IGNoYW5uZWw7XG4gICAgICBjb25zdCBzY2FsZVR5cGUgPSB0aGlzLmNvbmZpZ1tzY2FsZV07XG4gICAgICAvLyBvcmRpbmFsIGRvbWFpbiBpcyBiYXNlZCBvbiBkYXRhQ29udGFpbmVyLCBpZiBvbmx5IGZpbHRlciBjaGFuZ2VkXG4gICAgICAvLyBubyBuZWVkIHRvIHVwZGF0ZSBvcmRpbmFsIGRvbWFpblxuICAgICAgaWYgKCFuZXdGaWx0ZXIgfHwgc2NhbGVUeXBlICE9PSBTQ0FMRV9UWVBFUy5vcmRpbmFsKSB7XG4gICAgICAgIGNvbnN0IHtkb21haW59ID0gY2hhbm5lbDtcbiAgICAgICAgY29uc3QgdXBkYXRlZERvbWFpbiA9IHRoaXMuY2FsY3VsYXRlTGF5ZXJEb21haW4odGFibGUsIGNoYW5uZWwpO1xuICAgICAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtbZG9tYWluXTogdXBkYXRlZERvbWFpbn0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXREYXRhc2V0KGRhdGFzZXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFJZCA/IGRhdGFzZXRzW3RoaXMuY29uZmlnLmRhdGFJZF0gOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHZpc3VhbCBjaGFubmVsIGZpZWxkIGFuZCBzY2FsZXMgYmFzZWQgb24gc3VwcG9ydGVkIGZpZWxkICYgc2NhbGUgdHlwZVxuICAgKiBAcGFyYW0gY2hhbm5lbFxuICAgKi9cbiAgdmFsaWRhdGVWaXN1YWxDaGFubmVsKGNoYW5uZWw6IHN0cmluZykge1xuICAgIHRoaXMudmFsaWRhdGVGaWVsZFR5cGUoY2hhbm5lbCk7XG4gICAgdGhpcy52YWxpZGF0ZVNjYWxlKGNoYW5uZWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGZpZWxkIHR5cGUgYmFzZWQgb24gY2hhbm5lbFNjYWxlVHlwZVxuICAgKi9cbiAgdmFsaWRhdGVGaWVsZFR5cGUoY2hhbm5lbDogc3RyaW5nKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge2ZpZWxkLCBjaGFubmVsU2NhbGVUeXBlLCBzdXBwb3J0ZWRGaWVsZFR5cGVzfSA9IHZpc3VhbENoYW5uZWw7XG5cbiAgICBpZiAodGhpcy5jb25maWdbZmllbGRdKSB7XG4gICAgICAvLyBpZiBmaWVsZCBpcyBzZWxlY3RlZCwgY2hlY2sgaWYgZmllbGQgdHlwZSBpcyBzdXBwb3J0ZWRcbiAgICAgIGNvbnN0IGNoYW5uZWxTdXBwb3J0ZWRGaWVsZFR5cGVzID1cbiAgICAgICAgc3VwcG9ydGVkRmllbGRUeXBlcyB8fCBDSEFOTkVMX1NDQUxFX1NVUFBPUlRFRF9GSUVMRFNbY2hhbm5lbFNjYWxlVHlwZV07XG5cbiAgICAgIGlmICghY2hhbm5lbFN1cHBvcnRlZEZpZWxkVHlwZXMuaW5jbHVkZXModGhpcy5jb25maWdbZmllbGRdLnR5cGUpKSB7XG4gICAgICAgIC8vIGZpZWxkIHR5cGUgaXMgbm90IHN1cHBvcnRlZCwgc2V0IGl0IGJhY2sgdG8gbnVsbFxuICAgICAgICAvLyBzZXQgc2NhbGUgYmFjayB0byBkZWZhdWx0XG4gICAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1tmaWVsZF06IG51bGx9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgc2NhbGUgdHlwZSBiYXNlZCBvbiBhZ2dyZWdhdGlvblxuICAgKi9cbiAgdmFsaWRhdGVTY2FsZShjaGFubmVsKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge3NjYWxlfSA9IHZpc3VhbENoYW5uZWw7XG4gICAgaWYgKCFzY2FsZSkge1xuICAgICAgLy8gdmlzdWFsQ2hhbm5lbCBkb2Vzbid0IGhhdmUgc2NhbGVcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2NhbGVPcHRpb25zID0gdGhpcy5nZXRTY2FsZU9wdGlvbnMoY2hhbm5lbCk7XG4gICAgLy8gY2hlY2sgaWYgY3VycmVudCBzZWxlY3RlZCBzY2FsZSBpc1xuICAgIC8vIHN1cHBvcnRlZCwgaWYgbm90LCBjaGFuZ2UgdG8gZGVmYXVsdFxuICAgIGlmICghc2NhbGVPcHRpb25zLmluY2x1ZGVzKHRoaXMuY29uZmlnW3NjYWxlXSkpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1tzY2FsZV06IHNjYWxlT3B0aW9uc1swXX0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2NhbGUgb3B0aW9ucyBiYXNlZCBvbiBjdXJyZW50IGZpZWxkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFubmVsXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX1cbiAgICovXG4gIGdldFNjYWxlT3B0aW9ucyhjaGFubmVsOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge2ZpZWxkLCBzY2FsZSwgY2hhbm5lbFNjYWxlVHlwZX0gPSB2aXN1YWxDaGFubmVsO1xuXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnW2ZpZWxkXVxuICAgICAgPyBGSUVMRF9PUFRTW3RoaXMuY29uZmlnW2ZpZWxkXS50eXBlXS5zY2FsZVtjaGFubmVsU2NhbGVUeXBlXVxuICAgICAgOiBbdGhpcy5nZXREZWZhdWx0TGF5ZXJDb25maWcoe2RhdGFJZDogJyd9KVtzY2FsZV1dO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXQ6IEtlcGxlclRhYmxlLCBjaGFubmVsOiBzdHJpbmcpIHtcbiAgICBjb25zdCB2aXN1YWxDaGFubmVsID0gdGhpcy52aXN1YWxDaGFubmVsc1tjaGFubmVsXTtcbiAgICB0aGlzLnZhbGlkYXRlVmlzdWFsQ2hhbm5lbChjaGFubmVsKTtcbiAgICAvLyBjYWxjdWxhdGUgbGF5ZXIgY2hhbm5lbCBkb21haW5cbiAgICBjb25zdCB1cGRhdGVkRG9tYWluID0gdGhpcy5jYWxjdWxhdGVMYXllckRvbWFpbihkYXRhc2V0LCB2aXN1YWxDaGFubmVsKTtcbiAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtbdmlzdWFsQ2hhbm5lbC5kb21haW5dOiB1cGRhdGVkRG9tYWlufSk7XG4gIH1cblxuICBnZXRWaXN1YWxDaGFubmVsVXBkYXRlVHJpZ2dlcnMoKTogVXBkYXRlVHJpZ2dlcnMge1xuICAgIGNvbnN0IHVwZGF0ZVRyaWdnZXJzOiBVcGRhdGVUcmlnZ2VycyA9IHt9O1xuICAgIE9iamVjdC52YWx1ZXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaCh2aXN1YWxDaGFubmVsID0+IHtcbiAgICAgIC8vIGZpZWxkIHJhbmdlIHNjYWxlIGRvbWFpblxuICAgICAgY29uc3Qge2FjY2Vzc29yLCBmaWVsZCwgc2NhbGUsIGRvbWFpbiwgcmFuZ2UsIGRlZmF1bHRWYWx1ZSwgZml4ZWR9ID0gdmlzdWFsQ2hhbm5lbDtcblxuICAgICAgaWYgKGFjY2Vzc29yKSB7XG4gICAgICAgIHVwZGF0ZVRyaWdnZXJzW2FjY2Vzc29yXSA9IHtcbiAgICAgICAgICBbZmllbGRdOiB0aGlzLmNvbmZpZ1tmaWVsZF0sXG4gICAgICAgICAgW3NjYWxlXTogdGhpcy5jb25maWdbc2NhbGVdLFxuICAgICAgICAgIFtkb21haW5dOiB0aGlzLmNvbmZpZ1tkb21haW5dLFxuICAgICAgICAgIFtyYW5nZV06IHRoaXMuY29uZmlnLnZpc0NvbmZpZ1tyYW5nZV0sXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOlxuICAgICAgICAgICAgdHlwZW9mIGRlZmF1bHRWYWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IGRlZmF1bHRWYWx1ZSh0aGlzLmNvbmZpZykgOiBkZWZhdWx0VmFsdWUsXG4gICAgICAgICAgLi4uKGZpeGVkID8ge1tmaXhlZF06IHRoaXMuY29uZmlnLnZpc0NvbmZpZ1tmaXhlZF19IDoge30pXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHVwZGF0ZVRyaWdnZXJzO1xuICB9XG5cbiAgY2FsY3VsYXRlTGF5ZXJEb21haW4oZGF0YXNldCwgdmlzdWFsQ2hhbm5lbCkge1xuICAgIGNvbnN0IHtzY2FsZX0gPSB2aXN1YWxDaGFubmVsO1xuICAgIGNvbnN0IHNjYWxlVHlwZSA9IHRoaXMuY29uZmlnW3NjYWxlXTtcblxuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5jb25maWdbdmlzdWFsQ2hhbm5lbC5maWVsZF07XG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgLy8gaWYgY29sb3JGaWVsZCBvciBzaXplRmllbGQgd2VyZSBzZXQgYmFjayB0byBudWxsXG4gICAgICByZXR1cm4gZGVmYXVsdERvbWFpbjtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YXNldC5nZXRDb2x1bW5MYXllckRvbWFpbihmaWVsZCwgc2NhbGVUeXBlKSB8fCBkZWZhdWx0RG9tYWluO1xuICB9XG5cbiAgaGFzSG92ZXJlZE9iamVjdChvYmplY3RJbmZvKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNMYXllckhvdmVyZWQob2JqZWN0SW5mbykgJiYgb2JqZWN0SW5mby5vYmplY3QgPyBvYmplY3RJbmZvLm9iamVjdCA6IG51bGw7XG4gIH1cblxuICBpc0xheWVySG92ZXJlZChvYmplY3RJbmZvKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIG9iamVjdEluZm8/LnBpY2tlZCAmJiBvYmplY3RJbmZvPy5sYXllcj8ucHJvcHM/LmlkID09PSB0aGlzLmlkO1xuICB9XG5cbiAgZ2V0UmFkaXVzU2NhbGVCeVpvb20obWFwU3RhdGU6IE1hcFN0YXRlLCBmaXhlZFJhZGl1cz86IGJvb2xlYW4pIHtcbiAgICBjb25zdCByYWRpdXNDaGFubmVsID0gT2JqZWN0LnZhbHVlcyh0aGlzLnZpc3VhbENoYW5uZWxzKS5maW5kKHZjID0+IHZjLnByb3BlcnR5ID09PSAncmFkaXVzJyk7XG5cbiAgICBpZiAoIXJhZGl1c0NoYW5uZWwpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGNvbnN0IGZpZWxkID0gcmFkaXVzQ2hhbm5lbC5maWVsZDtcbiAgICBjb25zdCBmaXhlZCA9IGZpeGVkUmFkaXVzID09PSB1bmRlZmluZWQgPyB0aGlzLmNvbmZpZy52aXNDb25maWcuZml4ZWRSYWRpdXMgOiBmaXhlZFJhZGl1cztcbiAgICBjb25zdCB7cmFkaXVzfSA9IHRoaXMuY29uZmlnLnZpc0NvbmZpZztcblxuICAgIHJldHVybiBmaXhlZCA/IDEgOiAodGhpcy5jb25maWdbZmllbGRdID8gMSA6IHJhZGl1cykgKiB0aGlzLmdldFpvb21GYWN0b3IobWFwU3RhdGUpO1xuICB9XG5cbiAgc2hvdWxkQ2FsY3VsYXRlTGF5ZXJEYXRhKHByb3BzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBwcm9wcy5zb21lKHAgPT4gIXRoaXMubm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzLmluY2x1ZGVzKHApKTtcbiAgfVxuXG4gIGdldEJydXNoaW5nRXh0ZW5zaW9uUHJvcHMoaW50ZXJhY3Rpb25Db25maWcsIGJydXNoaW5nVGFyZ2V0Pykge1xuICAgIGNvbnN0IHticnVzaH0gPSBpbnRlcmFjdGlvbkNvbmZpZztcblxuICAgIHJldHVybiB7XG4gICAgICAvLyBicnVzaGluZ1xuICAgICAgYXV0b0hpZ2hsaWdodDogIWJydXNoLmVuYWJsZWQsXG4gICAgICBicnVzaGluZ1JhZGl1czogYnJ1c2guY29uZmlnLnNpemUgKiAxMDAwLFxuICAgICAgYnJ1c2hpbmdUYXJnZXQ6IGJydXNoaW5nVGFyZ2V0IHx8ICdzb3VyY2UnLFxuICAgICAgYnJ1c2hpbmdFbmFibGVkOiBicnVzaC5lbmFibGVkXG4gICAgfTtcbiAgfVxuXG4gIGdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyh7XG4gICAgaWR4LFxuICAgIGdwdUZpbHRlcixcbiAgICBtYXBTdGF0ZSxcbiAgICBsYXllckNhbGxiYWNrcyxcbiAgICB2aXNpYmxlXG4gIH06IHtcbiAgICBpZHg6IG51bWJlcjtcbiAgICBncHVGaWx0ZXI6IEdwdUZpbHRlcjtcbiAgICBtYXBTdGF0ZTogTWFwU3RhdGU7XG4gICAgbGF5ZXJDYWxsYmFja3M6IGFueTtcbiAgICB2aXNpYmxlOiBib29sZWFuO1xuICB9KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgaWR4LFxuICAgICAgY29vcmRpbmF0ZVN5c3RlbTogQ09PUkRJTkFURV9TWVNURU0uTE5HTEFULFxuICAgICAgcGlja2FibGU6IHRydWUsXG4gICAgICB3cmFwTG9uZ2l0dWRlOiB0cnVlLFxuICAgICAgcGFyYW1ldGVyczoge2RlcHRoVGVzdDogQm9vbGVhbihtYXBTdGF0ZS5kcmFnUm90YXRlIHx8IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5lbmFibGUzZCl9LFxuICAgICAgaGlkZGVuOiB0aGlzLmNvbmZpZy5oaWRkZW4sXG4gICAgICAvLyB2aXNjb25maWdcbiAgICAgIG9wYWNpdHk6IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5vcGFjaXR5LFxuICAgICAgaGlnaGxpZ2h0Q29sb3I6IHRoaXMuY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgLy8gZGF0YSBmaWx0ZXJpbmdcbiAgICAgIGV4dGVuc2lvbnM6IFtkYXRhRmlsdGVyRXh0ZW5zaW9uXSxcbiAgICAgIGZpbHRlclJhbmdlOiBncHVGaWx0ZXIgPyBncHVGaWx0ZXIuZmlsdGVyUmFuZ2UgOiB1bmRlZmluZWQsXG4gICAgICBvbkZpbHRlcmVkSXRlbXNDaGFuZ2U6IGdwdUZpbHRlciA/IGxheWVyQ2FsbGJhY2tzPy5vbkZpbHRlcmVkSXRlbXNDaGFuZ2UgOiB1bmRlZmluZWQsXG5cbiAgICAgIC8vIGxheWVyIHNob3VsZCBiZSB2aXNpYmxlIGFuZCBpZiBzcGxpdE1hcCwgc2hvd24gaW4gdG8gb25lIG9mIHBhbmVsXG4gICAgICB2aXNpYmxlOiB0aGlzLmNvbmZpZy5pc1Zpc2libGUgJiYgdmlzaWJsZVxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0SG92ZXJMYXllclByb3BzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogYCR7dGhpcy5pZH0taG92ZXJlZGAsXG4gICAgICBwaWNrYWJsZTogZmFsc2UsXG4gICAgICB3cmFwTG9uZ2l0dWRlOiB0cnVlLFxuICAgICAgY29vcmRpbmF0ZVN5c3RlbTogQ09PUkRJTkFURV9TWVNURU0uTE5HTEFUXG4gICAgfTtcbiAgfVxuXG4gIHJlbmRlclRleHRMYWJlbExheWVyKFxuICAgIHtcbiAgICAgIGdldFBvc2l0aW9uLFxuICAgICAgZ2V0RmlsdGVyZWQsXG4gICAgICBnZXRQaXhlbE9mZnNldCxcbiAgICAgIGJhY2tncm91bmRQcm9wcyxcbiAgICAgIHVwZGF0ZVRyaWdnZXJzLFxuICAgICAgc2hhcmVkUHJvcHNcbiAgICB9OiB7XG4gICAgICBnZXRQb3NpdGlvbj86ICgoZDogYW55KSA9PiBudW1iZXJbXSkgfCBhcnJvdy5WZWN0b3I7XG4gICAgICBnZXRGaWx0ZXJlZD86IChkYXRhOiB7aW5kZXg6IG51bWJlcn0sIG9iamVjdEluZm86IHtpbmRleDogbnVtYmVyfSkgPT4gbnVtYmVyO1xuICAgICAgZ2V0UGl4ZWxPZmZzZXQ6ICh0ZXh0TGFiZWw6IGFueSkgPT4gbnVtYmVyW10gfCAoKGQ6IGFueSkgPT4gbnVtYmVyW10pO1xuICAgICAgYmFja2dyb3VuZFByb3BzPzoge2JhY2tncm91bmQ6IGJvb2xlYW59O1xuICAgICAgdXBkYXRlVHJpZ2dlcnM6IHtcbiAgICAgICAgW2tleTogc3RyaW5nXTogYW55O1xuICAgICAgfTtcbiAgICAgIHNoYXJlZFByb3BzOiBhbnk7XG4gICAgfSxcbiAgICByZW5kZXJPcHRzXG4gICkge1xuICAgIGNvbnN0IHtkYXRhLCBtYXBTdGF0ZX0gPSByZW5kZXJPcHRzO1xuICAgIGNvbnN0IHt0ZXh0TGFiZWx9ID0gdGhpcy5jb25maWc7XG5cbiAgICBjb25zdCBUZXh0TGF5ZXJDbGFzcyA9IGRhdGEuZGF0YSBpbnN0YW5jZW9mIGFycm93LlRhYmxlID8gR2VvQXJyb3dUZXh0TGF5ZXIgOiBUZXh0TGF5ZXI7XG5cbiAgICByZXR1cm4gZGF0YS50ZXh0TGFiZWxzLnJlZHVjZSgoYWNjdSwgZCwgaSkgPT4ge1xuICAgICAgaWYgKGQuZ2V0VGV4dCkge1xuICAgICAgICBjb25zdCBiYWNrZ3JvdW5kID0gdGV4dExhYmVsW2ldLmJhY2tncm91bmQgfHwgYmFja2dyb3VuZFByb3BzPy5iYWNrZ3JvdW5kO1xuXG4gICAgICAgIGFjY3UucHVzaChcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgbmV3IFRleHRMYXllckNsYXNzKHtcbiAgICAgICAgICAgIC4uLnNoYXJlZFByb3BzLFxuICAgICAgICAgICAgaWQ6IGAke3RoaXMuaWR9LWxhYmVsLSR7dGV4dExhYmVsW2ldLmZpZWxkPy5uYW1lfWAsXG4gICAgICAgICAgICBkYXRhOiBkYXRhLmRhdGEsXG4gICAgICAgICAgICB2aXNpYmxlOiB0aGlzLmNvbmZpZy5pc1Zpc2libGUsXG4gICAgICAgICAgICBnZXRUZXh0OiBkLmdldFRleHQsXG4gICAgICAgICAgICBnZXRQb3NpdGlvbixcbiAgICAgICAgICAgIGdldEZpbHRlcmVkLFxuICAgICAgICAgICAgY2hhcmFjdGVyU2V0OiBkLmNoYXJhY3RlclNldCxcbiAgICAgICAgICAgIGdldFBpeGVsT2Zmc2V0OiBnZXRQaXhlbE9mZnNldCh0ZXh0TGFiZWxbaV0pLFxuICAgICAgICAgICAgZ2V0U2l6ZTogUFJPSkVDVEVEX1BJWEVMX1NJWkVfTVVMVElQTElFUixcbiAgICAgICAgICAgIHNpemVTY2FsZTogdGV4dExhYmVsW2ldLnNpemUsXG4gICAgICAgICAgICBnZXRUZXh0QW5jaG9yOiB0ZXh0TGFiZWxbaV0uYW5jaG9yLFxuICAgICAgICAgICAgZ2V0QWxpZ25tZW50QmFzZWxpbmU6IHRleHRMYWJlbFtpXS5hbGlnbm1lbnQsXG4gICAgICAgICAgICBnZXRDb2xvcjogdGV4dExhYmVsW2ldLmNvbG9yLFxuICAgICAgICAgICAgb3V0bGluZVdpZHRoOiB0ZXh0TGFiZWxbaV0ub3V0bGluZVdpZHRoICogVEVYVF9PVVRMSU5FX01VTFRJUExJRVIsXG4gICAgICAgICAgICBvdXRsaW5lQ29sb3I6IHRleHRMYWJlbFtpXS5vdXRsaW5lQ29sb3IsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgICAgZ2V0QmFja2dyb3VuZENvbG9yOiB0ZXh0TGFiZWxbaV0uYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgZm9udFNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIHNkZjogdGV4dExhYmVsW2ldLm91dGxpbmVXaWR0aCA+IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIC8vIHRleHQgd2lsbCBhbHdheXMgc2hvdyBvbiB0b3Agb2YgYWxsIGxheWVyc1xuICAgICAgICAgICAgICBkZXB0aFRlc3Q6IGZhbHNlXG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBnZXRGaWx0ZXJWYWx1ZTogZGF0YS5nZXRGaWx0ZXJWYWx1ZSxcbiAgICAgICAgICAgIHVwZGF0ZVRyaWdnZXJzOiB7XG4gICAgICAgICAgICAgIC4uLnVwZGF0ZVRyaWdnZXJzLFxuICAgICAgICAgICAgICBnZXRUZXh0OiB0ZXh0TGFiZWxbaV0uZmllbGQ/Lm5hbWUsXG4gICAgICAgICAgICAgIGdldFBpeGVsT2Zmc2V0OiB7XG4gICAgICAgICAgICAgICAgLi4udXBkYXRlVHJpZ2dlcnMuZ2V0UmFkaXVzLFxuICAgICAgICAgICAgICAgIG1hcFN0YXRlLFxuICAgICAgICAgICAgICAgIGFuY2hvcjogdGV4dExhYmVsW2ldLmFuY2hvcixcbiAgICAgICAgICAgICAgICBhbGlnbm1lbnQ6IHRleHRMYWJlbFtpXS5hbGlnbm1lbnRcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZ2V0VGV4dEFuY2hvcjogdGV4dExhYmVsW2ldLmFuY2hvcixcbiAgICAgICAgICAgICAgZ2V0QWxpZ25tZW50QmFzZWxpbmU6IHRleHRMYWJlbFtpXS5hbGlnbm1lbnQsXG4gICAgICAgICAgICAgIGdldENvbG9yOiB0ZXh0TGFiZWxbaV0uY29sb3JcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfc3ViTGF5ZXJQcm9wczoge1xuICAgICAgICAgICAgICAuLi4oYmFja2dyb3VuZFxuICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiB7XG4gICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VsbDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IG51bGwpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1O1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgY2FsY3VsYXRlRGF0YUF0dHJpYnV0ZShrZXBsZXJUYWJsZTogS2VwbGVyVGFibGUsIGdldFBvc2l0aW9uKTogYW55IHtcbiAgICAvLyBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzc2VzXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICB1cGRhdGVMYXllck1ldGEoZGF0YXNldDogS2VwbGVyVGFibGUsIGdldFBvc2l0aW9uKSB7XG4gICAgLy8gaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3Nlc1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBnZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXI/OiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKTogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkge1xuICAgIC8vIGltcGxlbWVudGVkIGluIHN1YmNsYXNzZXNcbiAgICByZXR1cm4gKCkgPT4gbnVsbDtcbiAgfVxuXG4gIGdldExlZ2VuZFZpc3VhbENoYW5uZWxzKCk6IHtba2V5OiBzdHJpbmddOiBWaXN1YWxDaGFubmVsfSB7XG4gICAgcmV0dXJuIHRoaXMudmlzdWFsQ2hhbm5lbHM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTGF5ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxLQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxrQkFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsV0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssVUFBQSxHQUFBQyxzQkFBQSxDQUFBTixPQUFBO0FBRUEsSUFBQU8sS0FBQSxHQUFBQyx1QkFBQSxDQUFBUixPQUFBO0FBQ0EsSUFBQVMsaUJBQUEsR0FBQUgsc0JBQUEsQ0FBQU4sT0FBQTtBQUNBLElBQUFVLFlBQUEsR0FBQVYsT0FBQTtBQUNBLElBQUFXLFdBQUEsR0FBQVgsT0FBQTtBQUVBLElBQUFZLFVBQUEsR0FBQVosT0FBQTtBQWtCQSxJQUFBYSxNQUFBLEdBQUFiLE9BQUE7QUFZQSxJQUFBYyxZQUFBLEdBQUFkLE9BQUE7QUFtQ0EsSUFBQWUsT0FBQSxHQUFBVCxzQkFBQSxDQUFBTixPQUFBO0FBQXFDLElBQUFnQixxQkFBQSxFQWhGckM7QUFDQTtBQUFBLFNBQUFDLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLHlCQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBVix3QkFBQVUsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLGdCQUFBSyxRQUFBLENBQUFMLENBQUEsMEJBQUFBLENBQUEsc0JBQUFBLENBQUEsUUFBQUcsQ0FBQSxHQUFBSix3QkFBQSxDQUFBRyxD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