kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
410 lines (342 loc) • 49 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pointVisConfigs = exports.iconResolver = exports.iconRequiredColumns = exports.iconPosResolver = exports.iconPosAccessor = exports.iconAccessor = exports["default"] = exports.SVG_ICON_URL = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _baseLayer = _interopRequireDefault(require("../base-layer"));
var _lodash = _interopRequireDefault(require("lodash.memoize"));
var _window = _interopRequireDefault(require("global/window"));
var _colorUtils = require("../../utils/color-utils");
var _svgIconLayer = _interopRequireDefault(require("../../deckgl-layers/svg-icon-layer/svg-icon-layer"));
var _iconLayerIcon = _interopRequireDefault(require("./icon-layer-icon"));
var _defaultSettings = require("../../constants/default-settings");
var _iconInfoModal = _interopRequireDefault(require("./icon-info-modal"));
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == (0, _typeof2["default"])(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError((0, _typeof2["default"])(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var SVG_ICON_URL = exports.SVG_ICON_URL = "".concat(_defaultSettings.CLOUDFRONT, "/icons/svg-icons.json");
var iconPosAccessor = exports.iconPosAccessor = function iconPosAccessor(_ref) {
var lat = _ref.lat,
lng = _ref.lng;
return function (d) {
return [d.data[lng.fieldIdx], d.data[lat.fieldIdx]];
};
};
var iconPosResolver = exports.iconPosResolver = function iconPosResolver(_ref2) {
var lat = _ref2.lat,
lng = _ref2.lng;
return "".concat(lat.fieldIdx, "-").concat(lng.fieldIdx);
};
var iconAccessor = exports.iconAccessor = function iconAccessor(_ref3) {
var icon = _ref3.icon;
return function (d) {
return d.data[icon.fieldIdx];
};
};
var iconResolver = exports.iconResolver = function iconResolver(_ref4) {
var icon = _ref4.icon;
return icon.fieldIdx;
};
var iconRequiredColumns = exports.iconRequiredColumns = ['lat', 'lng', 'icon'];
var pointVisConfigs = exports.pointVisConfigs = {
radius: 'radius',
fixedRadius: 'fixedRadius',
opacity: 'opacity',
colorRange: 'colorRange',
radiusRange: 'radiusRange'
};
var IconLayer = exports["default"] = /*#__PURE__*/function (_Layer) {
(0, _inherits2["default"])(IconLayer, _Layer);
var _super = _createSuper(IconLayer);
function IconLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, IconLayer);
_this = _super.call(this, props);
_this.registerVisConfig(pointVisConfigs);
_this.getPosition = (0, _lodash["default"])(iconPosAccessor, iconPosResolver);
_this.getIcon = (0, _lodash["default"])(iconAccessor, iconResolver); // prepare layer info modal
_this._layerInfoModal = (0, _iconInfoModal["default"])();
_this.getSvgIcons();
return _this;
}
(0, _createClass2["default"])(IconLayer, [{
key: "type",
get: function get() {
return 'icon';
}
}, {
key: "requiredLayerColumns",
get: function get() {
return iconRequiredColumns;
}
}, {
key: "columnPairs",
get: function get() {
return this.defaultPointColumnPairs;
}
}, {
key: "layerIcon",
get: function get() {
return _iconLayerIcon["default"];
}
}, {
key: "visualChannels",
get: function get() {
return _objectSpread(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(IconLayer.prototype), "visualChannels", this)), {}, {
size: _objectSpread(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(IconLayer.prototype), "visualChannels", this).size), {}, {
range: 'radiusRange',
property: 'radius',
channelScaleType: 'radius'
})
});
}
}, {
key: "layerInfoModal",
get: function get() {
return {
id: 'iconInfo',
template: this._layerInfoModal,
modalProps: {
title: 'How to draw icons'
}
};
}
}, {
key: "getSvgIcons",
value: function () {
var _getSvgIcons = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
var fetchConfig, response, _ref6, svgIcons;
return _regeneratorRuntime().wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
fetchConfig = {
method: 'GET',
mode: 'cors',
cache: 'no-cache'
};
if (!_window["default"].fetch) {
_context.next = 11;
break;
}
_context.next = 4;
return _window["default"].fetch(SVG_ICON_URL, fetchConfig);
case 4:
response = _context.sent;
_context.next = 7;
return response.json();
case 7:
_ref6 = _context.sent;
svgIcons = _ref6.svgIcons;
this.iconGeometry = svgIcons.reduce(function (accu, curr) {
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, curr.id, curr.mesh.cells.reduce(function (prev, cell) {
cell.forEach(function (p) {
Array.prototype.push.apply(prev, curr.mesh.positions[p]);
});
return prev;
}, [])));
}, {});
this._layerInfoModal = (0, _iconInfoModal["default"])(svgIcons);
case 11:
case "end":
return _context.stop();
}
}, _callee, this);
}));
function getSvgIcons() {
return _getSvgIcons.apply(this, arguments);
}
return getSvgIcons;
}()
}, {
key: "formatLayerData",
value: // TODO: fix complexity
/* eslint-disable complexity */
function formatLayerData(_, allData, filteredIndex, oldLayerData) {
var _this2 = this;
var opt = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
var _this$config = this.config,
colorScale = _this$config.colorScale,
colorDomain = _this$config.colorDomain,
colorField = _this$config.colorField,
color = _this$config.color,
columns = _this$config.columns,
sizeField = _this$config.sizeField,
sizeScale = _this$config.sizeScale,
sizeDomain = _this$config.sizeDomain,
_this$config$visConfi = _this$config.visConfig,
radiusRange = _this$config$visConfi.radiusRange,
colorRange = _this$config$visConfi.colorRange; // point color
var cScale = colorField && this.getVisChannelScale(colorScale, colorDomain, colorRange.colors.map(_colorUtils.hexToRgb)); // point radius
var rScale = sizeField && this.getVisChannelScale(sizeScale, sizeDomain, radiusRange, 0);
var getPosition = this.getPosition(columns);
var getIcon = this.getIcon(columns);
if (!oldLayerData || oldLayerData.getPosition !== getPosition) {
this.updateLayerMeta(allData, getPosition);
}
var data;
if (oldLayerData && oldLayerData.data && opt.sameData && oldLayerData.getPosition === getPosition && oldLayerData.getIcon === getIcon) {
data = oldLayerData.data;
} else {
data = filteredIndex.reduce(function (accu, index) {
var pos = getPosition({
data: allData[index]
});
var icon = getIcon({
data: allData[index]
}); // 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') {
return accu;
}
accu.push({
index: index,
icon: icon,
data: allData[index]
});
return accu;
}, []);
}
var getRadius = rScale ? function (d) {
return _this2.getEncodedChannelValue(rScale, d.data, sizeField, 0);
} : 1;
var getColor = cScale ? function (d) {
return _this2.getEncodedChannelValue(cScale, d.data, colorField);
} : color;
return {
data: data,
getPosition: getPosition,
getIcon: getIcon,
getColor: getColor,
getRadius: getRadius
};
}
/* eslint-enable complexity */
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(allData, getPosition) {
var bounds = this.getPointsBounds(allData, function (d) {
return getPosition({
data: d
});
});
this.updateMeta({
bounds: bounds
});
}
}, {
key: "renderLayer",
value: function renderLayer(_ref7) {
var _this3 = this;
var data = _ref7.data,
idx = _ref7.idx,
objectHovered = _ref7.objectHovered,
mapState = _ref7.mapState,
interactionConfig = _ref7.interactionConfig,
layerInteraction = _ref7.layerInteraction;
var layerProps = _objectSpread({
radiusMinPixels: 1,
radiusScale: this.getRadiusScaleByZoom(mapState)
}, this.config.visConfig.fixedRadius ? {} : {
radiusMaxPixels: 500
});
return !this.iconGeometry ? [] : [new _svgIconLayer["default"](_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, layerProps), data), layerInteraction), {}, {
id: this.id,
idx: idx,
opacity: this.config.visConfig.opacity,
getIconGeometry: function getIconGeometry(id) {
return _this3.iconGeometry[id];
},
// picking
autoHighlight: true,
highlightColor: this.config.highlightColor,
pickable: true,
// parameters
parameters: {
depthTest: mapState.dragRotate
},
// update triggers
updateTriggers: {
getRadius: {
sizeField: this.config.colorField,
radiusRange: this.config.visConfig.radiusRange,
sizeScale: this.config.sizeScale
},
getColor: {
color: this.config.color,
colorField: this.config.colorField,
colorRange: this.config.visConfig.colorRange,
colorScale: this.config.colorScale
}
}
}))].concat((0, _toConsumableArray2["default"])(this.isLayerHovered(objectHovered) ? [new _svgIconLayer["default"](_objectSpread(_objectSpread({}, layerProps), {}, {
id: "".concat(this.id, "-hovered"),
data: [objectHovered.object],
getPosition: data.getPosition,
getRadius: data.getRadius,
getColor: this.config.highlightColor,
getIconGeometry: function getIconGeometry(id) {
return _this3.iconGeometry[id];
},
pickable: false
}))] : []));
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(_ref8) {
var _ref8$fieldPairs = _ref8.fieldPairs,
fieldPairs = _ref8$fieldPairs === void 0 ? [] : _ref8$fieldPairs,
_ref8$fields = _ref8.fields,
fields = _ref8$fields === void 0 ? [] : _ref8$fields;
var notFound = {
props: []
};
if (!fieldPairs.length || !fields.length) {
return notFound;
}
var iconFields = fields.filter(function (_ref9) {
var name = _ref9.name;
return name.replace(/[_,.]+/g, ' ').trim().split(' ').some(function (seg) {
return _defaultSettings.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 props = iconFields.map(function (iconField) {
return {
label: iconField.name.replace(/[_,.]+/g, ' ').trim(),
columns: {
lat: ptPair.pair.lat,
lng: ptPair.pair.lng,
icon: {
value: iconField.name,
fieldIdx: iconField.tableFieldIndex - 1
}
},
isVisible: true
};
});
return {
props: props
};
}
}]);
return IconLayer;
}(_baseLayer["default"]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYXllcnMvaWNvbi1sYXllci9pY29uLWxheWVyLmpzIl0sIm5hbWVzIjpbIlNWR19JQ09OX1VSTCIsIkNMT1VERlJPTlQiLCJpY29uUG9zQWNjZXNzb3IiLCJsYXQiLCJsbmciLCJkIiwiZGF0YSIsImZpZWxkSWR4IiwiaWNvblBvc1Jlc29sdmVyIiwiaWNvbkFjY2Vzc29yIiwiaWNvbiIsImljb25SZXNvbHZlciIsImljb25SZXF1aXJlZENvbHVtbnMiLCJwb2ludFZpc0NvbmZpZ3MiLCJyYWRpdXMiLCJmaXhlZFJhZGl1cyIsIm9wYWNpdHkiLCJjb2xvclJhbmdlIiwicmFkaXVzUmFuZ2UiLCJJY29uTGF5ZXIiLCJwcm9wcyIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0UG9zaXRpb24iLCJnZXRJY29uIiwiX2xheWVySW5mb01vZGFsIiwiZ2V0U3ZnSWNvbnMiLCJkZWZhdWx0UG9pbnRDb2x1bW5QYWlycyIsIkljb25MYXllckljb24iLCJzaXplIiwicmFuZ2UiLCJwcm9wZXJ0eSIsImNoYW5uZWxTY2FsZVR5cGUiLCJpZCIsInRlbXBsYXRlIiwibW9kYWxQcm9wcyIsInRpdGxlIiwiZmV0Y2hDb25maWciLCJtZXRob2QiLCJtb2RlIiwiY2FjaGUiLCJ3aW5kb3ciLCJmZXRjaCIsInJlc3BvbnNlIiwianNvbiIsInN2Z0ljb25zIiwiaWNvbkdlb21ldHJ5IiwicmVkdWNlIiwiYWNjdSIsImN1cnIiLCJtZXNoIiwiY2VsbHMiLCJwcmV2IiwiY2VsbCIsImZvckVhY2giLCJwIiwiQXJyYXkiLCJwcm90b3R5cGUiLCJwdXNoIiwiYXBwbHkiLCJwb3NpdGlvbnMiLCJfIiwiYWxsRGF0YSIsImZpbHRlcmVkSW5kZXgiLCJvbGRMYXllckRhdGEiLCJvcHQiLCJjb25maWciLCJjb2xvclNjYWxlIiwiY29sb3JEb21haW4iLCJjb2xvckZpZWxkIiwiY29sb3IiLCJjb2x1bW5zIiwic2l6ZUZpZWxkIiwic2l6ZVNjYWxlIiwic2l6ZURvbWFpbiIsInZpc0NvbmZpZyIsImNTY2FsZSIsImdldFZpc0NoYW5uZWxTY2FsZSIsImNvbG9ycyIsIm1hcCIsImhleFRvUmdiIiwiclNjYWxlIiwidXBkYXRlTGF5ZXJNZXRhIiwic2FtZURhdGEiLCJpbmRleCIsInBvcyIsImV2ZXJ5IiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJnZXRSYWRpdXMiLCJnZXRFbmNvZGVkQ2hhbm5lbFZhbHVlIiwiZ2V0Q29sb3IiLCJib3VuZHMiLCJnZXRQb2ludHNCb3VuZHMiLCJ1cGRhdGVNZXRhIiwiaWR4Iiwib2JqZWN0SG92ZXJlZCIsIm1hcFN0YXRlIiwiaW50ZXJhY3Rpb25Db25maWciLCJsYXllckludGVyYWN0aW9uIiwibGF5ZXJQcm9wcyIsInJhZGl1c01pblBpeGVscyIsInJhZGl1c1NjYWxlIiwiZ2V0UmFkaXVzU2NhbGVCeVpvb20iLCJyYWRpdXNNYXhQaXhlbHMiLCJTdmdJY29uTGF5ZXIiLCJnZXRJY29uR2VvbWV0cnkiLCJhdXRvSGlnaGxpZ2h0IiwiaGlnaGxpZ2h0Q29sb3IiLCJwaWNrYWJsZSIsInBhcmFtZXRlcnMiLCJkZXB0aFRlc3QiLCJkcmFnUm90YXRlIiwidXBkYXRlVHJpZ2dlcnMiLCJpc0xheWVySG92ZXJlZCIsIm9iamVjdCIsImZpZWxkUGFpcnMiLCJmaWVsZHMiLCJub3RGb3VuZCIsImxlbmd0aCIsImljb25GaWVsZHMiLCJmaWx0ZXIiLCJuYW1lIiwicmVwbGFjZSIsInRyaW0iLCJzcGxpdCIsInNvbWUiLCJzZWciLCJJQ09OX0ZJRUxEUyIsInQiLCJpbmNsdWRlcyIsInB0UGFpciIsImljb25GaWVsZCIsImxhYmVsIiwicGFpciIsInZhbHVlIiwidGFibGVGaWVsZEluZGV4IiwiaXNWaXNpYmxlIiwiTGF5ZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzsrQ0EzQkEsb0o7Ozs7Ozs7Ozs7QUE2Qk8sSUFBTUEsWUFB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aUJtSCxJQUFqQixDQUFzQixVQUFBRyxDQUFDO0FBQUEsbUJBQUlBLENBQUMsQ0FBQ0MsUUFBRixDQUFXSCxHQUFYLENBQUo7QUFBQSxXQUF2QixDQUFKO0FBQUEsU0FKWCxDQUQrQjtBQUFBLE9BQWQsQ0FBbkI7O0FBUUEsVUFBSSxDQUFDUCxVQUFVLENBQUNELE1BQWhCLEVBQXdCO0FBQ3RCLGVBQU9ELFFBQVA7QUFDRCxPQWhCMEQsQ0FrQjNEOzs7QUFDQSxVQUFNYSxNQUFNLEdBQUdmLFVBQVUsQ0FBQyxDQUFELENBQXpCO0FBRUEsVUFBTS9GLEtBQUssR0FBR21HLFVBQVUsQ0FBQ3pDLEdBQVgsQ0FBZSxVQUFBcUQsU0FBUztBQUFBLGVBQUs7QUFDekNDLFVBQUFBLEtBQUssRUFBRUQsU0FBUyxDQUFDVixJQUFWLENBQWVDLE9BQWYsQ0FBdUIsU0FBdkIsRUFBa0MsR0FBbEMsRUFBdUNDLElBQXZDLEVBRGtDO0FBRXpDckQsVUFBQUEsT0FBTyxFQUFFO0FBQ1BuRSxZQUFBQSxHQUFHLEVBQUUrSCxNQUFNLENBQUNHLElBQVAsQ0FBWWxJLEdBRFY7QUFFUEMsWUFBQUEsR0FBRyxFQUFFOEgsTUFBTSxDQUFDRyxJQUFQLENBQVlqSSxHQUZWO0FBR1BNLFlBQUFBLElBQUksRUFBRTtBQUNKNEgsY0FBQUEsS0FBSyxFQUFFSCxTQUFTLENBQUNWLElBRGI7QUFFSmxILGNBQUFBLFFBQVEsRUFBRTRILFNBQVMsQ0FBQ0ksZUFBVixHQUE0QjtBQUZsQztBQUhDLFdBRmdDO0FBVXpDQyxVQUFBQSxTQUFTLEVBQUU7QUFWOEIsU0FBTDtBQUFBLE9BQXhCLENBQWQ7QUFhQSxhQUFPO0FBQUNwSCxRQUFBQSxLQUFLLEVBQUxBO0FBQUQsT0FBUDtBQUNEOzs7RUFqSG9DcUgscUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjMgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgTGF5ZXIgZnJvbSAnLi4vYmFzZS1sYXllcic7XG5pbXBvcnQgbWVtb2l6ZSBmcm9tICdsb2Rhc2gubWVtb2l6ZSc7XG5pbXBvcnQgd2luZG93IGZyb20gJ2dsb2JhbC93aW5kb3cnO1xuXG5pbXBvcnQge2hleFRvUmdifSBmcm9tICd1dGlscy9jb2xvci11dGlscyc7XG5pbXBvcnQgU3ZnSWNvbkxheWVyIGZyb20gJ2RlY2tnbC1sYXllcnMvc3ZnLWljb24tbGF5ZXIvc3ZnLWljb24tbGF5ZXInO1xuaW1wb3J0IEljb25MYXllckljb24gZnJvbSAnLi9pY29uLWxheWVyLWljb24nO1xuaW1wb3J0IHtJQ09OX0ZJRUxEUywgQ0xPVURGUk9OVH0gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuaW1wb3J0IEljb25JbmZvTW9kYWxGYWN0b3J5IGZyb20gJy4vaWNvbi1pbmZvLW1vZGFsJztcblxuZXhwb3J0IGNvbnN0IFNWR19JQ09OX1VSTCA9IGAke0NMT1VERlJPTlR9L2ljb25zL3N2Zy1pY29ucy5qc29uYDtcblxuZXhwb3J0IGNvbnN0IGljb25Qb3NBY2Nlc3NvciA9ICh7bGF0LCBsbmd9KSA9PiBkID0+IFtcbiAgZC5kYXRhW2xuZy5maWVsZElkeF0sXG4gIGQuZGF0YVtsYXQuZmllbGRJZHhdXG5dO1xuXG5leHBvcnQgY29uc3QgaWNvblBvc1Jlc29sdmVyID0gKHtsYXQsIGxuZ30pID0+IGAke2xhdC5maWVsZElkeH0tJHtsbmcuZmllbGRJZHh9YDtcblxuZXhwb3J0IGNvbnN0IGljb25BY2Nlc3NvciA9ICh7aWNvbn0pID0+IGQgPT4gZC5kYXRhW2ljb24uZmllbGRJZHhdO1xuZXhwb3J0IGNvbnN0IGljb25SZXNvbHZlciA9ICh7aWNvbn0pID0+IGljb24uZmllbGRJZHg7XG5cbmV4cG9ydCBjb25zdCBpY29uUmVxdWlyZWRDb2x1bW5zID0gWydsYXQnLCAnbG5nJywgJ2ljb24nXTtcblxuZXhwb3J0IGNvbnN0IHBvaW50VmlzQ29uZmlncyA9IHtcbiAgcmFkaXVzOiAncmFkaXVzJyxcbiAgZml4ZWRSYWRpdXM6ICdmaXhlZFJhZGl1cycsXG4gIG9wYWNpdHk6ICdvcGFjaXR5JyxcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnLFxuICByYWRpdXNSYW5nZTogJ3JhZGl1c1JhbmdlJ1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSWNvbkxheWVyIGV4dGVuZHMgTGF5ZXIge1xuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcblxuICAgIHRoaXMucmVnaXN0ZXJWaXNDb25maWcocG9pbnRWaXNDb25maWdzKTtcbiAgICB0aGlzLmdldFBvc2l0aW9uID0gbWVtb2l6ZShpY29uUG9zQWNjZXNzb3IsIGljb25Qb3NSZXNvbHZlcik7XG4gICAgdGhpcy5nZXRJY29uID0gbWVtb2l6ZShpY29uQWNjZXNzb3IsIGljb25SZXNvbHZlcik7XG5cbiAgICAvLyBwcmVwYXJlIGxheWVyIGluZm8gbW9kYWxcbiAgICB0aGlzLl9sYXllckluZm9Nb2RhbCA9IEljb25JbmZvTW9kYWxGYWN0b3J5KCk7XG4gICAgdGhpcy5nZXRTdmdJY29ucygpO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdpY29uJztcbiAgfVxuXG4gIGdldCByZXF1aXJlZExheWVyQ29sdW1ucygpIHtcbiAgICByZXR1cm4gaWNvblJlcXVpcmVkQ29sdW1ucztcbiAgfVxuXG4gIGdldCBjb2x1bW5QYWlycygpIHtcbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0UG9pbnRDb2x1bW5QYWlycztcbiAgfVxuXG4gIGdldCBsYXllckljb24oKSB7XG4gICAgcmV0dXJuIEljb25MYXllckljb247XG4gIH1cblxuICBnZXQgdmlzdWFsQ2hhbm5lbHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN1cGVyLnZpc3VhbENoYW5uZWxzLFxuICAgICAgc2l6ZToge1xuICAgICAgICAuLi5zdXBlci52aXN1YWxDaGFubmVscy5zaXplLFxuICAgICAgICByYW5nZTogJ3JhZGl1c1JhbmdlJyxcbiAgICAgICAgcHJvcGVydHk6ICdyYWRpdXMnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiAncmFkaXVzJ1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXQgbGF5ZXJJbmZvTW9kYWwoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiAnaWNvbkluZm8nLFxuICAgICAgdGVtcGxhdGU6IHRoaXMuX2xheWVySW5mb01vZGFsLFxuICAgICAgbW9kYWxQcm9wczoge1xuICAgICAgICB0aXRsZTogJ0hvdyB0byBkcmF3IGljb25zJ1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBhc3luYyBnZXRTdmdJY29ucygpIHtcbiAgICBjb25zdCBmZXRjaENvbmZpZyA9IHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBtb2RlOiAnY29ycycsXG4gICAgICBjYWNoZTogJ25vLWNhY2hlJ1xuICAgIH07XG5cbiAgICBpZiAod2luZG93LmZldGNoKSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdpbmRvdy5mZXRjaChTVkdfSUNPTl9VUkwsIGZldGNoQ29uZmlnKTtcbiAgICAgIGNvbnN0IHtzdmdJY29uc30gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIHRoaXMuaWNvbkdlb21ldHJ5ID0gc3ZnSWNvbnMucmVkdWNlKFxuICAgICAgICAoYWNjdSwgY3VycikgPT4gKHtcbiAgICAgICAgICAuLi5hY2N1LFxuICAgICAgICAgIFtjdXJyLmlkXTogY3Vyci5tZXNoLmNlbGxzLnJlZHVjZSgocHJldiwgY2VsbCkgPT4ge1xuICAgICAgICAgICAgY2VsbC5mb3JFYWNoKHAgPT4ge1xuICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShwcmV2LCBjdXJyLm1lc2gucG9zaXRpb25zW3BdKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHByZXY7XG4gICAgICAgICAgfSwgW10pXG4gICAgICAgIH0pLFxuICAgICAgICB7fVxuICAgICAgKTtcbiAgICAgIHRoaXMuX2xheWVySW5mb01vZGFsID0gSWNvbkluZm9Nb2RhbEZhY3Rvcnkoc3ZnSWNvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoe2ZpZWxkUGFpcnMgPSBbXSwgZmllbGRzID0gW119KSB7XG4gICAgY29uc3Qgbm90Rm91bmQgPSB7cHJvcHM6IFtdfTtcbiAgICBpZiAoIWZpZWxkUGFpcnMubGVuZ3RoIHx8ICFmaWVsZHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gbm90Rm91bmQ7XG4gICAgfVxuXG4gICAgY29uc3QgaWNvbkZpZWxkcyA9IGZpZWxkcy5maWx0ZXIoKHtuYW1lfSkgPT5cbiAgICAgIG5hbWVcbiAgICAgICAgLnJlcGxhY2UoL1tfLC5dKy9nLCAnICcpXG4gICAgICAgIC50cmltKClcbiAgICAgICAgLnNwbGl0KCcgJylcbiAgICAgICAgLnNvbWUoc2VnID0+IElDT05fRklFTERTLmljb24uc29tZSh0ID0+IHQuaW5jbHVkZXMoc2VnKSkpXG4gICAgKTtcblxuICAgIGlmICghaWNvbkZpZWxkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBub3RGb3VuZDtcbiAgICB9XG5cbiAgICAvLyBjcmVhdGUgaWNvbiBsYXllcnMgZm9yIGZpcnN0IHBvaW50IHBhaXJcbiAgICBjb25zdCBwdFBhaXIgPSBmaWVsZFBhaXJzWzBdO1xuXG4gICAgY29uc3QgcHJvcHMgPSBpY29uRmllbGRzLm1hcChpY29uRmllbGQgPT4gKHtcbiAgICAgIGxhYmVsOiBpY29uRmllbGQubmFtZS5yZXBsYWNlKC9bXywuXSsvZywgJyAnKS50cmltKCksXG4gICAgICBjb2x1bW5zOiB7XG4gICAgICAgIGxhdDogcHRQYWlyLnBhaXIubGF0LFxuICAgICAgICBsbmc6IHB0UGFpci5wYWlyLmxuZyxcbiAgICAgICAgaWNvbjoge1xuICAgICAgICAgIHZhbHVlOiBpY29uRmllbGQubmFtZSxcbiAgICAgICAgICBmaWVsZElkeDogaWNvbkZpZWxkLnRhYmxlRmllbGRJbmRleCAtIDFcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZVxuICAgIH0pKTtcblxuICAgIHJldHVybiB7cHJvcHN9O1xuICB9XG5cbiAgLy8gVE9ETzogZml4IGNvbXBsZXhpdHlcbiAgLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuICBmb3JtYXRMYXllckRhdGEoXywgYWxsRGF0YSwgZmlsdGVyZWRJbmRleCwgb2xkTGF5ZXJEYXRhLCBvcHQgPSB7fSkge1xuICAgIGNvbnN0IHtcbiAgICAgIGNvbG9yU2NhbGUsXG4gICAgICBjb2xvckRvbWFpbixcbiAgICAgIGNvbG9yRmllbGQsXG4gICAgICBjb2xvcixcbiAgICAgIGNvbHVtbnMsXG4gICAgICBzaXplRmllbGQsXG4gICAgICBzaXplU2NhbGUsXG4gICAgICBzaXplRG9tYWluLFxuICAgICAgdmlzQ29uZmlnOiB7cmFkaXVzUmFuZ2UsIGNvbG9yUmFuZ2V9XG4gICAgfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgLy8gcG9pbnQgY29sb3JcbiAgICBjb25zdCBjU2NhbGUgPVxuICAgICAgY29sb3JGaWVsZCAmJlxuICAgICAgdGhpcy5nZXRWaXNDaGFubmVsU2NhbGUoXG4gICAgICAgIGNvbG9yU2NhbGUsXG4gICAgICAgIGNvbG9yRG9tYWluLFxuICAgICAgICBjb2xvclJhbmdlLmNvbG9ycy5tYXAoaGV4VG9SZ2IpXG4gICAgICApO1xuXG4gICAgLy8gcG9pbnQgcmFkaXVzXG4gICAgY29uc3QgclNjYWxlID1cbiAgICAgIHNpemVGaWVsZCAmJiB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShzaXplU2NhbGUsIHNpemVEb21haW4sIHJhZGl1c1JhbmdlLCAwKTtcblxuICAgIGNvbnN0IGdldFBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbihjb2x1bW5zKTtcbiAgICBjb25zdCBnZXRJY29uID0gdGhpcy5nZXRJY29uKGNvbHVtbnMpO1xuXG4gICAgaWYgKCFvbGRMYXllckRhdGEgfHwgb2xkTGF5ZXJEYXRhLmdldFBvc2l0aW9uICE9PSBnZXRQb3NpdGlvbikge1xuICAgICAgdGhpcy51cGRhdGVMYXllck1ldGEoYWxsRGF0YSwgZ2V0UG9zaXRpb24pO1xuICAgIH1cblxuICAgIGxldCBkYXRhO1xuICAgIGlmIChcbiAgICAgIG9sZExheWVyRGF0YSAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmRhdGEgJiZcbiAgICAgIG9wdC5zYW1lRGF0YSAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmdldFBvc2l0aW9uID09PSBnZXRQb3NpdGlvbiAmJlxuICAgICAgb2xkTGF5ZXJEYXRhLmdldEljb24gPT09IGdldEljb25cbiAgICApIHtcbiAgICAgIGRhdGEgPSBvbGRMYXllckRhdGEuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IGZpbHRlcmVkSW5kZXgucmVkdWNlKChhY2N1LCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbih7ZGF0YTogYWxsRGF0YVtpbmRleF19KTtcbiAgICAgICAgY29uc3QgaWNvbiA9IGdldEljb24oe2RhdGE6IGFsbERhdGFbaW5kZXhdfSk7XG5cbiAgICAgICAgLy8gaWYgZG9lc24ndCBoYXZlIHBvaW50IGxhdCBvciBsbmcsIGRvIG5vdCBhZGQgdGhlIHBvaW50XG4gICAgICAgIC8vIGRlY2suZ2wgY2FuJ3QgaGFuZGxlIHBvc2l0aW9uID0gbnVsbFxuICAgICAgICBpZiAoIXBvcy5ldmVyeShOdW1iZXIuaXNGaW5pdGUpIHx8IHR5cGVvZiBpY29uICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHJldHVybiBhY2N1O1xuICAgICAgICB9XG5cbiAgICAgICAgYWNjdS5wdXNoKHtcbiAgICAgICAgICBpbmRleCxcbiAgICAgICAgICBpY29uLFxuICAgICAgICAgIGRhdGE6IGFsbERhdGFbaW5kZXhdXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBhY2N1O1xuICAgICAgfSwgW10pO1xuICAgIH1cblxuICAgIGNvbnN0IGdldFJhZGl1cyA9IHJTY2FsZVxuICAgICAgPyBkID0+IHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShyU2NhbGUsIGQuZGF0YSwgc2l6ZUZpZWxkLCAwKVxuICAgICAgOiAxO1xuXG4gICAgY29uc3QgZ2V0Q29sb3IgPSBjU2NhbGVcbiAgICAgID8gZCA9PiB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoY1NjYWxlLCBkLmRhdGEsIGNvbG9yRmllbGQpXG4gICAgICA6IGNvbG9yO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGEsXG4gICAgICBnZXRQb3NpdGlvbixcbiAgICAgIGdldEljb24sXG4gICAgICBnZXRDb2xvcixcbiAgICAgIGdldFJhZGl1c1xuICAgIH07XG4gIH1cbiAgLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cbiAgdXBkYXRlTGF5ZXJNZXRhKGFsbERhdGEsIGdldFBvc2l0aW9uKSB7XG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5nZXRQb2ludHNCb3VuZHMoYWxsRGF0YSwgZCA9PiBnZXRQb3NpdGlvbih7ZGF0YTogZH0pKTtcbiAgICB0aGlzLnVwZGF0ZU1ldGEoe2JvdW5kc30pO1xuICB9XG5cbiAgcmVuZGVyTGF5ZXIoe1xuICAgIGRhdGEsXG4gICAgaWR4LFxuICAgIG9iamVjdEhvdmVyZWQsXG4gICAgbWFwU3RhdGUsXG4gICAgaW50ZXJhY3Rpb25Db25maWcsXG4gICAgbGF5ZXJJbnRlcmFjdGlvblxuICB9KSB7XG4gICAgY29uc3QgbGF5ZXJQcm9wcyA9IHtcbiAgICAgIHJhZGl1c01pblBpeGVsczogMSxcbiAgICAgIHJhZGl1c1NjYWxlOiB0aGlzLmdldFJhZGl1c1NjYWxlQnlab29tKG1hcFN0YXRlKSxcbiAgICAgIC4uLih0aGlzLmNvbmZpZy52aXNDb25maWcuZml4ZWRSYWRpdXMgPyB7fSA6IHtyYWRpdXNNYXhQaXhlbHM6IDUwMH0pXG4gICAgfTtcblxuICAgIHJldHVybiAhdGhpcy5pY29uR2VvbWV0cnlcbiAgICAgID8gW11cbiAgICAgIDogW1xuICAgICAgICAgIG5ldyBTdmdJY29uTGF5ZXIoe1xuICAgICAgICAgICAgLi4ubGF5ZXJQcm9wcyxcbiAgICAgICAgICAgIC4uLmRhdGEsXG4gICAgICAgICAgICAuLi5sYXllckludGVyYWN0aW9uLFxuICAgICAgICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICBpZHgsXG4gICAgICAgICAgICBvcGFjaXR5OiB0aGlzLmNvbmZpZy52aXNDb25maWcub3BhY2l0eSxcbiAgICAgICAgICAgIGdldEljb25HZW9tZXRyeTogaWQgPT4gdGhpcy5pY29uR2VvbWV0cnlbaWRdLFxuXG4gICAgICAgICAgICAvLyBwaWNraW5nXG4gICAgICAgICAgICBhdXRvSGlnaGxpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgaGlnaGxpZ2h0Q29sb3I6IHRoaXMuY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgICAgICAgcGlja2FibGU6IHRydWUsXG5cbiAgICAgICAgICAgIC8vIHBhcmFtZXRlcnNcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHtkZXB0aFRlc3Q6IG1hcFN0YXRlLmRyYWdSb3RhdGV9LFxuXG4gICAgICAgICAgICAvLyB1cGRhdGUgdHJpZ2dlcnNcbiAgICAgICAgICAgIHVwZGF0ZVRyaWdnZXJzOiB7XG4gICAgICAgICAgICAgIGdldFJhZGl1czoge1xuICAgICAgICAgICAgICAgIHNpemVGaWVsZDogdGhpcy5jb25maWcuY29sb3JGaWVsZCxcbiAgICAgICAgICAgICAgICByYWRpdXNSYW5nZTogdGhpcy5jb25maWcudmlzQ29uZmlnLnJhZGl1c1JhbmdlLFxuICAgICAgICAgICAgICAgIHNpemVTY2FsZTogdGhpcy5jb25maWcuc2l6ZVNjYWxlXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGdldENvbG9yOiB7XG4gICAgICAgICAgICAgICAgY29sb3I6IHRoaXMuY29uZmlnLmNvbG9yLFxuICAgICAgICAgICAgICAgIGNvbG9yRmllbGQ6IHRoaXMuY29uZmlnLmNvbG9yRmllbGQsXG4gICAgICAgICAgICAgICAgY29sb3JSYW5nZTogdGhpcy5jb25maWcudmlzQ29uZmlnLmNvbG9yUmFuZ2UsXG4gICAgICAgICAgICAgICAgY29sb3JTY2FsZTogdGhpcy5jb25maWcuY29sb3JTY2FsZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICAgLi4uKHRoaXMuaXNMYXllckhvdmVyZWQob2JqZWN0SG92ZXJlZClcbiAgICAgICAgICAgID8gW1xuICAgICAgICAgICAgICAgIG5ldyBTdmdJY29uTGF5ZXIoe1xuICAgICAgICAgICAgICAgICAgLi4ubGF5ZXJQcm9wcyxcbiAgICAgICAgICAgICAgICAgIGlkOiBgJHt0aGlzLmlkfS1ob3ZlcmVkYCxcbiAgICAgICAgICAgICAgICAgIGRhdGE6IFtvYmplY3RIb3ZlcmVkLm9iamVjdF0sXG4gICAgICAgICAgICAgICAgICBnZXRQb3NpdGlvbjogZGF0YS5nZXRQb3NpdGlvbixcbiAgICAgICAgICAgICAgICAgIGdldFJhZGl1czogZGF0YS5nZXRSYWRpdXMsXG4gICAgICAgICAgICAgICAgICBnZXRDb2xvcjogdGhpcy5jb25maWcuaGlnaGxpZ2h0Q29sb3IsXG4gICAgICAgICAgICAgICAgICBnZXRJY29uR2VvbWV0cnk6IGlkID0+IHRoaXMuaWNvbkdlb21ldHJ5W2lkXSxcbiAgICAgICAgICAgICAgICAgIHBpY2thYmxlOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIDogW10pXG4gICAgICAgIF07XG4gIH1cbn1cbiJdfQ==