kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
390 lines (385 loc) • 54.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pointVisConfigs = exports.iconRequiredColumns = exports.iconPosAccessor = exports.iconOptionalColumns = exports.iconAccessor = exports["default"] = exports.SVG_ICON_URL = void 0;
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 _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _window = _interopRequireDefault(require("global/window"));
var _extensions = require("@deck.gl/extensions");
var _constants = _interopRequireDefault(require("@luma.gl/constants"));
var _deckglLayers = require("@kepler.gl/deckgl-layers");
var _iconLayerIcon = _interopRequireDefault(require("./icon-layer-icon"));
var _constants2 = require("@kepler.gl/constants");
var _iconInfoModal = _interopRequireDefault(require("./icon-info-modal"));
var _baseLayer = _interopRequireDefault(require("../base-layer"));
var _layerUtils = require("../layer-utils");
var _utils = require("@kepler.gl/utils");
var _layerTextLabel = require("../layer-text-label");
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; }
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _superPropGet(t, e, r, o) { var p = (0, _get2["default"])((0, _getPrototypeOf2["default"])(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
var brushingExtension = new _extensions.BrushingExtension();
var SVG_ICON_URL = exports.SVG_ICON_URL = "".concat(_constants2.KEPLER_UNFOLDED_BUCKET, "/icons/svg-icons.json");
var iconPosAccessor = exports.iconPosAccessor = function iconPosAccessor(_ref) {
var lat = _ref.lat,
lng = _ref.lng,
altitude = _ref.altitude;
return function (dc) {
return function (d) {
return [dc.valueAt(d.index, lng.fieldIdx), dc.valueAt(d.index, lat.fieldIdx), (altitude === null || altitude === void 0 ? void 0 : altitude.fieldIdx) > -1 ? dc.valueAt(d.index, altitude.fieldIdx) : 0];
};
};
};
var iconAccessor = exports.iconAccessor = function iconAccessor(_ref2) {
var icon = _ref2.icon;
return function (dc) {
return function (d) {
return dc.valueAt(d.index, icon.fieldIdx);
};
};
};
var iconRequiredColumns = exports.iconRequiredColumns = ['lat', 'lng', 'icon'];
var iconOptionalColumns = exports.iconOptionalColumns = ['altitude'];
var pointVisConfigs = exports.pointVisConfigs = {
radius: 'radius',
fixedRadius: 'fixedRadius',
opacity: 'opacity',
colorRange: 'colorRange',
radiusRange: 'radiusRange',
billboard: 'billboard'
};
function flatterIconPositions(icon) {
// had to flip y, since @luma modal has changed
return icon.mesh.cells.reduce(function (prev, cell) {
cell.forEach(function (p) {
prev.push.apply(prev, [icon.mesh.positions[p][0], -icon.mesh.positions[p][1], icon.mesh.positions[p][2]]);
});
return prev;
}, []);
}
var IconLayer = exports["default"] = /*#__PURE__*/function (_Layer) {
function IconLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, IconLayer);
_this = _callSuper(this, IconLayer, [props]);
(0, _defineProperty2["default"])(_this, "getIconAccessor", void 0);
(0, _defineProperty2["default"])(_this, "_layerInfoModal", void 0);
(0, _defineProperty2["default"])(_this, "iconGeometry", void 0);
_this.registerVisConfig(pointVisConfigs);
_this.getPositionAccessor = function (dataContainer) {
return iconPosAccessor(_this.config.columns)(dataContainer);
};
_this.getIconAccessor = function (dataContainer) {
return iconAccessor(_this.config.columns)(dataContainer);
};
_this._layerInfoModal = (0, _iconInfoModal["default"])(props.svgIcons);
_this.iconGeometry = props.iconGeometry || null;
if ((0, _utils.isTest)()) {
return (0, _possibleConstructorReturn2["default"])(_this);
}
if (props.svgIcons) {
// if svg icons are passed in then bypass fetching of remote svg icons
_this.setSvgIcons(props.svgIcons);
} else {
// prepare layer info modal and fetch remote svg icons
_this.getSvgIcons();
}
return _this;
}
(0, _inherits2["default"])(IconLayer, _Layer);
return (0, _createClass2["default"])(IconLayer, [{
key: "svgIconUrl",
get: function get() {
return SVG_ICON_URL;
}
}, {
key: "type",
get: function get() {
return 'icon';
}
}, {
key: "requiredLayerColumns",
get: function get() {
return iconRequiredColumns;
}
}, {
key: "optionalColumns",
get: function get() {
return iconOptionalColumns;
}
}, {
key: "columnPairs",
get: function get() {
return this.defaultPointColumnPairs;
}
}, {
key: "layerIcon",
get: function get() {
return _iconLayerIcon["default"];
}
}, {
key: "visualChannels",
get: function get() {
return {
color: _objectSpread(_objectSpread({}, _superPropGet(IconLayer, "visualChannels", this, 1).color), {}, {
accessor: 'getFillColor',
defaultValue: function defaultValue(config) {
return config.color;
}
}),
size: _objectSpread(_objectSpread({}, _superPropGet(IconLayer, "visualChannels", this, 1).size), {}, {
property: 'radius',
range: 'radiusRange',
channelScaleType: 'radius',
accessor: 'getRadius',
defaultValue: 1
})
};
}
}, {
key: "layerInfoModal",
get: function get() {
return {
id: 'iconInfo',
template: this._layerInfoModal,
modalProps: {
title: 'modal.iconInfo.title'
}
};
}
}, {
key: "getZoomFactor",
value: function getZoomFactor(_ref3) {
var zoom = _ref3.zoom,
_ref3$zoomOffset = _ref3.zoomOffset,
zoomOffset = _ref3$zoomOffset === void 0 ? 0 : _ref3$zoomOffset;
return Math.pow(2, 14 - zoom + zoomOffset);
}
}, {
key: "getSvgIcons",
value: function getSvgIcons() {
var _this2 = this;
var fetchConfig = {
method: 'GET',
mode: 'cors',
cache: 'no-cache'
};
if (_window["default"].fetch && this.svgIconUrl) {
_window["default"].fetch(this.svgIconUrl, fetchConfig).then(function (response) {
return response.json();
}).then(function () {
var parsed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_this2.setSvgIcons(parsed.svgIcons);
});
}
}
}, {
key: "setSvgIcons",
value: function setSvgIcons() {
var svgIcons = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
this.iconGeometry = svgIcons.reduce(function (accu, curr) {
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, curr.id, flatterIconPositions(curr)));
}, {});
this._layerInfoModal = (0, _iconInfoModal["default"])(svgIcons);
}
}, {
key: "getFilteredItemCount",
value: function getFilteredItemCount() {
// use total
if (Object.keys(this.filteredItemCount).length) {
return Object.values(this.filteredItemCount).reduce(function (total, curr) {
return Number.isFinite(curr) ? total + curr : total;
}, 0);
}
return null;
}
}, {
key: "calculateDataAttribute",
value: function calculateDataAttribute(_ref4, getPosition) {
var dataContainer = _ref4.dataContainer,
filteredIndex = _ref4.filteredIndex;
var getIcon = this.getIconAccessor(dataContainer);
var data = [];
for (var i = 0; i < filteredIndex.length; i++) {
var index = filteredIndex[i];
var rowIndex = {
index: index
};
var pos = getPosition(rowIndex);
var icon = getIcon(rowIndex);
// if doesn't have point lat or lng, do not add the point
// deck.gl can't handle position = null
if (pos.every(Number.isFinite) && typeof icon === 'string') {
data.push({
index: index,
icon: icon
});
}
}
return data;
}
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData) {
if (this.config.dataId === null) {
return {};
}
var textLabel = this.config.textLabel;
var _datasets$this$config = datasets[this.config.dataId],
gpuFilter = _datasets$this$config.gpuFilter,
dataContainer = _datasets$this$config.dataContainer;
var getPosition = this.getPositionAccessor(dataContainer);
var _this$updateData = this.updateData(datasets, oldLayerData),
data = _this$updateData.data,
triggerChanged = _this$updateData.triggerChanged;
// get all distinct characters in the text labels
var textLabels = (0, _layerTextLabel.formatTextLabelData)({
textLabel: textLabel,
triggerChanged: triggerChanged,
oldLayerData: oldLayerData,
data: data,
dataContainer: dataContainer
});
var accessors = this.getAttributeAccessors({
dataContainer: dataContainer
});
return _objectSpread({
data: data,
getPosition: getPosition,
getFilterValue: gpuFilter.filterValueAccessor(dataContainer)(),
textLabels: textLabels
}, accessors);
}
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(dataset, getPosition) {
var dataContainer = dataset.dataContainer;
var bounds = this.getPointsBounds(dataContainer, getPosition);
this.updateMeta({
bounds: bounds
});
}
}, {
key: "renderLayer",
value: function renderLayer(opts) {
var _this$config$columns$,
_this3 = this;
var data = opts.data,
gpuFilter = opts.gpuFilter,
objectHovered = opts.objectHovered,
mapState = opts.mapState,
interactionConfig = opts.interactionConfig;
var radiusScale = this.getRadiusScaleByZoom(mapState);
var layerProps = _objectSpread({
radiusScale: radiusScale,
billboard: this.config.visConfig.billboard
}, this.config.visConfig.fixedRadius ? {} : {
radiusMaxPixels: 500
});
var updateTriggers = _objectSpread({
getPosition: this.config.columns,
getFilterValue: gpuFilter.filterValueUpdateTriggers
}, this.getVisualChannelUpdateTriggers());
var defaultLayerProps = this.getDefaultDeckLayerProps(opts);
var brushingProps = this.getBrushingExtensionProps(interactionConfig);
var getPixelOffset = (0, _layerTextLabel.getTextOffsetByRadius)(radiusScale, data.getRadius, mapState);
var extensions = [].concat((0, _toConsumableArray2["default"])(defaultLayerProps.extensions), [brushingExtension]);
// shared Props between layer and label layer
var sharedProps = _objectSpread({
getFilterValue: data.getFilterValue,
extensions: extensions,
filterRange: defaultLayerProps.filterRange
}, brushingProps);
var labelLayers = (0, _toConsumableArray2["default"])(this.renderTextLabelLayer({
getPosition: data.getPosition,
sharedProps: sharedProps,
getPixelOffset: getPixelOffset,
updateTriggers: updateTriggers
}, opts));
var hoveredObject = this.hasHoveredObject(objectHovered);
var parameters = {
// icons will be flat on the map when the altitude column is not used
depthTest: ((_this$config$columns$ = this.config.columns.altitude) === null || _this$config$columns$ === void 0 ? void 0 : _this$config$columns$.fieldIdx) > -1,
cullFace: _constants["default"].FRONT
};
return !this.iconGeometry ? [] : [new _deckglLayers.SvgIconLayer(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultLayerProps), brushingProps), layerProps), data), {}, {
parameters: parameters,
getIconGeometry: function getIconGeometry(id) {
var _this3$iconGeometry;
return (_this3$iconGeometry = _this3.iconGeometry) === null || _this3$iconGeometry === void 0 ? void 0 : _this3$iconGeometry[id];
},
// update triggers
updateTriggers: updateTriggers,
extensions: extensions
}))].concat((0, _toConsumableArray2["default"])(hoveredObject ? [
// @ts-expect-error SvgIconLayerProps needs getIcon Field
new _deckglLayers.SvgIconLayer(_objectSpread(_objectSpread(_objectSpread({}, this.getDefaultHoverLayerProps()), layerProps), {}, {
visible: defaultLayerProps.visible,
data: [hoveredObject],
parameters: parameters,
getPosition: data.getPosition,
getRadius: data.getRadius,
getFillColor: this.config.highlightColor,
getIconGeometry: function getIconGeometry(id) {
var _this3$iconGeometry2;
return (_this3$iconGeometry2 = _this3.iconGeometry) === null || _this3$iconGeometry2 === void 0 ? void 0 : _this3$iconGeometry2[id];
}
}))] : []), (0, _toConsumableArray2["default"])(labelLayers));
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(_ref5) {
var _ref5$fieldPairs = _ref5.fieldPairs,
fieldPairs = _ref5$fieldPairs === void 0 ? [] : _ref5$fieldPairs,
_ref5$fields = _ref5.fields,
fields = _ref5$fields === void 0 ? [] : _ref5$fields;
var notFound = {
props: []
};
if (!fieldPairs.length || !fields.length) {
return notFound;
}
var iconFields = fields.filter(function (_ref6) {
var name = _ref6.name;
return name.replace(/[_,.]+/g, ' ').trim().split(' ').some(function (seg) {
return _constants2.ICON_FIELDS.icon.some(function (t) {
return t.includes(seg);
});
});
});
if (!iconFields.length) {
return notFound;
}
// create icon layers for first point pair
var ptPair = fieldPairs[0];
var columns = (0, _layerUtils.assignPointPairToLayerColumn)(ptPair, true);
var props = iconFields.map(function (iconField) {
return {
label: iconField.name.replace(/[_,.]+/g, ' ').trim(),
columns: _objectSpread(_objectSpread({}, columns), {}, {
icon: {
value: iconField.name,
fieldIdx: iconField.fieldIdx
}
}),
isVisible: true
};
});
return {
props: props
};
}
}]);
}(_baseLayer["default"]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfd2luZG93IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZXh0ZW5zaW9ucyIsIl9jb25zdGFudHMiLCJfZGVja2dsTGF5ZXJzIiwiX2ljb25MYXllckljb24iLCJfY29uc3RhbnRzMiIsIl9pY29uSW5mb01vZGFsIiwiX2Jhc2VMYXllciIsIl9sYXllclV0aWxzIiwiX3V0aWxzIiwiX2xheWVyVGV4dExhYmVsIiwib3duS2V5cyIsImUiLCJyIiwidCIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJfY2FsbFN1cGVyIiwiX2dldFByb3RvdHlwZU9mMiIsIl9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMiIsIl9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QiLCJSZWZsZWN0IiwiY29uc3RydWN0IiwiY29uc3RydWN0b3IiLCJCb29sZWFuIiwicHJvdG90eXBlIiwidmFsdWVPZiIsImNhbGwiLCJfc3VwZXJQcm9wR2V0IiwicCIsIl9nZXQyIiwiYnJ1c2hpbmdFeHRlbnNpb24iLCJCcnVzaGluZ0V4dGVuc2lvbiIsIlNWR19JQ09OX1VSTCIsImV4cG9ydHMiLCJjb25jYXQiLCJLRVBMRVJfVU5GT0xERURfQlVDS0VUIiwiaWNvblBvc0FjY2Vzc29yIiwiX3JlZiIsImxhdCIsImxuZyIsImFsdGl0dWRlIiwiZGMiLCJkIiwidmFsdWVBdCIsImluZGV4IiwiZmllbGRJZHgiLCJpY29uQWNjZXNzb3IiLCJfcmVmMiIsImljb24iLCJpY29uUmVxdWlyZWRDb2x1bW5zIiwiaWNvbk9wdGlvbmFsQ29sdW1ucyIsInBvaW50VmlzQ29uZmlncyIsInJhZGl1cyIsImZpeGVkUmFkaXVzIiwib3BhY2l0eSIsImNvbG9yUmFuZ2UiLCJyYWRpdXNSYW5nZSIsImJpbGxib2FyZCIsImZsYXR0ZXJJY29uUG9zaXRpb25zIiwibWVzaCIsImNlbGxzIiwicmVkdWNlIiwicHJldiIsImNlbGwiLCJwb3NpdGlvbnMiLCJJY29uTGF5ZXIiLCJfTGF5ZXIiLCJwcm9wcyIsIl90aGlzIiwiX2NsYXNzQ2FsbENoZWNrMiIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0UG9zaXRpb25BY2Nlc3NvciIsImRhdGFDb250YWluZXIiLCJjb25maWciLCJjb2x1bW5zIiwiZ2V0SWNvbkFjY2Vzc29yIiwiX2xheWVySW5mb01vZGFsIiwiSWNvbkluZm9Nb2RhbEZhY3RvcnkiLCJzdmdJY29ucyIsImljb25HZW9tZXRyeSIsImlzVGVzdCIsInNldFN2Z0ljb25zIiwiZ2V0U3ZnSWNvbnMiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsImdldCIsImRlZmF1bHRQb2ludENvbHVtblBhaXJzIiwiSWNvbkxheWVySWNvbiIsImNvbG9yIiwiYWNjZXNzb3IiLCJkZWZhdWx0VmFsdWUiLCJzaXplIiwicHJvcGVydHkiLCJyYW5nZSIsImNoYW5uZWxTY2FsZVR5cGUiLCJpZCIsInRlbXBsYXRlIiwibW9kYWxQcm9wcyIsInRpdGxlIiwidmFsdWUiLCJnZXRab29tRmFjdG9yIiwiX3JlZjMiLCJ6b29tIiwiX3JlZjMkem9vbU9mZnNldCIsInpvb21PZmZzZXQiLCJNYXRoIiwicG93IiwiX3RoaXMyIiwiZmV0Y2hDb25maWciLCJtZXRob2QiLCJtb2RlIiwiY2FjaGUiLCJXaW5kb3ciLCJmZXRjaCIsInN2Z0ljb25VcmwiLCJ0aGVuIiwicmVzcG9uc2UiLCJqc29uIiwicGFyc2VkIiwidW5kZWZpbmVkIiwiYWNjdSIsImN1cnIiLCJnZXRGaWx0ZXJlZEl0ZW1Db3VudCIsImZpbHRlcmVkSXRlbUNvdW50IiwidmFsdWVzIiwidG90YWwiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUiLCJfcmVmNCIsImdldFBvc2l0aW9uIiwiZmlsdGVyZWRJbmRleCIsImdldEljb24iLCJkYXRhIiwiaSIsInJvd0luZGV4IiwicG9zIiwiZXZlcnkiLCJmb3JtYXRMYXllckRhdGEiLCJkYXRhc2V0cyIsIm9sZExheWVyRGF0YSIsImRhdGFJZCIsInRleHRMYWJlbCIsIl9kYXRhc2V0cyR0aGlzJGNvbmZpZyIsImdwdUZpbHRlciIsIl90aGlzJHVwZGF0ZURhdGEiLCJ1cGRhdGVEYXRhIiwidHJpZ2dlckNoYW5nZWQiLCJ0ZXh0TGFiZWxzIiwiZm9ybWF0VGV4dExhYmVsRGF0YSIsImFjY2Vzc29ycyIsImdldEF0dHJpYnV0ZUFjY2Vzc29ycyIsImdldEZpbHRlclZhbHVlIiwiZmlsdGVyVmFsdWVBY2Nlc3NvciIsInVwZGF0ZUxheWVyTWV0YSIsImRhdGFzZXQiLCJib3VuZHMiLCJnZXRQb2ludHNCb3VuZHMiLCJ1cGRhdGVNZXRhIiwicmVuZGVyTGF5ZXIiLCJvcHRzIiwiX3RoaXMkY29uZmlnJGNvbHVtbnMkIiwiX3RoaXMzIiwib2JqZWN0SG92ZXJlZCIsIm1hcFN0YXRlIiwiaW50ZXJhY3Rpb25Db25maWciLCJyYWRpdXNTY2FsZSIsImdldFJhZGl1c1NjYWxlQnlab29tIiwibGF5ZXJQcm9wcyIsInZpc0NvbmZpZyIsInJhZGl1c01heFBpeGVscyIsInVwZGF0ZVRyaWdnZXJzIiwiZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2VycyIsImdldFZpc3VhbENoYW5uZWxVcGRhdGVUcmlnZ2VycyIsImRlZmF1bHRMYXllclByb3BzIiwiZ2V0RGVmYXVsdERlY2tMYXllclByb3BzIiwiYnJ1c2hpbmdQcm9wcyIsImdldEJydXNoaW5nRXh0ZW5zaW9uUHJvcHMiLCJnZXRQaXhlbE9mZnNldCIsImdldFRleHRPZmZzZXRCeVJhZGl1cyIsImdldFJhZGl1cyIsImV4dGVuc2lvbnMiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwic2hhcmVkUHJvcHMiLCJmaWx0ZXJSYW5nZSIsImxhYmVsTGF5ZXJzIiwicmVuZGVyVGV4dExhYmVsTGF5ZXIiLCJob3ZlcmVkT2JqZWN0IiwiaGFzSG92ZXJlZE9iamVjdCIsInBhcmFtZXRlcnMiLCJkZXB0aFRlc3QiLCJjdWxsRmFjZSIsIkdMIiwiRlJPTlQiLCJTdmdJY29uTGF5ZXIiLCJnZXRJY29uR2VvbWV0cnkiLCJfdGhpczMkaWNvbkdlb21ldHJ5IiwiZ2V0RGVmYXVsdEhvdmVyTGF5ZXJQcm9wcyIsInZpc2libGUiLCJnZXRGaWxsQ29sb3IiLCJoaWdobGlnaHRDb2xvciIsIl90aGlzMyRpY29uR2VvbWV0cnkyIiwiZmluZERlZmF1bHRMYXllclByb3BzIiwiX3JlZjUiLCJfcmVmNSRmaWVsZFBhaXJzIiwiZmllbGRQYWlycyIsIl9yZWY1JGZpZWxkcyIsImZpZWxkcyIsIm5vdEZvdW5kIiwiaWNvbkZpZWxkcyIsIl9yZWY2IiwibmFtZSIsInJlcGxhY2UiLCJ0cmltIiwic3BsaXQiLCJzb21lIiwic2VnIiwiSUNPTl9GSUVMRFMiLCJpbmNsdWRlcyIsInB0UGFpciIsImFzc2lnblBvaW50UGFpclRvTGF5ZXJDb2x1bW4iLCJtYXAiLCJpY29uRmllbGQiLCJsYWJlbCIsImlzVmlzaWJsZSIsIkxheWVyIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ljb24tbGF5ZXIvaWNvbi1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgV2luZG93IGZyb20gJ2dsb2JhbC93aW5kb3cnO1xuaW1wb3J0IHtCcnVzaGluZ0V4dGVuc2lvbn0gZnJvbSAnQGRlY2suZ2wvZXh0ZW5zaW9ucyc7XG5pbXBvcnQgR0wgZnJvbSAnQGx1bWEuZ2wvY29uc3RhbnRzJztcblxuaW1wb3J0IHtTdmdJY29uTGF5ZXJ9IGZyb20gJ0BrZXBsZXIuZ2wvZGVja2dsLWxheWVycyc7XG5pbXBvcnQgSWNvbkxheWVySWNvbiBmcm9tICcuL2ljb24tbGF5ZXItaWNvbic7XG5pbXBvcnQge0lDT05fRklFTERTLCBLRVBMRVJfVU5GT0xERURfQlVDS0VUfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQgSWNvbkluZm9Nb2RhbEZhY3RvcnkgZnJvbSAnLi9pY29uLWluZm8tbW9kYWwnO1xuaW1wb3J0IExheWVyLCB7TGF5ZXJCYXNlQ29uZmlnLCBMYXllckJhc2VDb25maWdQYXJ0aWFsfSBmcm9tICcuLi9iYXNlLWxheWVyJztcbmltcG9ydCB7YXNzaWduUG9pbnRQYWlyVG9MYXllckNvbHVtbiwgRmluZERlZmF1bHRMYXllclByb3BzUmV0dXJuVmFsdWV9IGZyb20gJy4uL2xheWVyLXV0aWxzJztcbmltcG9ydCB7aXNUZXN0fSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCB7Z2V0VGV4dE9mZnNldEJ5UmFkaXVzLCBmb3JtYXRUZXh0TGFiZWxEYXRhfSBmcm9tICcuLi9sYXllci10ZXh0LWxhYmVsJztcbmltcG9ydCB7ZGVmYXVsdCBhcyBLZXBsZXJUYWJsZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge0RhdGFDb250YWluZXJJbnRlcmZhY2V9IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuaW1wb3J0IHtcbiAgQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnQm9vbGVhbixcbiAgVmlzQ29uZmlnQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnTnVtYmVyLFxuICBWaXNDb25maWdSYW5nZSxcbiAgTWVyZ2UsXG4gIExheWVyQ29sdW1uXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuXG5leHBvcnQgdHlwZSBJY29uTGF5ZXJDb2x1bW5zQ29uZmlnID0ge1xuICBsYXQ6IExheWVyQ29sdW1uO1xuICBsbmc6IExheWVyQ29sdW1uO1xuICBhbHRpdHVkZTogTGF5ZXJDb2x1bW47XG4gIGljb246IExheWVyQ29sdW1uO1xufTtcblxudHlwZSBJY29uR2VvbWV0cnkgPSBvYmplY3QgfCBudWxsO1xuXG5leHBvcnQgdHlwZSBJY29uTGF5ZXJWaXNDb25maWdTZXR0aW5ncyA9IHtcbiAgcmFkaXVzOiBWaXNDb25maWdOdW1iZXI7XG4gIGZpeGVkUmFkaXVzOiBWaXNDb25maWdCb29sZWFuO1xuICBvcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIGNvbG9yUmFuZ2U6IFZpc0NvbmZpZ0NvbG9yUmFuZ2U7XG4gIHJhZGl1c1JhbmdlOiBWaXNDb25maWdSYW5nZTtcbn07XG5cbmV4cG9ydCB0eXBlIEljb25MYXllclZpc0NvbmZpZyA9IHtcbiAgcmFkaXVzOiBudW1iZXI7XG4gIGZpeGVkUmFkaXVzOiBib29sZWFuO1xuICBvcGFjaXR5OiBudW1iZXI7XG4gIGNvbG9yUmFuZ2U6IENvbG9yUmFuZ2U7XG4gIHJhZGl1c1JhbmdlOiBbbnVtYmVyLCBudW1iZXJdO1xuICBiaWxsYm9hcmQ6IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBJY29uTGF5ZXJDb25maWcgPSBNZXJnZTxcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICB7Y29sdW1uczogSWNvbkxheWVyQ29sdW1uc0NvbmZpZzsgdmlzQ29uZmlnOiBJY29uTGF5ZXJWaXNDb25maWd9XG4+O1xuXG5leHBvcnQgdHlwZSBJY29uTGF5ZXJEYXRhID0ge2luZGV4OiBudW1iZXI7IGljb246IHN0cmluZ307XG5cbmNvbnN0IGJydXNoaW5nRXh0ZW5zaW9uID0gbmV3IEJydXNoaW5nRXh0ZW5zaW9uKCk7XG5cbmV4cG9ydCBjb25zdCBTVkdfSUNPTl9VUkwgPSBgJHtLRVBMRVJfVU5GT0xERURfQlVDS0VUfS9pY29ucy9zdmctaWNvbnMuanNvbmA7XG5cbmV4cG9ydCBjb25zdCBpY29uUG9zQWNjZXNzb3IgPVxuICAoe2xhdCwgbG5nLCBhbHRpdHVkZX06IEljb25MYXllckNvbHVtbnNDb25maWcpID0+XG4gIChkYzogRGF0YUNvbnRhaW5lckludGVyZmFjZSkgPT5cbiAgZCA9PiBbXG4gICAgZGMudmFsdWVBdChkLmluZGV4LCBsbmcuZmllbGRJZHgpLFxuICAgIGRjLnZhbHVlQXQoZC5pbmRleCwgbGF0LmZpZWxkSWR4KSxcbiAgICBhbHRpdHVkZT8uZmllbGRJZHggPiAtMSA/IGRjLnZhbHVlQXQoZC5pbmRleCwgYWx0aXR1ZGUuZmllbGRJZHgpIDogMFxuICBdO1xuXG5leHBvcnQgY29uc3QgaWNvbkFjY2Vzc29yID1cbiAgKHtpY29ufTogSWNvbkxheWVyQ29sdW1uc0NvbmZpZykgPT5cbiAgKGRjOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PlxuICBkID0+XG4gICAgZGMudmFsdWVBdChkLmluZGV4LCBpY29uLmZpZWxkSWR4KTtcblxuZXhwb3J0IGNvbnN0IGljb25SZXF1aXJlZENvbHVtbnM6IFsnbGF0JywgJ2xuZycsICdpY29uJ10gPSBbJ2xhdCcsICdsbmcnLCAnaWNvbiddO1xuZXhwb3J0IGNvbnN0IGljb25PcHRpb25hbENvbHVtbnM6IFsnYWx0aXR1ZGUnXSA9IFsnYWx0aXR1ZGUnXTtcblxuZXhwb3J0IGNvbnN0IHBvaW50VmlzQ29uZmlnczoge1xuICByYWRpdXM6ICdyYWRpdXMnO1xuICBmaXhlZFJhZGl1czogJ2ZpeGVkUmFkaXVzJztcbiAgb3BhY2l0eTogJ29wYWNpdHknO1xuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZSc7XG4gIHJhZGl1c1JhbmdlOiAncmFkaXVzUmFuZ2UnO1xuICBiaWxsYm9hcmQ6ICdiaWxsYm9hcmQnO1xufSA9IHtcbiAgcmFkaXVzOiAncmFkaXVzJyxcbiAgZml4ZWRSYWRpdXM6ICdmaXhlZFJhZGl1cycsXG4gIG9wYWNpdHk6ICdvcGFjaXR5JyxcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnLFxuICByYWRpdXNSYW5nZTogJ3JhZGl1c1JhbmdlJyxcbiAgYmlsbGJvYXJkOiAnYmlsbGJvYXJkJ1xufTtcblxuZnVuY3Rpb24gZmxhdHRlckljb25Qb3NpdGlvbnMoaWNvbikge1xuICAvLyBoYWQgdG8gZmxpcCB5LCBzaW5jZSBAbHVtYSBtb2RhbCBoYXMgY2hhbmdlZFxuICByZXR1cm4gaWNvbi5tZXNoLmNlbGxzLnJlZHVjZSgocHJldiwgY2VsbCkgPT4ge1xuICAgIGNlbGwuZm9yRWFjaChwID0+IHtcbiAgICAgIHByZXYucHVzaChcbiAgICAgICAgLi4uW2ljb24ubWVzaC5wb3NpdGlvbnNbcF1bMF0sIC1pY29uLm1lc2gucG9zaXRpb25zW3BdWzFdLCBpY29uLm1lc2gucG9zaXRpb25zW3BdWzJdXVxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJldjtcbiAgfSwgW10pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJY29uTGF5ZXIgZXh0ZW5kcyBMYXllciB7XG4gIGdldEljb25BY2Nlc3NvcjogKGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+IChkOiBhbnkpID0+IGFueTtcbiAgX2xheWVySW5mb01vZGFsOiAoKSA9PiBKU1guRWxlbWVudDtcbiAgaWNvbkdlb21ldHJ5OiBJY29uR2VvbWV0cnk7XG5cbiAgZGVjbGFyZSB2aXNDb25maWdTZXR0aW5nczogSWNvbkxheWVyVmlzQ29uZmlnU2V0dGluZ3M7XG4gIGRlY2xhcmUgY29uZmlnOiBJY29uTGF5ZXJDb25maWc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvcHM6IHtcbiAgICAgIGlkPzogc3RyaW5nO1xuICAgICAgaWNvbkdlb21ldHJ5PzogSWNvbkdlb21ldHJ5O1xuICAgICAgc3ZnSWNvbnM/OiBhbnlbXTtcbiAgICB9ICYgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbFxuICApIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKHBvaW50VmlzQ29uZmlncyk7XG4gICAgdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yID0gKGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+XG4gICAgICBpY29uUG9zQWNjZXNzb3IodGhpcy5jb25maWcuY29sdW1ucykoZGF0YUNvbnRhaW5lcik7XG4gICAgdGhpcy5nZXRJY29uQWNjZXNzb3IgPSBkYXRhQ29udGFpbmVyID0+IGljb25BY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW5zKShkYXRhQ29udGFpbmVyKTtcblxuICAgIHRoaXMuX2xheWVySW5mb01vZGFsID0gSWNvbkluZm9Nb2RhbEZhY3RvcnkocHJvcHMuc3ZnSWNvbnMpO1xuICAgIHRoaXMuaWNvbkdlb21ldHJ5ID0gcHJvcHMuaWNvbkdlb21ldHJ5IHx8IG51bGw7XG5cbiAgICBpZiAoaXNUZXN0KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHByb3BzLnN2Z0ljb25zKSB7XG4gICAgICAvLyBpZiBzdmcgaWNvbnMgYXJlIHBhc3NlZCBpbiB0aGVuIGJ5cGFzcyBmZXRjaGluZyBvZiByZW1vdGUgc3ZnIGljb25zXG4gICAgICB0aGlzLnNldFN2Z0ljb25zKHByb3BzLnN2Z0ljb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcHJlcGFyZSBsYXllciBpbmZvIG1vZGFsIGFuZCBmZXRjaCByZW1vdGUgc3ZnIGljb25zXG4gICAgICB0aGlzLmdldFN2Z0ljb25zKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN2Z0ljb25VcmwoKSB7XG4gICAgcmV0dXJuIFNWR19JQ09OX1VSTDtcbiAgfVxuXG4gIGdldCB0eXBlKCk6ICdpY29uJyB7XG4gICAgcmV0dXJuICdpY29uJztcbiAgfVxuXG4gIGdldCByZXF1aXJlZExheWVyQ29sdW1ucygpIHtcbiAgICByZXR1cm4gaWNvblJlcXVpcmVkQ29sdW1ucztcbiAgfVxuXG4gIGdldCBvcHRpb25hbENvbHVtbnMoKSB7XG4gICAgcmV0dXJuIGljb25PcHRpb25hbENvbHVtbnM7XG4gIH1cblxuICBnZXQgY29sdW1uUGFpcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVmYXVsdFBvaW50Q29sdW1uUGFpcnM7XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCkge1xuICAgIHJldHVybiBJY29uTGF5ZXJJY29uO1xuICB9XG5cbiAgZ2V0IHZpc3VhbENoYW5uZWxzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb2xvcjoge1xuICAgICAgICAuLi5zdXBlci52aXN1YWxDaGFubmVscy5jb2xvcixcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRGaWxsQ29sb3InLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGNvbmZpZyA9PiBjb25maWcuY29sb3JcbiAgICAgIH0sXG4gICAgICBzaXplOiB7XG4gICAgICAgIC4uLnN1cGVyLnZpc3VhbENoYW5uZWxzLnNpemUsXG4gICAgICAgIHByb3BlcnR5OiAncmFkaXVzJyxcbiAgICAgICAgcmFuZ2U6ICdyYWRpdXNSYW5nZScsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6ICdyYWRpdXMnLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldFJhZGl1cycsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogMVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXQgbGF5ZXJJbmZvTW9kYWwoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiAnaWNvbkluZm8nLFxuICAgICAgdGVtcGxhdGU6IHRoaXMuX2xheWVySW5mb01vZGFsLFxuICAgICAgbW9kYWxQcm9wczoge1xuICAgICAgICB0aXRsZTogJ21vZGFsLmljb25JbmZvLnRpdGxlJ1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXRab29tRmFjdG9yKHt6b29tLCB6b29tT2Zmc2V0ID0gMH06IHt6b29tOiBudW1iZXIsIHpvb21PZmZzZXQ/OiBudW1iZXJ9KSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDIsIDE0IC0gem9vbSArIHpvb21PZmZzZXQpO1xuICB9XG5cbiAgZ2V0U3ZnSWNvbnMoKSB7XG4gICAgY29uc3QgZmV0Y2hDb25maWcgPSB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgbW9kZTogJ2NvcnMnLFxuICAgICAgY2FjaGU6ICduby1jYWNoZSdcbiAgICB9O1xuXG4gICAgaWYgKFdpbmRvdy5mZXRjaCAmJiB0aGlzLnN2Z0ljb25VcmwpIHtcbiAgICAgIFdpbmRvdy5mZXRjaCh0aGlzLnN2Z0ljb25VcmwsIGZldGNoQ29uZmlnKVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiByZXNwb25zZS5qc29uKCkpXG4gICAgICAgIC50aGVuKChwYXJzZWQ6IHtzdmdJY29ucz86IGFueVtdfSA9IHt9KSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRTdmdJY29ucyhwYXJzZWQuc3ZnSWNvbnMpO1xuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBzZXRTdmdJY29ucyhzdmdJY29uczogYW55W10gPSBbXSkge1xuICAgIHRoaXMuaWNvbkdlb21ldHJ5ID0gc3ZnSWNvbnMucmVkdWNlKFxuICAgICAgKGFjY3UsIGN1cnIpID0+ICh7XG4gICAgICAgIC4uLmFjY3UsXG4gICAgICAgIFtjdXJyLmlkXTogZmxhdHRlckljb25Qb3NpdGlvbnMoY3VycilcbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuXG4gICAgdGhpcy5fbGF5ZXJJbmZvTW9kYWwgPSBJY29uSW5mb01vZGFsRmFjdG9yeShzdmdJY29ucyk7XG4gIH1cblxuICBzdGF0aWMgZmluZERlZmF1bHRMYXllclByb3BzKHtmaWVsZFBhaXJzID0gW10sIGZpZWxkcyA9IFtdfTogS2VwbGVyVGFibGUpOiBGaW5kRGVmYXVsdExheWVyUHJvcHNSZXR1cm5WYWx1ZSB7XG4gICAgY29uc3Qgbm90Rm91bmQ6IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlID0ge3Byb3BzOiBbXX07XG4gICAgaWYgKCFmaWVsZFBhaXJzLmxlbmd0aCB8fCAhZmllbGRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG5vdEZvdW5kO1xuICAgIH1cblxuICAgIGNvbnN0IGljb25GaWVsZHMgPSBmaWVsZHMuZmlsdGVyKCh7bmFtZX0pID0+XG4gICAgICBuYW1lXG4gICAgICAgIC5yZXBsYWNlKC9bXywuXSsvZywgJyAnKVxuICAgICAgICAudHJpbSgpXG4gICAgICAgIC5zcGxpdCgnICcpXG4gICAgICAgIC5zb21lKHNlZyA9PiBJQ09OX0ZJRUxEUy5pY29uLnNvbWUodCA9PiB0LmluY2x1ZGVzKHNlZykpKVxuICAgICk7XG5cbiAgICBpZiAoIWljb25GaWVsZHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gbm90Rm91bmQ7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIGljb24gbGF5ZXJzIGZvciBmaXJzdCBwb2ludCBwYWlyXG4gICAgY29uc3QgcHRQYWlyID0gZmllbGRQYWlyc1swXTtcbiAgICBjb25zdCBjb2x1bW5zID0gYXNzaWduUG9pbnRQYWlyVG9MYXllckNvbHVtbihwdFBhaXIsIHRydWUpO1xuXG4gICAgY29uc3QgcHJvcHMgPSBpY29uRmllbGRzLm1hcChpY29uRmllbGQgPT4gKHtcbiAgICAgIGxhYmVsOiBpY29uRmllbGQubmFtZS5yZXBsYWNlKC9bXywuXSsvZywgJyAnKS50cmltKCksXG4gICAgICBjb2x1bW5zOiB7XG4gICAgICAgIC4uLmNvbHVtbnMsXG4gICAgICAgIGljb246IHtcbiAgICAgICAgICB2YWx1ZTogaWNvbkZpZWxkLm5hbWUsXG4gICAgICAgICAgZmllbGRJZHg6IGljb25GaWVsZC5maWVsZElkeFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgaXNWaXNpYmxlOiB0cnVlXG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHtwcm9wc307XG4gIH1cblxuICBnZXRGaWx0ZXJlZEl0ZW1Db3VudCgpIHtcbiAgICAvLyB1c2UgdG90YWxcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5maWx0ZXJlZEl0ZW1Db3VudCkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLmZpbHRlcmVkSXRlbUNvdW50KS5yZWR1Y2UoXG4gICAgICAgICh0b3RhbCwgY3VycikgPT4gKE51bWJlci5pc0Zpbml0ZShjdXJyKSA/IHRvdGFsICsgY3VyciA6IHRvdGFsKSxcbiAgICAgICAgMFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUoe2RhdGFDb250YWluZXIsIGZpbHRlcmVkSW5kZXh9OiBLZXBsZXJUYWJsZSwgZ2V0UG9zaXRpb24pIHtcbiAgICBjb25zdCBnZXRJY29uID0gdGhpcy5nZXRJY29uQWNjZXNzb3IoZGF0YUNvbnRhaW5lcik7XG4gICAgY29uc3QgZGF0YTogSWNvbkxheWVyRGF0YVtdID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbHRlcmVkSW5kZXgubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gZmlsdGVyZWRJbmRleFtpXTtcbiAgICAgIGNvbnN0IHJvd0luZGV4ID0ge2luZGV4fTtcbiAgICAgIGNvbnN0IHBvcyA9IGdldFBvc2l0aW9uKHJvd0luZGV4KTtcbiAgICAgIGNvbnN0IGljb24gPSBnZXRJY29uKHJvd0luZGV4KTtcblxuICAgICAgLy8gaWYgZG9lc24ndCBoYXZlIHBvaW50IGxhdCBvciBsbmcsIGRvIG5vdCBhZGQgdGhlIHBvaW50XG4gICAgICAvLyBkZWNrLmdsIGNhbid0IGhhbmRsZSBwb3NpdGlvbiA9IG51bGxcbiAgICAgIGlmIChwb3MuZXZlcnkoTnVtYmVyLmlzRmluaXRlKSAmJiB0eXBlb2YgaWNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGF0YS5wdXNoKHtcbiAgICAgICAgICBpbmRleCxcbiAgICAgICAgICBpY29uXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZm9ybWF0TGF5ZXJEYXRhKGRhdGFzZXRzLCBvbGRMYXllckRhdGEpIHtcbiAgICBpZiAodGhpcy5jb25maWcuZGF0YUlkID09PSBudWxsKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IHt0ZXh0TGFiZWx9ID0gdGhpcy5jb25maWc7XG4gICAgY29uc3Qge2dwdUZpbHRlciwgZGF0YUNvbnRhaW5lcn0gPSBkYXRhc2V0c1t0aGlzLmNvbmZpZy5kYXRhSWRdO1xuXG4gICAgY29uc3QgZ2V0UG9zaXRpb24gPSB0aGlzLmdldFBvc2l0aW9uQWNjZXNzb3IoZGF0YUNvbnRhaW5lcik7XG5cbiAgICBjb25zdCB7ZGF0YSwgdHJpZ2dlckNoYW5nZWR9ID0gdGhpcy51cGRhdGVEYXRhKGRhdGFzZXRzLCBvbGRMYXllckRhdGEpO1xuXG4gICAgLy8gZ2V0IGFsbCBkaXN0aW5jdCBjaGFyYWN0ZXJzIGluIHRoZSB0ZXh0IGxhYmVsc1xuICAgIGNvbnN0IHRleHRMYWJlbHMgPSBmb3JtYXRUZXh0TGFiZWxEYXRhKHtcbiAgICAgIHRleHRMYWJlbCxcbiAgICAgIHRyaWdnZXJDaGFuZ2VkLFxuICAgICAgb2xkTGF5ZXJEYXRhLFxuICAgICAgZGF0YSxcbiAgICAgIGRhdGFDb250YWluZXJcbiAgICB9KTtcblxuICAgIGNvbnN0IGFjY2Vzc29ycyA9IHRoaXMuZ2V0QXR0cmlidXRlQWNjZXNzb3JzKHtkYXRhQ29udGFpbmVyfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YSxcbiAgICAgIGdldFBvc2l0aW9uLFxuICAgICAgZ2V0RmlsdGVyVmFsdWU6IGdwdUZpbHRlci5maWx0ZXJWYWx1ZUFjY2Vzc29yKGRhdGFDb250YWluZXIpKCksXG4gICAgICB0ZXh0TGFiZWxzLFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfTtcbiAgfVxuXG4gIHVwZGF0ZUxheWVyTWV0YShkYXRhc2V0OiBLZXBsZXJUYWJsZSwgZ2V0UG9zaXRpb24pIHtcbiAgICBjb25zdCB7ZGF0YUNvbnRhaW5lcn0gPSBkYXRhc2V0O1xuICAgIGNvbnN0IGJvdW5kcyA9IHRoaXMuZ2V0UG9pbnRzQm91bmRzKGRhdGFDb250YWluZXIsIGdldFBvc2l0aW9uKTtcbiAgICB0aGlzLnVwZGF0ZU1ldGEoe2JvdW5kc30pO1xuICB9XG5cbiAgcmVuZGVyTGF5ZXIob3B0cykge1xuICAgIGNvbnN0IHtkYXRhLCBncHVGaWx0ZXIsIG9iamVjdEhvdmVyZWQsIG1hcFN0YXRlLCBpbnRlcmFjdGlvbkNvbmZpZ30gPSBvcHRzO1xuXG4gICAgY29uc3QgcmFkaXVzU2NhbGUgPSB0aGlzLmdldFJhZGl1c1NjYWxlQnlab29tKG1hcFN0YXRlKTtcblxuICAgIGNvbnN0IGxheWVyUHJvcHMgPSB7XG4gICAgICByYWRpdXNTY2FsZSxcbiAgICAgIGJpbGxib2FyZDogdGhpcy5jb25maWcudmlzQ29uZmlnLmJpbGxib2FyZCxcbiAgICAgIC4uLih0aGlzLmNvbmZpZy52aXNDb25maWcuZml4ZWRSYWRpdXMgPyB7fSA6IHtyYWRpdXNNYXhQaXhlbHM6IDUwMH0pXG4gICAgfTtcblxuICAgIGNvbnN0IHVwZGF0ZVRyaWdnZXJzID0ge1xuICAgICAgZ2V0UG9zaXRpb246IHRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZ3B1RmlsdGVyLmZpbHRlclZhbHVlVXBkYXRlVHJpZ2dlcnMsXG4gICAgICAuLi50aGlzLmdldFZpc3VhbENoYW5uZWxVcGRhdGVUcmlnZ2VycygpXG4gICAgfTtcblxuICAgIGNvbnN0IGRlZmF1bHRMYXllclByb3BzID0gdGhpcy5nZXREZWZhdWx0RGVja0xheWVyUHJvcHMob3B0cyk7XG4gICAgY29uc3QgYnJ1c2hpbmdQcm9wcyA9IHRoaXMuZ2V0QnJ1c2hpbmdFeHRlbnNpb25Qcm9wcyhpbnRlcmFjdGlvbkNvbmZpZyk7XG4gICAgY29uc3QgZ2V0UGl4ZWxPZmZzZXQgPSBnZXRUZXh0T2Zmc2V0QnlSYWRpdXMocmFkaXVzU2NhbGUsIGRhdGEuZ2V0UmFkaXVzLCBtYXBTdGF0ZSk7XG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IFsuLi5kZWZhdWx0TGF5ZXJQcm9wcy5leHRlbnNpb25zLCBicnVzaGluZ0V4dGVuc2lvbl07XG5cbiAgICAvLyBzaGFyZWQgUHJvcHMgYmV0d2VlbiBsYXllciBhbmQgbGFiZWwgbGF5ZXJcbiAgICBjb25zdCBzaGFyZWRQcm9wcyA9IHtcbiAgICAgIGdldEZpbHRlclZhbHVlOiBkYXRhLmdldEZpbHRlclZhbHVlLFxuICAgICAgZXh0ZW5zaW9ucyxcbiAgICAgIGZpbHRlclJhbmdlOiBkZWZhdWx0TGF5ZXJQcm9wcy5maWx0ZXJSYW5nZSxcbiAgICAgIC4uLmJydXNoaW5nUHJvcHNcbiAgICB9O1xuXG4gICAgY29uc3QgbGFiZWxMYXllcnMgPSBbXG4gICAgICAuLi50aGlzLnJlbmRlclRleHRMYWJlbExheWVyKFxuICAgICAgICB7XG4gICAgICAgICAgZ2V0UG9zaXRpb246IGRhdGEuZ2V0UG9zaXRpb24sXG4gICAgICAgICAgc2hhcmVkUHJvcHMsXG4gICAgICAgICAgZ2V0UGl4ZWxPZmZzZXQsXG4gICAgICAgICAgdXBkYXRlVHJpZ2dlcnNcbiAgICAgICAgfSxcbiAgICAgICAgb3B0c1xuICAgICAgKVxuICAgIF07XG4gICAgY29uc3QgaG92ZXJlZE9iamVjdCA9IHRoaXMuaGFzSG92ZXJlZE9iamVjdChvYmplY3RIb3ZlcmVkKTtcblxuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSB7XG4gICAgICAvLyBpY29ucyB3aWxsIGJlIGZsYXQgb24gdGhlIG1hcCB3aGVuIHRoZSBhbHRpdHVkZSBjb2x1bW4gaXMgbm90IHVzZWRcbiAgICAgIGRlcHRoVGVzdDogdGhpcy5jb25maWcuY29sdW1ucy5hbHRpdHVkZT8uZmllbGRJZHggPiAtMSxcbiAgICAgIGN1bGxGYWNlOiBHTC5GUk9OVFxuICAgIH07XG5cbiAgICByZXR1cm4gIXRoaXMuaWNvbkdlb21ldHJ5XG4gICAgICA/IFtdXG4gICAgICA6IFtcbiAgICAgICAgICBuZXcgU3ZnSWNvbkxheWVyKHtcbiAgICAgICAgICAgIC4uLmRlZmF1bHRMYXllclByb3BzLFxuICAgICAgICAgICAgLi4uYnJ1c2hpbmdQcm9wcyxcbiAgICAgICAgICAgIC4uLmxheWVyUHJvcHMsXG4gICAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICAgICAgcGFyYW1ldGVycyxcbiAgICAgICAgICAgIGdldEljb25HZW9tZXRyeTogaWQgPT4gdGhpcy5pY29uR2VvbWV0cnk/LltpZF0sXG5cbiAgICAgICAgICAgIC8vIHVwZGF0ZSB0cmlnZ2Vyc1xuICAgICAgICAgICAgdXBkYXRlVHJpZ2dlcnMsXG4gICAgICAgICAgICBleHRlbnNpb25zXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICAvLyBob3ZlciBsYXllclxuICAgICAgICAgIC4uLihob3ZlcmVkT2JqZWN0XG4gICAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFN2Z0ljb25MYXllclByb3BzIG5lZWRzIGdldEljb24gRmllbGRcbiAgICAgICAgICAgICAgICBuZXcgU3ZnSWNvbkxheWVyKHtcbiAgICAgICAgICAgICAgICAgIC4uLnRoaXMuZ2V0RGVmYXVsdEhvdmVyTGF5ZXJQcm9wcygpLFxuICAgICAgICAgICAgICAgICAgLi4ubGF5ZXJQcm9wcyxcbiAgICAgICAgICAgICAgICAgIHZpc2libGU6IGRlZmF1bHRMYXllclByb3BzLnZpc2libGUsXG4gICAgICAgICAgICAgICAgICBkYXRhOiBbaG92ZXJlZE9iamVjdF0sXG4gICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLFxuICAgICAgICAgICAgICAgICAgZ2V0UG9zaXRpb246IGRhdGEuZ2V0UG9zaXRpb24sXG4gICAgICAgICAgICAgICAgICBnZXRSYWRpdXM6IGRhdGEuZ2V0UmFkaXVzLFxuICAgICAgICAgICAgICAgICAgZ2V0RmlsbENvbG9yOiB0aGlzLmNvbmZpZy5oaWdobGlnaHRDb2xvcixcbiAgICAgICAgICAgICAgICAgIGdldEljb25HZW9tZXRyeTogaWQgPT4gdGhpcy5pY29uR2VvbWV0cnk/LltpZF1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICBdXG4gICAgICAgICAgICA6IFtdKSxcblxuICAgICAgICAgIC8vIHRleHQgbGFiZWwgbGF5ZXJcbiAgICAgICAgICAuLi5sYWJlbExheWVyc1xuICAgICAgICBdO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7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