kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
313 lines (304 loc) • 54.6 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.HISTOGRAM_WIDTH = exports.HISTOGRAM_HEIGHT = exports.ColorChartTick = exports.ColorChartHeader = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _d3Format = require("d3-format");
var _d3Scale = require("d3-scale");
var _react = _interopRequireWildcard(require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/node_modules/react"));
var _styledComponents = _interopRequireDefault(require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/node_modules/styled-components"));
var _src = require("/Users/ihordykhta/Desktop/unfolded/kepler.gl/src/utils/src");
var _colorPalette = _interopRequireDefault(require("../side-panel/layer-panel/color-palette"));
var _histogramPlot = _interopRequireWildcard(require("./histogram-plot"));
var _loadingSpinner = _interopRequireDefault(require("./loading-spinner"));
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8; // 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" != _typeof(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 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 HISTOGRAM_WIDTH = exports.HISTOGRAM_WIDTH = 210;
var HISTOGRAM_HEIGHT = exports.HISTOGRAM_HEIGHT = 80;
var HISTOGRAM_MARGIN = {
top: 10,
bottom: 8,
left: 10,
right: 20
};
var COLOR_CHART_TICK_WRAPPER_HEIGHT = 10;
var COLOR_CHART_TICK_HEIGHT = 8;
var COLOR_CHART_TICK_WIDTH = 4;
var COLOR_CHART_TICK_BORDER_COLOR = '#999999';
var StyledContainer = _styledComponents["default"].div.attrs({
className: 'color-chart-loading'
})(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n height: ", "px;\n"])), HISTOGRAM_HEIGHT);
// height 142 = 18 + 110 + 10
var ColorChartContainer = _styledComponents["default"].div.attrs({
className: 'color-chart-container'
})(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n margin-top: 8px;\n"])));
var ColorChartHeaderWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-header'
})(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n justify-content: space-around;\n color: ", ";\n margin-left: ", "px;\n margin-right: ", "px;\n font-size: 9px;\n"])), function (props) {
return props.theme.textColor;
}, HISTOGRAM_MARGIN.left, HISTOGRAM_MARGIN.right);
var ColorChartHeaderItem = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n width: 33%;\n overflow: hidden;\n white-space: nowrap;\n"])));
var ColorChartWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-wrapper'
})(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n position: relative;\n height: ", "px;\n"])), HISTOGRAM_HEIGHT + 30);
var ColorPaletteWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-palette'
})(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n margin-top: ", "px;\n margin-left: ", "px;\n margin-right: ", "px;\n"])), HISTOGRAM_MARGIN.top, HISTOGRAM_MARGIN.left, HISTOGRAM_MARGIN.right);
var HistogramWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-histogram'
})(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n"])));
var ColorChartTickContainer = _styledComponents["default"].div.attrs({
className: 'color-chart-tick-container'
})(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n height: ", "px;\n position: relative;\n margin-left: ", "px;\n margin-right: ", "px;\n"])), COLOR_CHART_TICK_WRAPPER_HEIGHT, HISTOGRAM_MARGIN.left, HISTOGRAM_MARGIN.right);
var ColorChartHeader = exports.ColorChartHeader = function ColorChartHeader(_ref) {
var minVal = _ref.minVal,
meanVal = _ref.meanVal,
maxVal = _ref.maxVal;
return /*#__PURE__*/_react["default"].createElement(ColorChartHeaderWrapper, null, /*#__PURE__*/_react["default"].createElement(ColorChartHeaderItem, {
title: minVal
}, "MIN: ", minVal), /*#__PURE__*/_react["default"].createElement(ColorChartHeaderItem, {
title: meanVal
}, "MEAN: ", (0, _d3Format.format)('.4~r')(meanVal)), /*#__PURE__*/_react["default"].createElement(ColorChartHeaderItem, {
title: maxVal,
style: {
textAlign: 'right'
}
}, "MAX: ", maxVal));
};
var ColorChartTick = exports.ColorChartTick = function ColorChartTick(_ref2) {
var colors = _ref2.colors,
positions = _ref2.positions,
histogramWidth = _ref2.histogramWidth,
onTickMoving = _ref2.onTickMoving,
onTickChanged = _ref2.onTickChanged;
var _useState = (0, _react.useState)(positions),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
statePositions = _useState2[0],
setPositions = _useState2[1];
var _useState3 = (0, _react.useState)(-1),
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
dragTick = _useState4[0],
setDragTick = _useState4[1];
var containerRef = (0, _react.useRef)(null);
(0, _react.useEffect)(function () {
setPositions(positions);
setDragTick(dragTick);
}, [positions, dragTick]);
var onMouseMove = (0, _react.useCallback)(function (e) {
if (dragTick >= 0) {
// @ts-ignore
var offsetX = containerRef.current.getBoundingClientRect().x;
statePositions[dragTick] = e.clientX - (offsetX !== null && offsetX !== void 0 ? offsetX : 0);
var leftBound = dragTick === 0 ? 0 : statePositions[dragTick - 1] + 1;
var rightBound = dragTick === positions.length - 1 ? histogramWidth : statePositions[dragTick + 1] - 1;
// restrict user drag-n-move between left and right neighboring ticks
if (statePositions[dragTick] < leftBound) {
statePositions[dragTick] = leftBound;
}
if (statePositions[dragTick] > rightBound) {
statePositions[dragTick] = rightBound;
}
setPositions((0, _toConsumableArray2["default"])(statePositions));
onTickMoving(statePositions, dragTick);
}
}, [dragTick, onTickMoving, positions.length, statePositions, histogramWidth]);
var onMouseUp = (0, _react.useCallback)(function (e) {
if (dragTick >= 0) {
onTickChanged();
setDragTick(-1);
e.stopPropagation();
e.preventDefault();
}
}, [dragTick, onTickChanged]);
var _onMouseDown = (0, _react.useCallback)(function (e, tickIndex) {
if ((0, _src.isNumber)(tickIndex)) {
setDragTick(tickIndex);
e.stopPropagation();
e.preventDefault();
}
}, []);
return /*#__PURE__*/_react["default"].createElement(ColorChartTickContainer, {
ref: containerRef,
onMouseMove: onMouseMove,
onMouseUp: onMouseUp,
onMouseLeave: onMouseUp
}, colors.map(function (color, index) {
return /*#__PURE__*/_react["default"].createElement("div", {
draggable: true,
key: "color-chart-tick-".concat(color, "-").concat(index),
onMouseDown: function onMouseDown(e) {
return _onMouseDown(e, index);
},
style: {
backgroundColor: color,
left: "".concat(statePositions[index] - COLOR_CHART_TICK_WIDTH / 2 - 1, "px"),
borderWidth: "1px",
borderStyle: 'solid',
borderColor: COLOR_CHART_TICK_BORDER_COLOR,
position: 'absolute',
width: "".concat(COLOR_CHART_TICK_WIDTH, "px"),
height: "".concat(COLOR_CHART_TICK_HEIGHT, "px"),
cursor: 'pointer'
}
});
}));
};
// only for numetic field
ColumnStatsChartFactory.deps = [_histogramPlot["default"]];
function ColumnStatsChartFactory(HistogramPlot) {
var ColumnStatsChart = function ColumnStatsChart(_ref3) {
var allBins = _ref3.allBins,
filteredBins = _ref3.filteredBins,
isFiltered = _ref3.isFiltered,
histogramDomain = _ref3.histogramDomain,
colorBreaks = _ref3.colorBreaks,
onChangedUpdater = _ref3.onChangedUpdater;
var _useState5 = (0, _react.useState)(colorBreaks),
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
ticks = _useState6[0],
setTicks = _useState6[1];
var _useDimensions = (0, _src.useDimensions)(),
_useDimensions2 = (0, _slicedToArray2["default"])(_useDimensions, 2),
ref = _useDimensions2[0],
size = _useDimensions2[1];
var histogramWidth = size ? size.width - HISTOGRAM_MARGIN.left - HISTOGRAM_MARGIN.right : HISTOGRAM_WIDTH;
// distinguish between props.colorBreaks and states.ticks
var isTickChangingRef = _react["default"].useRef(false);
(0, _react.useEffect)(function () {
setTicks(ticks);
// reset isTickChanging once histogram domain is recomputed
isTickChangingRef.current = false;
}, [ticks]);
// histograms used by histogram-plot.js
var histogramsByGroup = (0, _react.useMemo)(function () {
return {
bins: allBins,
filteredBins: filteredBins
};
}, [allBins, filteredBins]);
// get colors from colorBreaks
var domainColors = (0, _react.useMemo)(function () {
return colorBreaks ? colorBreaks.map(function (c) {
return c.data;
}) : [];
}, [colorBreaks]);
var tickPositions = (0, _react.useMemo)(function () {
if (!isTickChangingRef.current) {
setTicks(colorBreaks);
}
var _histogramDomain = (0, _slicedToArray2["default"])(histogramDomain, 2),
valueMin = _histogramDomain[0],
valueMax = _histogramDomain[1];
var widthScale = (0, _d3Scale.scaleLinear)().domain([valueMin, valueMax]).range([0, histogramWidth]);
return ticks.slice(0, -1).map(function (cb) {
var pos = widthScale(cb.range[1]);
if (pos < 0) return 0;else if (pos > histogramWidth) return histogramWidth;
return pos;
});
}, [histogramDomain, ticks, colorBreaks, histogramWidth]);
var domainColorWidths = (0, _react.useMemo)(function () {
var n = tickPositions.length;
var widths = [tickPositions[0]];
for (var i = 1; i < n; ++i) {
widths.push(tickPositions[i] - tickPositions[i - 1]);
}
widths.push(histogramWidth - tickPositions[n - 1]);
return widths;
}, [tickPositions, histogramWidth]);
// handle tick drag-n-move
var onTickMovingHandler = (0, _react.useCallback)(function (newTickPositions, tickIndex) {
var _histogramDomain2 = (0, _slicedToArray2["default"])(histogramDomain, 2),
valueMin = _histogramDomain2[0],
valueMax = _histogramDomain2[1];
var valueRange = valueMax - valueMin;
var breaks = [valueMin];
newTickPositions.forEach(function (element) {
breaks.push(valueMin + valueRange * element / histogramWidth);
});
breaks.push(valueMax);
for (var i = 0; i < ticks.length; ++i) {
var leftValue = i === tickIndex + 1 ? breaks[i] : ticks[i].range[0];
var rightValue = i + 1 === tickIndex + 1 ? breaks[i + 1] : ticks[i].range[1];
ticks[i] = _objectSpread(_objectSpread({}, ticks[i]), {}, {
range: [leftValue, rightValue],
inputs: [leftValue, rightValue],
label: "".concat((0, _d3Format.format)('.2f')(breaks[i]), " to ").concat((0, _d3Format.format)('.2f')(breaks[i + 1]))
});
}
isTickChangingRef.current = true;
setTicks((0, _toConsumableArray2["default"])(ticks));
}, [histogramDomain, ticks, histogramWidth]);
// update parent and sibling components when tick dragging ended
var onTickChangedHandler = (0, _react.useCallback)(function () {
onChangedUpdater(ticks);
}, [onChangedUpdater, ticks]);
return /*#__PURE__*/_react["default"].createElement(ColorChartContainer, {
ref: ref
}, /*#__PURE__*/_react["default"].createElement(ColorChartHeader, {
minVal: histogramDomain[0],
maxVal: histogramDomain[1],
meanVal: histogramDomain[2]
}), /*#__PURE__*/_react["default"].createElement(ColorChartWrapper, null, /*#__PURE__*/_react["default"].createElement(ColorPaletteWrapper, null, /*#__PURE__*/_react["default"].createElement(_colorPalette["default"], {
colors: domainColors,
colorWidths: domainColorWidths,
height: HISTOGRAM_HEIGHT + 16
})), /*#__PURE__*/_react["default"].createElement(HistogramWrapper, null, /*#__PURE__*/_react["default"].createElement(HistogramPlot, {
histogramsByGroup: histogramsByGroup,
colorsByGroup: null,
isMasked: isFiltered ? _histogramPlot.HISTOGRAM_MASK_MODE.MaskWithOverlay : _histogramPlot.HISTOGRAM_MASK_MODE.Mask,
value: histogramDomain,
width: histogramWidth,
height: HISTOGRAM_HEIGHT,
margin: HISTOGRAM_MARGIN,
breakLines: tickPositions
}))), /*#__PURE__*/_react["default"].createElement(ColorChartTick, {
colors: domainColors.slice(0, -1),
positions: tickPositions,
histogramWidth: histogramWidth,
onTickMoving: onTickMovingHandler,
onTickChanged: onTickChangedHandler
}));
};
var ColumnStatsChartWLoading = function ColumnStatsChartWLoading(_ref4) {
var colorField = _ref4.colorField,
dataset = _ref4.dataset,
colorBreaks = _ref4.colorBreaks,
allBins = _ref4.allBins,
filteredBins = _ref4.filteredBins,
isFiltered = _ref4.isFiltered,
histogramDomain = _ref4.histogramDomain,
onChangedUpdater = _ref4.onChangedUpdater;
var fieldName = colorField === null || colorField === void 0 ? void 0 : colorField.name;
var field = (0, _react.useMemo)(function () {
return fieldName ? dataset.getColumnField(fieldName) : null;
}, [dataset, fieldName]);
if (!(0, _src.isNumericColorBreaks)(colorBreaks)) {
// TODO: implement display for ordinal breaks
return null;
}
if (field !== null && field !== void 0 && field.isLoadingStats) {
return /*#__PURE__*/_react["default"].createElement(StyledContainer, null, /*#__PURE__*/_react["default"].createElement(_loadingSpinner["default"], null));
}
return /*#__PURE__*/_react["default"].createElement(ColumnStatsChart, {
colorBreaks: colorBreaks,
allBins: allBins,
filteredBins: filteredBins,
isFiltered: isFiltered,
histogramDomain: histogramDomain,
onChangedUpdater: onChangedUpdater
});
};
return ColumnStatsChartWLoading;
}
var _default = exports["default"] = ColumnStatsChartFactory;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZDNGb3JtYXQiLCJyZXF1aXJlIiwiX2QzU2NhbGUiLCJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIl9zdHlsZWRDb21wb25lbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9zcmMiLCJfY29sb3JQYWxldHRlIiwiX2hpc3RvZ3JhbVBsb3QiLCJfbG9hZGluZ1NwaW5uZXIiLCJfdGVtcGxhdGVPYmplY3QiLCJfdGVtcGxhdGVPYmplY3QyIiwiX3RlbXBsYXRlT2JqZWN0MyIsIl90ZW1wbGF0ZU9iamVjdDQiLCJfdGVtcGxhdGVPYmplY3Q1IiwiX3RlbXBsYXRlT2JqZWN0NiIsIl90ZW1wbGF0ZU9iamVjdDciLCJfdGVtcGxhdGVPYmplY3Q4IiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJfdHlwZW9mIiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0Iiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiSElTVE9HUkFNX1dJRFRIIiwiZXhwb3J0cyIsIkhJU1RPR1JBTV9IRUlHSFQiLCJISVNUT0dSQU1fTUFSR0lOIiwidG9wIiwiYm90dG9tIiwibGVmdCIsInJpZ2h0IiwiQ09MT1JfQ0hBUlRfVElDS19XUkFQUEVSX0hFSUdIVCIsIkNPTE9SX0NIQVJUX1RJQ0tfSEVJR0hUIiwiQ09MT1JfQ0hBUlRfVElDS19XSURUSCIsIkNPTE9SX0NIQVJUX1RJQ0tfQk9SREVSX0NPTE9SIiwiU3R5bGVkQ29udGFpbmVyIiwic3R5bGVkIiwiZGl2IiwiYXR0cnMiLCJjbGFzc05hbWUiLCJfdGFnZ2VkVGVtcGxhdGVMaXRlcmFsMiIsIkNvbG9yQ2hhcnRDb250YWluZXIiLCJDb2xvckNoYXJ0SGVhZGVyV3JhcHBlciIsInByb3BzIiwidGhlbWUiLCJ0ZXh0Q29sb3IiLCJDb2xvckNoYXJ0SGVhZGVySXRlbSIsIkNvbG9yQ2hhcnRXcmFwcGVyIiwiQ29sb3JQYWxldHRlV3JhcHBlciIsIkhpc3RvZ3JhbVdyYXBwZXIiLCJDb2xvckNoYXJ0VGlja0NvbnRhaW5lciIsIkNvbG9yQ2hhcnRIZWFkZXIiLCJfcmVmIiwibWluVmFsIiwibWVhblZhbCIsIm1heFZhbCIsImNyZWF0ZUVsZW1lbnQiLCJ0aXRsZSIsImQzRm9ybWF0Iiwic3R5bGUiLCJ0ZXh0QWxpZ24iLCJDb2xvckNoYXJ0VGljayIsIl9yZWYyIiwiY29sb3JzIiwicG9zaXRpb25zIiwiaGlzdG9ncmFtV2lkdGgiLCJvblRpY2tNb3ZpbmciLCJvblRpY2tDaGFuZ2VkIiwiX3VzZVN0YXRlIiwidXNlU3RhdGUiLCJfdXNlU3RhdGUyIiwiX3NsaWNlZFRvQXJyYXkyIiwic3RhdGVQb3NpdGlvbnMiLCJzZXRQb3NpdGlvbnMiLCJfdXNlU3RhdGUzIiwiX3VzZVN0YXRlNCIsImRyYWdUaWNrIiwic2V0RHJhZ1RpY2siLCJjb250YWluZXJSZWYiLCJ1c2VSZWYiLCJ1c2VFZmZlY3QiLCJvbk1vdXNlTW92ZSIsInVzZUNhbGxiYWNrIiwib2Zmc2V0WCIsImN1cnJlbnQiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJ4IiwiY2xpZW50WCIsImxlZnRCb3VuZCIsInJpZ2h0Qm91bmQiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwib25Nb3VzZVVwIiwic3RvcFByb3BhZ2F0aW9uIiwicHJldmVudERlZmF1bHQiLCJvbk1vdXNlRG93biIsInRpY2tJbmRleCIsImlzTnVtYmVyIiwicmVmIiwib25Nb3VzZUxlYXZlIiwibWFwIiwiY29sb3IiLCJpbmRleCIsImRyYWdnYWJsZSIsImtleSIsImNvbmNhdCIsImJhY2tncm91bmRDb2xvciIsImJvcmRlcldpZHRoIiwiYm9yZGVyU3R5bGUiLCJib3JkZXJDb2xvciIsInBvc2l0aW9uIiwid2lkdGgiLCJoZWlnaHQiLCJjdXJzb3IiLCJDb2x1bW5TdGF0c0NoYXJ0RmFjdG9yeSIsImRlcHMiLCJIaXN0b2dyYW1QbG90RmFjdG9yeSIsIkhpc3RvZ3JhbVBsb3QiLCJDb2x1bW5TdGF0c0NoYXJ0IiwiX3JlZjMiLCJhbGxCaW5zIiwiZmlsdGVyZWRCaW5zIiwiaXNGaWx0ZXJlZCIsImhpc3RvZ3JhbURvbWFpbiIsImNvbG9yQnJlYWtzIiwib25DaGFuZ2VkVXBkYXRlciIsIl91c2VTdGF0ZTUiLCJfdXNlU3RhdGU2IiwidGlja3MiLCJzZXRUaWNrcyIsIl91c2VEaW1lbnNpb25zIiwidXNlRGltZW5zaW9ucyIsIl91c2VEaW1lbnNpb25zMiIsInNpemUiLCJpc1RpY2tDaGFuZ2luZ1JlZiIsIlJlYWN0IiwiaGlzdG9ncmFtc0J5R3JvdXAiLCJ1c2VNZW1vIiwiYmlucyIsImRvbWFpbkNvbG9ycyIsImMiLCJkYXRhIiwidGlja1Bvc2l0aW9ucyIsIl9oaXN0b2dyYW1Eb21haW4iLCJ2YWx1ZU1pbiIsInZhbHVlTWF4Iiwid2lkdGhTY2FsZSIsInNjYWxlTGluZWFyIiwiZG9tYWluIiwicmFuZ2UiLCJzbGljZSIsImNiIiwicG9zIiwiZG9tYWluQ29sb3JXaWR0aHMiLCJ3aWR0aHMiLCJvblRpY2tNb3ZpbmdIYW5kbGVyIiwibmV3VGlja1Bvc2l0aW9ucyIsIl9oaXN0b2dyYW1Eb21haW4yIiwidmFsdWVSYW5nZSIsImJyZWFrcyIsImVsZW1lbnQiLCJsZWZ0VmFsdWUiLCJyaWdodFZhbHVlIiwiaW5wdXRzIiwibGFiZWwiLCJvblRpY2tDaGFuZ2VkSGFuZGxlciIsImNvbG9yV2lkdGhzIiwiY29sb3JzQnlHcm91cCIsImlzTWFza2VkIiwiSElTVE9HUkFNX01BU0tfTU9ERSIsIk1hc2tXaXRoT3ZlcmxheSIsIk1hc2siLCJ2YWx1ZSIsIm1hcmdpbiIsImJyZWFrTGluZXMiLCJDb2x1bW5TdGF0c0NoYXJ0V0xvYWRpbmciLCJfcmVmNCIsImNvbG9yRmllbGQiLCJkYXRhc2V0IiwiZmllbGROYW1lIiwibmFtZSIsImZpZWxkIiwiZ2V0Q29sdW1uRmllbGQiLCJpc051bWVyaWNDb2xvckJyZWFrcyIsImlzTG9hZGluZ1N0YXRzIiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zcmMvY29tbW9uL2NvbHVtbi1zdGF0cy1jaGFydC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHtmb3JtYXQgYXMgZDNGb3JtYXR9IGZyb20gJ2QzLWZvcm1hdCc7XG5pbXBvcnQge3NjYWxlTGluZWFyfSBmcm9tICdkMy1zY2FsZSc7XG5pbXBvcnQgUmVhY3QsIHt1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VNZW1vLCB1c2VSZWYsIHVzZVN0YXRlfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgc3R5bGVkIGZyb20gJ3N0eWxlZC1jb21wb25lbnRzJztcblxuaW1wb3J0IHtLZXBsZXJUYWJsZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge0JpbiwgRmllbGR9IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtcbiAgQ29sb3JCcmVhayxcbiAgQ29sb3JCcmVha09yZGluYWwsXG4gIGlzTnVtYmVyLFxuICBpc051bWVyaWNDb2xvckJyZWFrcyxcbiAgdXNlRGltZW5zaW9uc1xufSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IENvbG9yUGFsZXR0ZSBmcm9tICcuLi9zaWRlLXBhbmVsL2xheWVyLXBhbmVsL2NvbG9yLXBhbGV0dGUnO1xuaW1wb3J0IEhpc3RvZ3JhbVBsb3RGYWN0b3J5LCB7SElTVE9HUkFNX01BU0tfTU9ERX0gZnJvbSAnLi9oaXN0b2dyYW0tcGxvdCc7XG5pbXBvcnQgTG9hZGluZ1NwaW5uZXIgZnJvbSAnLi9sb2FkaW5nLXNwaW5uZXInO1xuXG5leHBvcnQgY29uc3QgSElTVE9HUkFNX1dJRFRIID0gMjEwO1xuZXhwb3J0IGNvbnN0IEhJU1RPR1JBTV9IRUlHSFQgPSA4MDtcbmNvbnN0IEhJU1RPR1JBTV9NQVJHSU4gPSB7dG9wOiAxMCwgYm90dG9tOiA4LCBsZWZ0OiAxMCwgcmlnaHQ6IDIwfTtcbmNvbnN0IENPTE9SX0NIQVJUX1RJQ0tfV1JBUFBFUl9IRUlHSFQgPSAxMDtcbmNvbnN0IENPTE9SX0NIQVJUX1RJQ0tfSEVJR0hUID0gODtcbmNvbnN0IENPTE9SX0NIQVJUX1RJQ0tfV0lEVEggPSA0O1xuY29uc3QgQ09MT1JfQ0hBUlRfVElDS19CT1JERVJfQ09MT1IgPSAnIzk5OTk5OSc7XG5cbmNvbnN0IFN0eWxlZENvbnRhaW5lciA9IHN0eWxlZC5kaXYuYXR0cnMoe1xuICBjbGFzc05hbWU6ICdjb2xvci1jaGFydC1sb2FkaW5nJ1xufSlgXG4gIGhlaWdodDogJHtISVNUT0dSQU1fSEVJR0hUfXB4O1xuYDtcblxuLy8gaGVpZ2h0IDE0MiA9IDE4ICsgMTEwICsgMTBcbmNvbnN0IENvbG9yQ2hhcnRDb250YWluZXIgPSBzdHlsZWQuZGl2LmF0dHJzKHtcbiAgY2xhc3NOYW1lOiAnY29sb3ItY2hhcnQtY29udGFpbmVyJ1xufSlgXG4gIG1hcmdpbi10b3A6IDhweDtcbmA7XG5cbmNvbnN0IENvbG9yQ2hhcnRIZWFkZXJXcmFwcGVyID0gc3R5bGVkLmRpdi5hdHRycyh7XG4gIGNsYXNzTmFtZTogJ2NvbG9yLWNoYXJ0LWhlYWRlcidcbn0pYFxuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbiAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUudGV4dENvbG9yfTtcbiAgbWFyZ2luLWxlZnQ6ICR7SElTVE9HUkFNX01BUkdJTi5sZWZ0fXB4O1xuICBtYXJnaW4tcmlnaHQ6ICR7SElTVE9HUkFNX01BUkdJTi5yaWdodH1weDtcbiAgZm9udC1zaXplOiA5cHg7XG5gO1xuXG5jb25zdCBDb2xvckNoYXJ0SGVhZGVySXRlbSA9IHN0eWxlZC5kaXZgXG4gIHdpZHRoOiAzMyU7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG5gO1xuXG5jb25zdCBDb2xvckNoYXJ0V3JhcHBlciA9IHN0eWxlZC5kaXYuYXR0cnMoe1xuICBjbGFzc05hbWU6ICdjb2xvci1jaGFydC13cmFwcGVyJ1xufSlgXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgaGVpZ2h0OiAke0hJU1RPR1JBTV9IRUlHSFQgKyAzMH1weDtcbmA7XG5cbmNvbnN0IENvbG9yUGFsZXR0ZVdyYXBwZXIgPSBzdHlsZWQuZGl2LmF0dHJzKHtcbiAgY2xhc3NOYW1lOiAnY29sb3ItY2hhcnQtcGFsZXR0ZSdcbn0pYFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIG1hcmdpbi10b3A6ICR7SElTVE9HUkFNX01BUkdJTi50b3B9cHg7XG4gIG1hcmdpbi1sZWZ0OiAke0hJU1RPR1JBTV9NQVJHSU4ubGVmdH1weDtcbiAgbWFyZ2luLXJpZ2h0OiAke0hJU1RPR1JBTV9NQVJHSU4ucmlnaHR9cHg7XG5gO1xuXG5jb25zdCBIaXN0b2dyYW1XcmFwcGVyID0gc3R5bGVkLmRpdi5hdHRycyh7XG4gIGNsYXNzTmFtZTogJ2NvbG9yLWNoYXJ0LWhpc3RvZ3JhbSdcbn0pYFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XG5gO1xuXG5jb25zdCBDb2xvckNoYXJ0VGlja0NvbnRhaW5lciA9IHN0eWxlZC5kaXYuYXR0cnMoe1xuICBjbGFzc05hbWU6ICdjb2xvci1jaGFydC10aWNrLWNvbnRhaW5lcidcbn0pYFxuICBoZWlnaHQ6ICR7Q09MT1JfQ0hBUlRfVElDS19XUkFQUEVSX0hFSUdIVH1weDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBtYXJnaW4tbGVmdDogJHtISVNUT0dSQU1fTUFSR0lOLmxlZnR9cHg7XG4gIG1hcmdpbi1yaWdodDogJHtISVNUT0dSQU1fTUFSR0lOLnJpZ2h0fXB4O1xuYDtcblxuZXhwb3J0IGNvbnN0IENvbG9yQ2hhcnRIZWFkZXIgPSAoe21pblZhbCwgbWVhblZhbCwgbWF4VmFsfSkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxDb2xvckNoYXJ0SGVhZGVyV3JhcHBlcj5cbiAgICAgIDxDb2xvckNoYXJ0SGVhZGVySXRlbSB0aXRsZT17bWluVmFsfT5NSU46IHttaW5WYWx9PC9Db2xvckNoYXJ0SGVhZGVySXRlbT5cbiAgICAgIDxDb2xvckNoYXJ0SGVhZGVySXRlbSB0aXRsZT17bWVhblZhbH0+TUVBTjoge2QzRm9ybWF0KCcuNH5yJykobWVhblZhbCl9PC9Db2xvckNoYXJ0SGVhZGVySXRlbT5cbiAgICAgIDxDb2xvckNoYXJ0SGVhZGVySXRlbSB0aXRsZT17bWF4VmFsfSBzdHlsZT17e3RleHRBbGlnbjogJ3JpZ2h0J319PlxuICAgICAgICBNQVg6IHttYXhWYWx9XG4gICAgICA8L0NvbG9yQ2hhcnRIZWFkZXJJdGVtPlxuICAgIDwvQ29sb3JDaGFydEhlYWRlcldyYXBwZXI+XG4gICk7XG59O1xuXG5leHBvcnQgdHlwZSBDb2xvckNoYXJ0VGlja1Byb3BzID0ge1xuICBjb2xvcnM6IHN0cmluZ1tdO1xuICBwb3NpdGlvbnM6IG51bWJlcltdO1xuICBvblRpY2tNb3Zpbmc6IChwb3NpdGlvbnM6IG51bWJlcltdLCBkcmFnVGljazogbnVtYmVyKSA9PiB2b2lkO1xuICBvblRpY2tDaGFuZ2VkOiAoKSA9PiB2b2lkO1xuICBoaXN0b2dyYW1XaWR0aDogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNvbnN0IENvbG9yQ2hhcnRUaWNrOiBSZWFjdC5GQzxDb2xvckNoYXJ0VGlja1Byb3BzPiA9ICh7XG4gIGNvbG9ycyxcbiAgcG9zaXRpb25zLFxuICBoaXN0b2dyYW1XaWR0aCxcbiAgb25UaWNrTW92aW5nLFxuICBvblRpY2tDaGFuZ2VkXG59KSA9PiB7XG4gIGNvbnN0IFtzdGF0ZVBvc2l0aW9ucywgc2V0UG9zaXRpb25zXSA9IHVzZVN0YXRlKHBvc2l0aW9ucyk7XG4gIGNvbnN0IFtkcmFnVGljaywgc2V0RHJhZ1RpY2tdID0gdXNlU3RhdGUoLTEpO1xuICBjb25zdCBjb250YWluZXJSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KG51bGwpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgc2V0UG9zaXRpb25zKHBvc2l0aW9ucyk7XG4gICAgc2V0RHJhZ1RpY2soZHJhZ1RpY2spO1xuICB9LCBbcG9zaXRpb25zLCBkcmFnVGlja10pO1xuXG4gIGNvbnN0IG9uTW91c2VNb3ZlID0gdXNlQ2FsbGJhY2soXG4gICAgZSA9PiB7XG4gICAgICBpZiAoZHJhZ1RpY2sgPj0gMCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IG9mZnNldFggPSBjb250YWluZXJSZWYuY3VycmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS54O1xuICAgICAgICBzdGF0ZVBvc2l0aW9uc1tkcmFnVGlja10gPSBlLmNsaWVudFggLSAob2Zmc2V0WCA/PyAwKTtcbiAgICAgICAgY29uc3QgbGVmdEJvdW5kID0gZHJhZ1RpY2sgPT09IDAgPyAwIDogc3RhdGVQb3NpdGlvbnNbZHJhZ1RpY2sgLSAxXSArIDE7XG4gICAgICAgIGNvbnN0IHJpZ2h0Qm91bmQgPVxuICAgICAgICAgIGRyYWdUaWNrID09PSBwb3NpdGlvbnMubGVuZ3RoIC0gMSA/IGhpc3RvZ3JhbVdpZHRoIDogc3RhdGVQb3NpdGlvbnNbZHJhZ1RpY2sgKyAxXSAtIDE7XG5cbiAgICAgICAgLy8gcmVzdHJpY3QgdXNlciBkcmFnLW4tbW92ZSBiZXR3ZWVuIGxlZnQgYW5kIHJpZ2h0IG5laWdoYm9yaW5nIHRpY2tzXG4gICAgICAgIGlmIChzdGF0ZVBvc2l0aW9uc1tkcmFnVGlja10gPCBsZWZ0Qm91bmQpIHtcbiAgICAgICAgICBzdGF0ZVBvc2l0aW9uc1tkcmFnVGlja10gPSBsZWZ0Qm91bmQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlUG9zaXRpb25zW2RyYWdUaWNrXSA+IHJpZ2h0Qm91bmQpIHtcbiAgICAgICAgICBzdGF0ZVBvc2l0aW9uc1tkcmFnVGlja10gPSByaWdodEJvdW5kO1xuICAgICAgICB9XG4gICAgICAgIHNldFBvc2l0aW9ucyhbLi4uc3RhdGVQb3NpdGlvbnNdKTtcbiAgICAgICAgb25UaWNrTW92aW5nKHN0YXRlUG9zaXRpb25zLCBkcmFnVGljayk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbZHJhZ1RpY2ssIG9uVGlja01vdmluZywgcG9zaXRpb25zLmxlbmd0aCwgc3RhdGVQb3NpdGlvbnMsIGhpc3RvZ3JhbVdpZHRoXVxuICApO1xuXG4gIGNvbnN0IG9uTW91c2VVcCA9IHVzZUNhbGxiYWNrKFxuICAgIGUgPT4ge1xuICAgICAgaWYgKGRyYWdUaWNrID49IDApIHtcbiAgICAgICAgb25UaWNrQ2hhbmdlZCgpO1xuICAgICAgICBzZXREcmFnVGljaygtMSk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtkcmFnVGljaywgb25UaWNrQ2hhbmdlZF1cbiAgKTtcblxuICBjb25zdCBvbk1vdXNlRG93biA9IHVzZUNhbGxiYWNrKChlLCB0aWNrSW5kZXgpID0+IHtcbiAgICBpZiAoaXNOdW1iZXIodGlja0luZGV4KSkge1xuICAgICAgc2V0RHJhZ1RpY2sodGlja0luZGV4KTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8Q29sb3JDaGFydFRpY2tDb250YWluZXJcbiAgICAgIHJlZj17Y29udGFpbmVyUmVmfVxuICAgICAgb25Nb3VzZU1vdmU9e29uTW91c2VNb3ZlfVxuICAgICAgb25Nb3VzZVVwPXtvbk1vdXNlVXB9XG4gICAgICBvbk1vdXNlTGVhdmU9e29uTW91c2VVcH1cbiAgICA+XG4gICAgICB7Y29sb3JzLm1hcCgoY29sb3IsIGluZGV4KSA9PiAoXG4gICAgICAgIDxkaXZcbiAgICAgICAgICBkcmFnZ2FibGU9e3RydWV9XG4gICAgICAgICAga2V5PXtgY29sb3ItY2hhcnQtdGljay0ke2NvbG9yfS0ke2luZGV4fWB9XG4gICAgICAgICAgb25Nb3VzZURvd249e2UgPT4gb25Nb3VzZURvd24oZSwgaW5kZXgpfVxuICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9yLFxuICAgICAgICAgICAgbGVmdDogYCR7c3RhdGVQb3NpdGlvbnNbaW5kZXhdIC0gQ09MT1JfQ0hBUlRfVElDS19XSURUSCAvIDIgLSAxfXB4YCxcbiAgICAgICAgICAgIGJvcmRlcldpZHRoOiBgMXB4YCxcbiAgICAgICAgICAgIGJvcmRlclN0eWxlOiAnc29saWQnLFxuICAgICAgICAgICAgYm9yZGVyQ29sb3I6IENPTE9SX0NIQVJUX1RJQ0tfQk9SREVSX0NPTE9SLFxuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICB3aWR0aDogYCR7Q09MT1JfQ0hBUlRfVElDS19XSURUSH1weGAsXG4gICAgICAgICAgICBoZWlnaHQ6IGAke0NPTE9SX0NIQVJUX1RJQ0tfSEVJR0hUfXB4YCxcbiAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInXG4gICAgICAgICAgfX1cbiAgICAgICAgLz5cbiAgICAgICkpfVxuICAgIDwvQ29sb3JDaGFydFRpY2tDb250YWluZXI+XG4gICk7XG59O1xuXG4vLyBvbmx5IGZvciBudW1ldGljIGZpZWxkXG5Db2x1bW5TdGF0c0NoYXJ0RmFjdG9yeS5kZXBzID0gW0hpc3RvZ3JhbVBsb3RGYWN0b3J5XTtcblxuZXhwb3J0IHR5cGUgQ29sdW1uU3RhdHNDaGFydFdMb2FkaW5nUHJvcHMgPSB7XG4gIGNvbG9yRmllbGQ6IEZpZWxkO1xuICBkYXRhc2V0OiBLZXBsZXJUYWJsZTtcbiAgY29sb3JCcmVha3M6IENvbG9yQnJlYWtbXSB8IENvbG9yQnJlYWtPcmRpbmFsW10gfCBudWxsO1xuICBhbGxCaW5zOiBCaW5bXTtcbiAgZmlsdGVyZWRCaW5zOiBCaW5bXTtcbiAgaXNGaWx0ZXJlZDogYm9vbGVhbjtcbiAgaGlzdG9ncmFtRG9tYWluOiBudW1iZXJbXTtcbiAgb25DaGFuZ2VkVXBkYXRlcjogKHRpY2tzOiBDb2xvckJyZWFrW10pID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgdHlwZSBDb2x1bW5TdGF0c0NoYXJ0UHJvcHMgPSB7XG4gIGFsbEJpbnM6IEJpbltdO1xuICBmaWx0ZXJlZEJpbnM6IEJpbltdO1xuICBpc0ZpbHRlcmVkOiBib29sZWFuO1xuICBoaXN0b2dyYW1Eb21haW46IG51bWJlcltdO1xuICBjb2xvckJyZWFrczogQ29sb3JCcmVha1tdO1xuICBvbkNoYW5nZWRVcGRhdGVyOiAodGlja3M6IENvbG9yQnJlYWtbXSkgPT4gdm9pZDtcbn07XG5mdW5jdGlvbiBDb2x1bW5TdGF0c0NoYXJ0RmFjdG9yeShcbiAgSGlzdG9ncmFtUGxvdDogUmV0dXJuVHlwZTx0eXBlb2YgSGlzdG9ncmFtUGxvdEZhY3Rvcnk+XG4pOiBSZWFjdC5GQzxDb2x1bW5TdGF0c0NoYXJ0V0xvYWRpbmdQcm9wcz4ge1xuICBjb25zdCBDb2x1bW5TdGF0c0NoYXJ0OiBSZWFjdC5GQzxDb2x1bW5TdGF0c0NoYXJ0UHJvcHM+ID0gKHtcbiAgICBhbGxCaW5zLFxuICAgIGZpbHRlcmVkQmlucyxcbiAgICBpc0ZpbHRlcmVkLFxuICAgIGhpc3RvZ3JhbURvbWFpbixcbiAgICBjb2xvckJyZWFrcyxcbiAgICBvbkNoYW5nZWRVcGRhdGVyXG4gIH0pID0+IHtcbiAgICBjb25zdCBbdGlja3MsIHNldFRpY2tzXSA9IHVzZVN0YXRlKGNvbG9yQnJlYWtzKTtcbiAgICBjb25zdCBbcmVmLCBzaXplXSA9IHVzZURpbWVuc2lvbnM8SFRNTERpdkVsZW1lbnQ+KCk7XG4gICAgY29uc3QgaGlzdG9ncmFtV2lkdGggPSBzaXplXG4gICAgICA/IHNpemUud2lkdGggLSBISVNUT0dSQU1fTUFSR0lOLmxlZnQgLSBISVNUT0dSQU1fTUFSR0lOLnJpZ2h0XG4gICAgICA6IEhJU1RPR1JBTV9XSURUSDtcblxuICAgIC8vIGRpc3Rpbmd1aXNoIGJldHdlZW4gcHJvcHMuY29sb3JCcmVha3MgYW5kIHN0YXRlcy50aWNrc1xuICAgIGNvbnN0IGlzVGlja0NoYW5naW5nUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICBzZXRUaWNrcyh0aWNrcyk7XG4gICAgICAvLyByZXNldCBpc1RpY2tDaGFuZ2luZyBvbmNlIGhpc3RvZ3JhbSBkb21haW4gaXMgcmVjb21wdXRlZFxuICAgICAgaXNUaWNrQ2hhbmdpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIH0sIFt0aWNrc10pO1xuXG4gICAgLy8gaGlzdG9ncmFtcyB1c2VkIGJ5IGhpc3RvZ3JhbS1wbG90LmpzXG4gICAgY29uc3QgaGlzdG9ncmFtc0J5R3JvdXAgPSB1c2VNZW1vKFxuICAgICAgKCkgPT4gKHtcbiAgICAgICAgYmluczogYWxsQmlucyxcbiAgICAgICAgZmlsdGVyZWRCaW5zXG4gICAgICB9KSxcbiAgICAgIFthbGxCaW5zLCBmaWx0ZXJlZEJpbnNdXG4gICAgKTtcblxuICAgIC8vIGdldCBjb2xvcnMgZnJvbSBjb2xvckJyZWFrc1xuICAgIGNvbnN0IGRvbWFpbkNvbG9ycyA9IHVzZU1lbW8oXG4gICAgICAoKSA9PiAoY29sb3JCcmVha3MgPyBjb2xvckJyZWFrcy5tYXAoYyA9PiBjLmRhdGEpIDogW10pLFxuICAgICAgW2NvbG9yQnJlYWtzXVxuICAgICk7XG5cbiAgICBjb25zdCB0aWNrUG9zaXRpb25zID0gdXNlTWVtbygoKSA9PiB7XG4gICAgICBpZiAoIWlzVGlja0NoYW5naW5nUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgc2V0VGlja3MoY29sb3JCcmVha3MpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbdmFsdWVNaW4sIHZhbHVlTWF4XSA9IGhpc3RvZ3JhbURvbWFpbjtcbiAgICAgIGNvbnN0IHdpZHRoU2NhbGUgPSBzY2FsZUxpbmVhcigpLmRvbWFpbihbdmFsdWVNaW4sIHZhbHVlTWF4XSkucmFuZ2UoWzAsIGhpc3RvZ3JhbVdpZHRoXSk7XG4gICAgICByZXR1cm4gdGlja3Muc2xpY2UoMCwgLTEpLm1hcChjYiA9PiB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHdpZHRoU2NhbGUoY2IucmFuZ2VbMV0pO1xuICAgICAgICBpZiAocG9zIDwgMCkgcmV0dXJuIDA7XG4gICAgICAgIGVsc2UgaWYgKHBvcyA+IGhpc3RvZ3JhbVdpZHRoKSByZXR1cm4gaGlzdG9ncmFtV2lkdGg7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgICB9KTtcbiAgICB9LCBbaGlzdG9ncmFtRG9tYWluLCB0aWNrcywgY29sb3JCcmVha3MsIGhpc3RvZ3JhbVdpZHRoXSk7XG5cbiAgICBjb25zdCBkb21haW5Db2xvcldpZHRocyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgICAgY29uc3QgbiA9IHRpY2tQb3NpdGlvbnMubGVuZ3RoO1xuICAgICAgY29uc3Qgd2lkdGhzID0gW3RpY2tQb3NpdGlvbnNbMF1dO1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgd2lkdGhzLnB1c2godGlja1Bvc2l0aW9uc1tpXSAtIHRpY2tQb3NpdGlvbnNbaSAtIDFdKTtcbiAgICAgIH1cbiAgICAgIHdpZHRocy5wdXNoKGhpc3RvZ3JhbVdpZHRoIC0gdGlja1Bvc2l0aW9uc1tuIC0gMV0pO1xuICAgICAgcmV0dXJuIHdpZHRocztcbiAgICB9LCBbdGlja1Bvc2l0aW9ucywgaGlzdG9ncmFtV2lkdGhdKTtcblxuICAgIC8vIGhhbmRsZSB0aWNrIGRyYWctbi1tb3ZlXG4gICAgY29uc3Qgb25UaWNrTW92aW5nSGFuZGxlciA9IHVzZUNhbGxiYWNrKFxuICAgICAgKG5ld1RpY2tQb3NpdGlvbnMsIHRpY2tJbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBbdmFsdWVNaW4sIHZhbHVlTWF4XSA9IGhpc3RvZ3JhbURvbWFpbjtcbiAgICAgICAgY29uc3QgdmFsdWVSYW5nZSA9IHZhbHVlTWF4IC0gdmFsdWVNaW47XG4gICAgICAgIGNvbnN0IGJyZWFrcyA9IFt2YWx1ZU1pbl07XG4gICAgICAgIG5ld1RpY2tQb3NpdGlvbnMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgICBicmVha3MucHVzaCh2YWx1ZU1pbiArICh2YWx1ZVJhbmdlICogZWxlbWVudCkgLyBoaXN0b2dyYW1XaWR0aCk7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVha3MucHVzaCh2YWx1ZU1heCk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aWNrcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGNvbnN0IGxlZnRWYWx1ZSA9IGkgPT09IHRpY2tJbmRleCArIDEgPyBicmVha3NbaV0gOiB0aWNrc1tpXS5yYW5nZVswXTtcbiAgICAgICAgICBjb25zdCByaWdodFZhbHVlID0gaSArIDEgPT09IHRpY2tJbmRleCArIDEgPyBicmVha3NbaSArIDFdIDogdGlja3NbaV0ucmFuZ2VbMV07XG5cbiAgICAgICAgICB0aWNrc1tpXSA9IHtcbiAgICAgICAgICAgIC4uLnRpY2tzW2ldLFxuICAgICAgICAgICAgcmFuZ2U6IFtsZWZ0VmFsdWUsIHJpZ2h0VmFsdWVdLFxuICAgICAgICAgICAgaW5wdXRzOiBbbGVmdFZhbHVlLCByaWdodFZhbHVlXSxcbiAgICAgICAgICAgIGxhYmVsOiBgJHtkM0Zvcm1hdCgnLjJmJykoYnJlYWtzW2ldKX0gdG8gJHtkM0Zvcm1hdCgnLjJmJykoYnJlYWtzW2kgKyAxXSl9YFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaXNUaWNrQ2hhbmdpbmdSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICAgIHNldFRpY2tzKFsuLi50aWNrc10pO1xuICAgICAgfSxcbiAgICAgIFtoaXN0b2dyYW1Eb21haW4sIHRpY2tzLCBoaXN0b2dyYW1XaWR0aF1cbiAgICApO1xuXG4gICAgLy8gdXBkYXRlIHBhcmVudCBhbmQgc2libGluZyBjb21wb25lbnRzIHdoZW4gdGljayBkcmFnZ2luZyBlbmRlZFxuICAgIGNvbnN0IG9uVGlja0NoYW5nZWRIYW5kbGVyID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgb25DaGFuZ2VkVXBkYXRlcih0aWNrcyk7XG4gICAgfSwgW29uQ2hhbmdlZFVwZGF0ZXIsIHRpY2tzXSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPENvbG9yQ2hhcnRDb250YWluZXIgcmVmPXtyZWZ9PlxuICAgICAgICA8Q29sb3JDaGFydEhlYWRlclxuICAgICAgICAgIG1pblZhbD17aGlzdG9ncmFtRG9tYWluWzBdfVxuICAgICAgICAgIG1heFZhbD17aGlzdG9ncmFtRG9tYWluWzFdfVxuICAgICAgICAgIG1lYW5WYWw9e2hpc3RvZ3JhbURvbWFpblsyXX1cbiAgICAgICAgLz5cbiAgICAgICAgPENvbG9yQ2hhcnRXcmFwcGVyPlxuICAgICAgICAgIDxDb2xvclBhbGV0dGVXcmFwcGVyPlxuICAgICAgICAgICAgPENvbG9yUGFsZXR0ZVxuICAgICAgICAgICAgICBjb2xvcnM9e2RvbWFpbkNvbG9yc31cbiAgICAgICAgICAgICAgY29sb3JXaWR0aHM9e2RvbWFpbkNvbG9yV2lkdGhzfVxuICAgICAgICAgICAgICBoZWlnaHQ9e0hJU1RPR1JBTV9IRUlHSFQgKyAxNn1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9Db2xvclBhbGV0dGVXcmFwcGVyPlxuICAgICAgICAgIDxIaXN0b2dyYW1XcmFwcGVyPlxuICAgICAgICAgICAgPEhpc3RvZ3JhbVBsb3RcbiAgICAgICAgICAgICAgaGlzdG9ncmFtc0J5R3JvdXA9e2hpc3RvZ3JhbXNCeUdyb3VwfVxuICAgICAgICAgICAgICBjb2xvcnNCeUdyb3VwPXtudWxsfVxuICAgICAgICAgICAgICBpc01hc2tlZD17aXNGaWx0ZXJlZCA/IEhJU1RPR1JBTV9NQVNLX01PREUuTWFza1dpdGhPdmVybGF5IDogSElTVE9HUkFNX01BU0tfTU9ERS5NYXNrfVxuICAgICAgICAgICAgICB2YWx1ZT17aGlzdG9ncmFtRG9tYWlufVxuICAgICAgICAgICAgICB3aWR0aD17aGlzdG9ncmFtV2lkdGh9XG4gICAgICAgICAgICAgIGhlaWdodD17SElTVE9HUkFNX0hFSUdIVH1cbiAgICAgICAgICAgICAgbWFyZ2luPXtISVNUT0dSQU1fTUFSR0lOfVxuICAgICAgICAgICAgICBicmVha0xpbmVzPXt0aWNrUG9zaXRpb25zfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L0hpc3RvZ3JhbVdyYXBwZXI+XG4gICAgICAgIDwvQ29sb3JDaGFydFdyYXBwZXI+XG4gICAgICAgIDxDb2xvckNoYXJ0VGlja1xuICAgICAgICAgIGNvbG9ycz17ZG9tYWluQ29sb3JzLnNsaWNlKDAsIC0xKX1cbiAgICAgICAgICBwb3NpdGlvbnM9e3RpY2tQb3NpdGlvbnN9XG4gICAgICAgICAgaGlzdG9ncmFtV2lkdGg9e2hpc3RvZ3JhbVdpZHRofVxuICAgICAgICAgIG9uVGlja01vdmluZz17b25UaWNrTW92aW5nSGFuZGxlcn1cbiAgICAgICAgICBvblRpY2tDaGFuZ2VkPXtvblRpY2tDaGFuZ2VkSGFuZGxlcn1cbiAgICAgICAgLz5cbiAgICAgIDwvQ29sb3JDaGFydENvbnRhaW5lcj5cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IENvbHVtblN0YXRzQ2hhcnRXTG9hZGluZzogUmVhY3QuRkM8Q29sdW1uU3RhdHNDaGFydFdMb2FkaW5nUHJvcHM+ID0gKHtcbiAgICBjb2xvckZpZWxkLFxuICAgIGRhdGFzZXQsXG4gICAgY29sb3JCcmVha3MsXG4gICAgYWxsQmlucyxcbiAgICBmaWx0ZXJlZEJpbnMsXG4gICAgaXNGaWx0ZXJlZCxcbiAgICBoaXN0b2dyYW1Eb21haW4sXG4gICAgb25DaGFuZ2VkVXBkYXRlclxuICB9KSA9PiB7XG4gICAgY29uc3QgZmllbGROYW1lID0gY29sb3JGaWVsZD8ubmFtZTtcbiAgICBjb25zdCBmaWVsZCA9IHVzZU1lbW8oXG4gICAgICAoKSA9PiAoZmllbGROYW1lID8gZGF0YXNldC5nZXRDb2x1bW5GaWVsZChmaWVsZE5hbWUpIDogbnVsbCksXG4gICAgICBbZGF0YXNldCwgZmllbGROYW1lXVxuICAgICk7XG5cbiAgICBpZiAoIWlzTnVtZXJpY0NvbG9yQnJlYWtzKGNvbG9yQnJlYWtzKSkge1xuICAgICAgLy8gVE9ETzogaW1wbGVtZW50IGRpc3BsYXkgZm9yIG9yZGluYWwgYnJlYWtzXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoZmllbGQ/LmlzTG9hZGluZ1N0YXRzKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8U3R5bGVkQ29udGFpbmVyPlxuICAgICAgICAgIDxMb2FkaW5nU3Bpbm5lciAvPlxuICAgICAgICA8L1N0eWxlZENvbnRhaW5lcj5cbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIDxDb2x1bW5TdGF0c0NoYXJ0XG4gICAgICAgIGNvbG9yQnJlYWtzPXtjb2xvckJyZWFrc31cbiAgICAgICAgYWxsQmlucz17YWxsQmluc31cbiAgICAgICAgZmlsdGVyZWRCaW5zPXtmaWx0ZXJlZEJpbnN9XG4gICAgICAgIGlzRmlsdGVyZWQ9e2lzRmlsdGVyZWR9XG4gICAgICAgIGhpc3RvZ3JhbURvbWFpbj17aGlzdG9ncmFtRG9tYWlufVxuICAgICAgICBvbkNoYW5nZWRVcGRhdGVyPXtvbkNoYW5nZWRVcGRhdGVyfVxuICAgICAgLz5cbiAgICApO1xuICB9O1xuXG4gIHJldHVybiBDb2x1bW5TdGF0c0NoYXJ0V0xvYWRpbmc7XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvbHVtblN0YXRzQ2hhcnRGYWN0b3J5O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFH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